#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,a[100005],b[100005],ans,_up[100005],_dn[100005];
map <int,int> mp;int lim;
struct ST{
int t[100005<<2];
inline void pushup(int k){
t[k]=max(t[k<<1],t[k<<1|1]);return;
}
inline void init(int k,int l,int r){
if(l==r){
t[k]=0;
}else{
int mid=l+r>>1;
if(t[k<<1])init(k<<1,l,mid);
if(t[k<<1|1])init(k<<1|1,mid+1,r);
pushup(k);
}return;
}
inline void updata(int P,int val,int k,int l,int r){
if(P<=l&&r<=P){
t[k]=max(t[k],val);
}else{
int mid=l+r>>1;
if(P<=mid)updata(P,val,k<<1,l,mid);
else updata(P,val,k<<1|1,mid+1,r);
pushup(k);
}return;
}
inline int query(int L,int R,int k,int l,int r){
if(L<=l&&r<=R){
return t[k];
}else{
int mid=l+r>>1,res=-2e18;
if(L<=mid)res=max(res,query(L,R,k<<1,l,mid));
if(R>mid)res=max(res,query(L,R,k<<1|1,mid+1,r));
return res;
}
}
}UP,DN,up,dn;
vector <int> to[100005];
int vis[100005],sz,siz[100005],crt;
inline void find(int x,int last){
siz[x]=1;int maxn=0;
for(int y:to[x]){
if(vis[y]||y==last)continue;
find(y,x);if(crt)return;
siz[x]+=siz[y],maxn=max(maxn,siz[y]);
}maxn=max(maxn,sz-siz[x]);
if(maxn<=sz/2){
crt=x,siz[last]=sz-siz[x];
}return;
}
int st[100005],ed[100005],tmp_up,tmp_dn,cnt;
inline bool cmp1(int A,int B){return a[A]<a[B];}
inline bool cmp2(int A,int B){return a[A]>a[B];}
vector <int> vec;
inline void add(int x,int last){
st[x]=++cnt,vec.push_back(x);
for(int y:to[x]){
if(y==last||vis[y])continue;add(y,x);
}ed[x]=cnt;return;
}
inline void calc(int x,int last,int rt){
// cout<<x<<' '<<_up[x]<<' '<<_dn[x]<<" Rana!!!\n";
if(a[x]<a[rt])tmp_up=max(tmp_up,_up[x]);
UP.updata(a[x],_up[x],1,1,lim);
if(a[x]>a[rt])tmp_dn=max(tmp_dn,_dn[x]);
DN.updata(a[x],_dn[x],1,1,lim);
for(int y:to[x]){
if(y==last||vis[y])continue;calc(y,x,rt);
}return;
}
inline void solve(int x){
// cout<<x<<" kdsb\n";
vis[x]=1,_up[x]=_dn[x]=0;
for(int y:to[x]){
if(vis[y])continue;
vec.clear(),cnt=0,add(y,x),tmp_up=tmp_dn=0;
sort(vec.begin(),vec.end(),cmp1);
for(int i:vec){
_up[i]=up.query(st[i],ed[i],1,1,n)+1;
ans=max(ans,_up[i]+DN.query(a[i]+1,lim,1,1,lim));
up.updata(st[i],_up[i],1,1,n);
}up.init(1,1,n);
sort(vec.begin(),vec.end(),cmp2);
for(int i:vec){
_dn[i]=dn.query(st[i],ed[i],1,1,n)+1;
ans=max(ans,_dn[i]+UP.query(1,a[i]-1,1,1,lim));
dn.updata(st[i],_dn[i],1,1,n);
}dn.init(1,1,n);
calc(y,x,x);
ans=max(ans,_up[x]+tmp_dn+1),_up[x]=max(_up[x],tmp_up);
ans=max(ans,_dn[x]+tmp_up+1),_dn[x]=max(_dn[x],tmp_dn);
// if(_up[x]+tmp_dn+1==8){
// cout<<x<<' '<<_up[x]<<' '<<tmp_dn<<' '<<y<<" upupupupupupupupup\n";
// }
// if(_dn[x]+tmp_up+1==8){
// cout<<x<<' '<<_dn[x]<<' '<<tmp_up<<' '<<y<<" dndndndndndndndndn\n";
// }
}UP.init(1,1,lim),DN.init(1,1,lim);
for(int y:to[x]){
if(vis[y])continue;
sz=siz[y],crt=0,find(y,x),solve(crt);
}return;
}
inline int read(){
register int x(0),t(0);
static char ch=getchar();
while(!isdigit(ch)){t|=(ch=='-');ch=getchar();}
while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
return t?-x:x;
}
signed main(){
n=sz=read();
for(int i=1;i<=n;i++){
a[i]=b[i]=read();
}b[n+1]=0,b[n+2]=1e9,sort(b+1,b+3+n);
for(int i=1;i<=n+2;i++){
if(!mp[b[i]])mp[b[i]]=++lim;
}
for(int i=1;i<=n;i++){
a[i]=mp[a[i]];
}
for(int i=1;i<n;i++){
int x=read(),y=read();
to[x].push_back(y),to[y].push_back(x);
}
// for(int i=1;i<=n;i++){
// for(int j:to[i]){
// cout<<i<<"-("<<a[i]<<") "<<j<<"-("<<a[j]<<")\n";
// }
// }
find(1,0),solve(crt);
cout<<ans;
return 0;
}
rt