#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 7;
const int L = 18;
vector<int> adj[N];
int par[N][L];
int dsuPar[N];
int h[N];
bool nodeMark[N];
int bigNode[N];
ll ans [N];
int siz[N];
int getPar(int u){
if(dsuPar[u] == -1) return u;
return (dsuPar[u] = getPar(dsuPar[u]));
}
bool merge(int u , int v){
u = getPar(u);
v = getPar(v);
if(u == v) return false;
if(siz[v] < siz[u]) swap(u , v);
dsuPar[u] = v;
siz[v] += siz[u];
return true;
}
void dfs(int u , int parent){
par[u][0] = parent;
for(int i = 1; i < L; i++){
if(par[u][i - 1] == -1) break;
par[u][i] = par[par[u][i - 1]][i - 1];
}
for(auto v: adj[u]){
if(v == parent) continue;
h[v] = h[u] + 1;
dfs(v , u);
}
}
int lca(int u , int v){
if(h[v] < h[u]) swap(u , v);
for(int i = L - 1; i >= 0; i--){
if(par[v][i] != -1 && h[par[v][i]] >= h[u]){
v = par[v][i];
}
}
if(v == u) return u;
for(int i = L - 1; i >= 0; i--){
if(par[u][i] == par[v][i]) continue;
u = par[u][i] , v = par[v][i];
}
return par[v][0];
}
ll dist(int u , int v){
return h[u] + h[v] - (2 * h[lca(u , v)]);
}
void onNode(int u){
nodeMark[u] = true;
for(auto v: adj[u]){
if(!nodeMark[v]) continue;
int bn = bigNode[getPar(v)];
if(merge(u , v)){
bigNode[getPar(u)] = u;
ans[u] = max(ans[u] , dist(u , bn) + ans[bn]);
}
}
}
int main(){
ios_base::sync_with_stdio(0) , cin.tie(0) , cout.tie(0);
memset(par , -1 , sizeof par);
memset(dsuPar , -1 , sizeof dsuPar);
int n;
cin >> n;
for(int i = 0; i < n; i++) {
siz[i] = 1;
bigNode[i] = i;
}
vector<pair<int ,int>> p(n);
for(int i = 0; i < n; i++){
cin >> p[i].first;
p[i].second = i;
}
sort(p.begin() , p.end());
for(int i = 0; i < n - 1; i++){
int u , v;
cin >> u >> v;
u-- , v--;
adj[u].push_back(v);
adj[v].push_back(u);
}
dfs(0 , -1);
ll an = 0;
for(int i = 0; i < n; i++){
onNode(p[i].second);
an = ans[p[i].second];
}
cout << an << endl;
return 0;
}