#include <bits/stdc++.h>
#define fst first
#define snd second
#define pb push_back
#define SZ(x) (int)x.size()
#define ALL(x) x.begin(),x.end()
#define forn(i,a,b) for(int i = a; i<b; i++)
#define mset(a,v) memset(a,v,sizeof(a))
#define FIN ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
typedef long long ll;
const int MAXN = 200000+5;
const int MAXP = 20;
#ifdef D
#define debug(x) cout << x
#else
#define debug(x) //nothing
#endif
ll n;
ll p[MAXN];
ll res[MAXN];
vector<ll> adj[MAXN];
struct UnionFind{
ll n;
vector<ll> rep;
vector<ll> sz;
vector<set<pair<ll,ll>>> aadj;
UnionFind(ll n) : n(n) , rep(n+5, 0), sz(n+5, 1) , aadj(n+5) {
forn(i,0,n){
rep[i]=i;
for(auto j:adj[i]){
aadj[i].insert({p[j],j});
}
}
}
ll Find(ll a){
return rep[a]==a?a:rep[a]=Find(rep[a]);
}
void Union(ll a, ll b){
debug("Union "<<a<<" "<<b<<'\n');
ll pa = Find(a);
ll pb = Find(b);
if(pa==pb) return;
if(sz[pa]<sz[pb]){
rep[pa]=pb;
for(auto i:aadj[pa]) aadj[pb].insert(i);
}else{
rep[pb]=pa;
if(sz[pa]==sz[pb]){
sz[pa]++;
}
for(auto i:aadj[pb]) aadj[pa].insert(i);
}
}
};
ll toJ;
ll lvlToJ;
ll lvl[MAXN];
ll pa[MAXN];
ll blift[MAXN][MAXP];
void dfs(ll nd, ll p, ll lv){
lvl[nd]=lv;
pa[nd]=p;
for(auto i:adj[nd]) if(i!=p){
dfs(i,nd,lv+1);
}
}
void precalc(){
forn(i,0,n) blift[i][0]=pa[i];
forn(k,1,MAXP){
forn(i,0,n){
if(blift[i][k-1]!=-1) blift[i][k]=blift[blift[i][k-1]][k-1];
else blift[i][k]=-1;
}
}
}
void sameLvl(ll &a, ll &b){
if(lvl[a]>lvl[b]) swap(a,b);
for(int k = MAXP-1; k>=0; k--){
if(blift[b][k]!=-1 && lvl[blift[b][k]]>=lvl[a]){
b=blift[b][k];
}
}
}
ll LCA(ll a, ll b){
sameLvl(a,b);
for(int k = MAXP-1; k>=0; k--){
if(blift[a][k]!=blift[b][k]){
a=blift[a][k];
b=blift[b][k];
}
}
if(a==b) return a;
return pa[a];
}
int main(){
mset(res,0);
cin>>n;
forn(i,0,n) cin>>p[i];
ll u,v;
forn(i,0,n-1){
cin>>u>>v; u--; v--;
adj[u].pb(v);
adj[v].pb(u);
}
vector<pair<ll,ll>> ord;
forn(i,0,n){
ord.pb({p[i],i});
}
sort(ALL(ord));
dfs(0,-1,0);
precalc();
UnionFind uf(n);
forn(i,0,n-1){
toJ=-1;
lvlToJ=-1;
ll nd = ord[i].snd;
ll val = ord[i].fst;
for(auto j:adj[nd]) if(p[j]<p[nd]){
uf.Union(nd,j);
}
ll rep = uf.Find(nd);
toJ = uf.aadj[rep].lower_bound({val+1,0})->snd;
ll lca = LCA(nd,toJ);
lvlToJ=(lvl[nd]-lvl[lca]) + (lvl[toJ]-lvl[lca]);
debug(i<<" "<<nd<<" "<<toJ<<" "<<rep<<" "<<lvlToJ<<'\n');
debug(res[nd]<<'\n');
res[toJ]=max(res[toJ], res[nd]+lvlToJ);
}
cout<<res[ord.back().snd]<<'\n';
return 0;
}