#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
map<int, int> v[N];
map<int, int> mp;
int s[N];

int main() {
    int n;
    scanf("%d", &n);
    lp(i, 1, n) {
        scanf("%d", &s[i]);
        mp[s[i]]++;
    }
    lp(i, 1, n - 1) {
        int x, y;
        scanf("%d%d", &x, &y);
        v[x][s[y]]++;
        v[y][s[x]]++;
    }
    int mx = INT_MAX;
    lp(i, 1, n) {
        if (!v[i].size()) {
            mx = min(mx, s[i]);
            continue;
        }
        pii z = *v[i].rbegin();
        mp[z.F] -= z.S;
        mp[s[i]]--;
        int p = INT_MIN;
        if (!mp[s[i]]) mp.erase(s[i]);
        if (!mp[z.F]) mp.erase(z.F);
        if (mp.size()) {
            pii t = *mp.rbegin();
            p = t.F + 2;
        }
        mx = min(mx, max({p, s[i], z.F + 1}));
        mp[s[i]]++;
        mp[z.F] += z.S;
    }
    printf("%d", mx);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
map<int, int> v[N];
map<int, int> mp;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    cin >> n;
    lp(i, 1, n) cin >> s[i], mp[s[i]]++;
    lp(i, 1, n - 1) {
        int x, y;
        cin >> x >> y;
        v[x][s[y]]++;
        v[y][s[x]]++;
    }
    int mx = INT_MAX;
    lp(i, 1, n) {
        pii z = *v[i].rbegin();
        //cout << z.F << "\n";
        mp[z.F] -= z.S;
        mp[s[i]]--;
        int p = INT_MIN;
        if (!mp[s[i]]) mp.erase(s[i]);
        if (!mp[z.F]) mp.erase(z.F);
        if (mp.size()) {
            pii t = *mp.rbegin();
            p = t.F + 2;
        }
        mx = min(mx, max({p, s[i], z.F + 1}));
        //cout << mx << "\n-------------\n";
        mp[s[i]]++;
        mp[z.F] += z.S;
    }
    cout << mx << "\n";
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
map<int, int> v[N];
map<int, int> mp;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    cin >> n;
    lp(i, 1, n) {
        cin >> s[i];
        mp[s[i]]++;
    }
    lp(i, 1, n - 1) {
        int x, y;
        cin >> x >> y;
        v[x][s[y]]++;
        v[y][s[x]]++;
    }
    int mx = INT_MAX;
    lp(i, 1, n) {
        if (!v[i].size()) {
            mx = min(mx, s[i]);
            continue;
        }
        pii z = *v[i].rbegin();
        mp[z.F] -= z.S;
        mp[s[i]]--;
        int p = INT_MIN;
        if (!mp[s[i]]) mp.erase(s[i]);
        if (!mp[z.F]) mp.erase(z.F);
        if (mp.size()) {
            pii t = *mp.rbegin();
            p = t.F + 2;
        }
        mx = min(mx, max({p, s[i], z.F + 1}));
        mp[s[i]]++;
        mp[z.F] += z.S;
    }
    cout << mx << "\n";
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
map<int, int> v[N];
map<int, int> mp;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    scanf("%d", &n);
    lp(i, 1, n) {
        cin >> s[i];
        mp[s[i]]++;
    }
    lp(i, 1, n - 1) {
        int x, y;
        scanf("%d%d", &x, &y);
        v[x][s[y]]++;
        v[y][s[x]]++;
    }
    int mx = INT_MAX;
    lp(i, 1, n) {
        if (!v[i].size()) {
            mx = min(mx, s[i]);
            continue;
        }
        pii z = *v[i].rbegin();
        mp[z.F] -= z.S;
        mp[s[i]]--;
        int p = INT_MIN;
        if (!mp[s[i]]) mp.erase(s[i]);
        if (!mp[z.F]) mp.erase(z.F);
        if (mp.size()) {
            pii t = *mp.rbegin();
            p = t.F + 2;
        }
        mx = min(mx, max({p, s[i], z.F + 1}));
        mp[s[i]]++;
        mp[z.F] += z.S;
    }
    printf("%d", mx);
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define ll long long
#define pb push_back
#define pf push_front
#define F first
#define S second
#define lp(i, a, b) for (int i=a;i<=(int)b;++i)
#define lp2(i, a, b) for (ll i=a;i>=b;--i)
#define f(x) return cout<<x<<"\n",0
#define pii pair<int,int>
#define pll pair<ll,ll>
#define all(c) c.begin(),c.end()
#define allr(c) c.rbegin(),c.rend()
#define p(x) cout<<#x<<" = { "<<x<<" } \n"
#define vi vector<int>
#define vl vector<ll>
#define vs vector<string>
#define vii vector<pii>
#define vll vector<pll>
#define FAST ios::sync_with_stdio(0),ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define clr(c, x) memset(c,x,sizeof(c));
const ll INFL = 0x3f3f3f3f3f3f3f3fLL;
const int dx[] = {0, 1, 0, -1, 1, -1, 1, -1};
const int dy[] = {1, 0, -1, 0, 1, -1, -1, 1};
const int N = (int) 3e5 + 5, INF = 0x3f3f3f3f, ALPHA = 26;
const ll mod = 998244353;
vi v[N];
multiset<int> st;
int s[N];

int main() {
#ifdef ONLINE_JUDGE
    FAST;
#endif
    int n;
    cin >> n;
    lp(i, 1, n) cin >> s[i];
    lp(i, 1, n - 1) {
        int x, y;
        cin >> x >> y;
        v[x].pb(y);
        v[y].pb(x);
    }
    lp(i, 1, n)st.insert(s[i] + 2);
    int mx = INT_MAX;
    lp(i, 1, n) {
        st.erase(st.lower_bound(s[i] + 2));
        st.insert(s[i]);
        //cout << "YES\n";
        for (auto u:v[i]) {
            st.erase(st.lower_bound(s[u] + 2));
            st.insert(s[u] + 1);
        }
        mx = min(mx, *st.rbegin());
        st.erase(st.lower_bound(s[i]));
        st.insert(s[i] + 2);
        for (auto u:v[i]) {
            st.insert(s[u] + 2);
            st.erase(st.lower_bound(s[u] + 1));
        }
    }
    cout << mx << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par) {
	pare[curr] = par;
	int worst = w[curr];
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], 1 + dfs(v, curr)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1);
	ma = wor[ind];
	while(RTIME < 1.95){
		ind = wind[ind];
		dfs(ind, -1);
		REMIN(ma, wor[ind]);
	}
	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 1e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
      if(!dec) cout<<"NO";
      exit(0);
}

int flag1, flag2;
vi eds[NMAX * 3];
ll w[NMAX * 3];
ll ma, mind;

void dfs(int curr, int par, int tim = 0) {
      if(w[curr] == ma && tim == 1)
            flag1 = 1;
      if(w[curr] == ma && tim >= 2)
            flag2 = 1;
      if(w[curr] == ma - 1 && tim >= 2)
            flag1 = 1;
      for(int v : eds[curr])
            if(v != par)
                  dfs(v, curr, tim + 1);
}

int main(){
      ios_base::sync_with_stdio(false); cin.tie(0);

      cin >> N;

      ma = -1e18;
      FOI(i, 1, N) {
            cin >> w[i];
            if(REMAX(ma, w[i]))
                  mind = i;
      }

      FOI(i, 1, N - 1) {
            cin >> a >> b;
            eds[a].pb(b);
            eds[b].pb(a);
      }

      dfs(mind, -1);

      if(flag2)
            cout << ma + 2;
      else if(flag1)
            cout << ma + 1;
      else
            cout << ma;

      return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 1e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
      if(!dec) cout<<"NO";
      exit(0);
}

int flag1, flag2;
vi eds[NMAX * 3];
ll w[NMAX * 3];
ll ma, mind;

int main(){
      ios_base::sync_with_stdio(false); cin.tie(0);

      cin >> N;

      ma = -1e18;
      FOI(i, 1, N) {
            cin >> w[i];
            REMAX(ma, w[i]);
      }

      int cnm1 = 0, cnm0 = 0;
      FOI(i, 1, N) {
            if(w[i] == ma) cnm0 ++;
            if(w[i] == ma - 1) cnm1 ++;
      }

      FOI(i, 1, N - 1) {
            cin >> a >> b;
            eds[a].pb(b);
            eds[b].pb(a);
      }

      if(!cnm1 && cnm0 == 1) {
            cout << ma;
            return 0;
      }
      if(cnm0 == 1) {
            int cool = 0;
            FOI(i, 1, N) {
                  int c1 = (w[i] == ma - 1);
                  for(int v : eds[i])
                        if(w[v] == ma - 1)
                              c1 ++;
                  if(c1 == cnm1)
                        cool = 1;
            }
            if(cool)
                  cout << ma;
            else
                  cout << ma + 1;
            return 0;
      }
      FOI(i, 1, N) {
            int cool = 0;
            FOI(i, 1, N) {
                  int c1 = (w[i] == ma);
                  for(int v : eds[i])
                        if(w[v] == ma)
                              c1 ++;
                  if(c1 == cnm0)
                        cool = 1;
            }
            if(cool)
                  cout << ma + 1;
            else
                  cout << ma + 2;
            return 0;
      }

      return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 1e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
      if(!dec) cout<<"NO";
      exit(0);
}

int flag1, flag2;
vi eds[NMAX * 3];
ll w[NMAX * 3];
ll ma, mind;

int main(){
      ios_base::sync_with_stdio(false); cin.tie(0);

      cin >> N;

      ma = -1e18, mind;
      FOI(i, 1, N) {
            cin >> w[i];
            if(REMAX(ma, w[i])) mind = i;
      }

      int cnm1 = 0, cnm0 = 0;
      FOI(i, 1, N) {
            if(w[i] == ma) cnm0 ++;
            if(w[i] == ma - 1) cnm1 ++;
      }

      FOI(i, 1, N - 1) {
            cin >> a >> b;
            eds[a].pb(b);
            eds[b].pb(a);
      }

      if(!cnm1 && cnm0 == 1) {
            cout << ma;
            return 0;
      }
      if(cnm0 == 1 && cnm1) {
            int cool = 0;

            int c1 = (w[mind] == ma - 1);

            for(int v : eds[mind])
                  if(w[v] == ma - 1)
                        c1 ++;
            if(c1 == cnm1)
                  cool = 1;

            if(cool)
                  cout << ma;
            else
                  cout << ma + 1;
            return 0;
      }
      FOI(i, 1, N) {
            int cool = 0;
            FOI(i, 1, N) {
                  int c1 = (w[i] == ma);
                  for(int v : eds[i])
                        if(w[v] == ma)
                              c1 ++;
                  if(c1 == cnm0)
                        cool = 1;
            }
            if(cool)
                  cout << ma + 1;
            else
                  cout << ma + 2;
            return 0;
      }

      return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int vis[NMAX];
int pare[NMAX];
ll ma;

int tim = 0;

void dfs0(int curr, int par) {
	pare[curr] = par;
	for(int v : eds[curr])
		if(v != par)
			dfs0(v, curr);
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	vpi gt;

	FOI(i, 1, N) {
		cin >> w[i];
		gt.pb({w[i], i});
	}

	sort(ALL(gt));
	ind = gt.back().se;
	ma = gt.back().fi;

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs0(ind, -1);
	vis[ind] = 1;
	tim = 0;
	FOD(i, SZ(gt) - 2, 0) {
		int go2 = gt[i].se;
		if(vis[go2]) continue;
		vi trav;
		while(!vis[go2]) {
			trav.pb(go2);
			go2 = pare[go2];
		}
		for(int v : trav) {
			tim ++;
			vis[v] = 1;
			REMAX(ma, w[v] + tim);
		}
	}

	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int vis[NMAX];
int pare[NMAX];
ll ma;

int tim[NMAX];

void dfs0(int curr, int par) {
	pare[curr] = par;
	for(int v : eds[curr])
		if(v != par)
			dfs0(v, curr);
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	vector<pair<ll, int>> gt;

	FOI(i, 1, N) {
		cin >> w[i];
		gt.pb({w[i], i});
	}

	sort(ALL(gt));
	ind = gt.back().se;
	ma = gt.back().fi;

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs0(ind, -1);
	vis[ind] = 1;

	FOD(i, SZ(gt) - 2, 0) {

		int go2 = gt[i].se;
		if(vis[go2]) continue;
		vi trav;

		while(!vis[go2]) {
			trav.pb(go2);
			go2 = pare[go2];
		}

		int currti = tim[go2];
		reverse(ALL(trav));

		for(int v : trav) {
			currti ++;
			vis[v] = 1;
			tim[v] = currti;
			REMAX(ma, w[v] + currti);
		}

	}

	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int vis[NMAX];
int pare[NMAX];
ll ma;

int tim = 0;

void dfs0(int curr, int par) {
	pare[curr] = par;
	for(int v : eds[curr])
		if(v != par)
			dfs0(v, curr);
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	vpi gt;

	FOI(i, 1, N) {
		cin >> w[i];
		gt.pb({w[i], i});
	}

	sort(ALL(gt));
	ind = gt.back().se;
	ma = gt.back().fi;

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs0(ind, -1);
	vis[ind] = 1;
	tim = 0;
	FOD(i, SZ(gt) - 2, 0) {
		int go2 = gt[i].se;
		if(vis[go2]) continue;
		vi trav;
		while(!vis[go2]) {
			trav.pb(go2);
			go2 = pare[go2];
		}
		reverse(ALL(trav));
		for(int v : trav) {
			tim ++;
			vis[v] = 1;
			REMAX(ma, w[v] + tim);
		}
	}

	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par, int tim) {
	pare[curr] = par;
	int worst = w[curr] + tim;
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], dfs(v, curr, tim + 1)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int disor[NMAX];
int dfori(int curr, int par, int tim) {
	REMAX(disor[curr], w[curr] + tim);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(disor[curr], dfori(v, curr, tim + 1));
		}
	return disor[curr];
}

int diswi[NMAX];
int dfwi(int curr, int par, int tim) {
	REMAX(diswi[curr], w[curr] + tim);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(diswi[curr], dfwi(v, curr, tim + 1));
		}
	return diswi[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1, 0);
	if(wind[ind] == ind)
		cout << ma;
	else {
		dfori(ind, -1, 0);
		dfwi(wind[ind], -1, 0);
		int bes = wor[ind];
		int curr = wind[ind];
		while(curr != ind) {
			REMIN(bes, max(diswi[curr], disor[curr]));
			curr = pare[curr];
		}
		cout << bes;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par) {
	pare[curr] = par;
	int worst = w[curr];
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], 1 + dfs(v, curr)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int disor[NMAX];
int dfori(int curr, int par) {
	REMAX(disor[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(disor[curr], dfori(v, curr) + 1);
		}
	return disor[curr];
}

int diswi[NMAX];
int dfwi(int curr, int par) {
	REMAX(diswi[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(diswi[curr], dfwi(v, curr) + 1);
		}
	return diswi[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1);
	if(wind[ind] == ind)
		cout << ma;
	else {
		dfori(ind, -1);
		dfwi(wind[ind], -1);
		int bes = wor[ind];
		int curr = wind[ind];
		while(curr != ind) {
			REMIN(bes, max(diswi[curr], disor[curr]));
			curr = pare[curr];
		}
		cout << bes;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par, int tim) {
	pare[curr] = par;
	int worst = w[curr] + tim;
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], dfs(v, curr, tim + 1)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int disor[NMAX];
int dfori(int curr, int par) {
	REMAX(disor[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(disor[curr], dfori(v, curr) + 1);
		}
	return disor[curr];
}

int diswi[NMAX];
int dfwi(int curr, int par) {
	REMAX(diswi[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(diswi[curr], dfwi(v, curr) + 1);
		}
	return diswi[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1, 0);
	if(wind[ind] == ind)
		cout << ma;
	else {
		dfori(ind, -1);
		dfwi(wind[ind], -1);
		int bes = wor[ind];
		int curr = wind[ind];
		while(curr != ind) {
			REMIN(bes, max(diswi[curr], disor[curr]));
			curr = pare[curr];
		}
		cout << bes;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par) {
	pare[curr] = par;
	int worst = w[curr];
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], 1 + dfs(v, curr)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int disor[NMAX];
int dfori(int curr, int par) {
	REMAX(disor[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(disor[curr], dfori(v, curr) + 1);
		}
	return disor[curr];
}

int diswi[NMAX];
int dfwi(int curr, int par) {
	REMAX(diswi[curr], w[curr]);
	for(int v : eds[curr])
		if(v != par) {
			REMAX(diswi[curr], dfwi(v, curr) + 1);
		}
	return diswi[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1);
	if(wind[ind] == ind)
		cout << wor[ind];
	else {
		dfori(ind, -1);
		dfwi(wind[ind], -1);
		int bes = wor[ind];
		int curr = wind[ind];
		while(curr != ind) {
			REMIN(bes, max(diswi[curr], disor[curr]));
			curr = pare[curr];
		}
		cout << bes;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par, int tim) {
	pare[curr] = par;
	int worst = w[curr] + tim;
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], dfs(v, curr, tim + 1)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int disor[NMAX];
void dfori(int curr, int par, int tim) {
	REMAX(disor[curr], w[curr] + tim);
	for(int v : eds[curr])
		if(v != par) {
			dfori(v, curr, tim + 1);
		}
}

int diswi[NMAX];
void dfwi(int curr, int par, int tim) {
	REMAX(diswi[curr], w[curr] + tim);
	for(int v : eds[curr])
		if(v != par) {
			dfwi(v, curr, tim + 1);
		}
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1, 0);
	if(wind[ind] == ind)
		cout << ma;
	else {
		dfori(ind, -1, 0);
		dfwi(wind[ind], -1, 0);
		int bes = wor[ind];
		int curr = wind[ind];
		while(curr != ind) {
			REMIN(bes, max(diswi[curr], disor[curr]));
			curr = pare[curr];
		}
		cout << bes;
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par) {
	pare[curr] = par;
	int worst = w[curr];
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], 1 + dfs(v, curr)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1);
	ma = wor[ind];
	while(wind[ind] != ind && RTIME < 1.95){
		ind = wind[ind];
		dfs(ind, -1);
		REMIN(ma, wor[ind]);
	}
	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
ll ma;

void dfs(int curr, int par, int tim) {
	REMAX(ma, w[curr] + tim);
	for(int v : eds[curr])
		if(v != par)
			dfs(v, curr, tim + 1);
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1, 0);

	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int vis[NMAX];
int pare[NMAX];
ll ma;

int tim[NMAX];

void dfs0(int curr, int par) {
	pare[curr] = par;
	for(int v : eds[curr])
		if(v != par)
			dfs0(v, curr);
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	vector<pair<ll, int>> gt;

	FOI(i, 1, N) {
		cin >> w[i];
		gt.pb({w[i], i});
	}

	sort(ALL(gt));
	ind = gt.back().se;
	ma = gt.back().fi;

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs0(ind, -1);
	vis[ind] = 1;

	FOD(i, SZ(gt) - 2, 0) {

		int go2 = gt[i].se;
		if(vis[go2]) continue;
		vi trav;

		while(!vis[go2]) {
			trav.pb(go2);
			go2 = pare[go2];
		}

		int currti = tim[go2];
		reverse(ALL(trav));

		for(int v : trav) {
			currti ++;
			vis[v] = 1;
			REMAX(ma, w[v] + currti);
		}

	}

	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 3e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
	if(!dec) cout<<"NO";
	exit(0);
}

ll w[NMAX];
vi eds[NMAX];
int wor[NMAX];
int wind[NMAX];
int sec[NMAX];
int pare[NMAX];
ll ma;

int dfs(int curr, int par) {
	pare[curr] = par;
	int worst = w[curr];
	wor[curr] = worst;
	wind[curr] = curr;
	for(int v : eds[curr])
		if(v != par) {
			if(REMAX(wor[curr], 1 + dfs(v, curr)))
				wind[curr] = wind[v];
		}
	return wor[curr];
}

int main(){
	ios_base::sync_with_stdio(false); cin.tie(0);

	cin >> N;
	ma = -1e18; int ind = -1;
	FOI(i, 1, N) {
		cin >> w[i];
		if(REMAX(ma, w[i]))
			ind = i;
	}

	FOI(i, 1, N - 1) {
		cin >> a >> b;
		eds[a].pb(b);
		eds[b].pb(a);
	}

	dfs(ind, -1);
	ma = wor[ind];
	while(wind[ind] != ind && RTIME < 1.95){
		dfs(wind[ind], -1);
		REMIN(ma, wor[ind]);
	}
	cout << ma;
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define fi first
#define se second
#define mp make_pair
#define SZ(x) ((int)(x.size()))
#define FOI(i,a,n) for(int (i)=int(a);(i)<=int(n);++(i))
#define FOD(i,a,n) for(int (i)=int(a);(i)>=int(n);--(i))
#define IN(x,y) ((y).find((x))!=(y).end())
#define ALL(t) t.begin(),t.end()
#define MSET(tabl,i) memset(tabl, i, sizeof(tabl))
#define PSET(x,y) fixed<<setprecision(y)<<lf(x)
#define DBG(c) cout << #c << " = " << c << endl;
#define RTIME ((double)clock()/(double)CLOCKS_PER_SEC)

template<typename T,typename S>inline bool REMIN(T&a,const S&b){return a>b?a=b,1:0;}
template<typename T,typename S>inline bool REMAX(T&a,const S&b){return a<b?a=b,1:0;}

typedef long long ll;
typedef long double lf;
typedef pair<int, int> pi;
typedef vector<pi> vpi;
typedef vector<int> vi;
typedef vector<vi> vvi;

int toint(const string &s) { stringstream ss; ss << s; int x; ss >> x; return x; }
string tostring ( int number ){  stringstream ss; ss<< number; return ss.str();}
int bit(ll x, int pos){ return ((1ll<<pos)&x) ? 1 : 0; }

const int INF = 1e9;
const int NMAX = 1e5+5;
const ll MOD = 1000000007;
const lf PI = 2*acos(0);

ll power(ll base, ll exp, ll c = MOD) { if(!exp) return 1; ll r = power(base, exp/2, c); r=(r*r)%c; if(exp&1) r=(r*base)%c; return r; }

int T,N,M;
int a,b,c;
string s1, s2;

void nope(int dec = 0){
      if(!dec) cout<<"NO";
      exit(0);
}

int flag1, flag2;
vi eds[NMAX * 3];
ll w[NMAX * 3];
ll ma, mind;

int main(){
      ios_base::sync_with_stdio(false); cin.tie(0);

      cin >> N;

      ma = -1e18;
      FOI(i, 1, N) {
            cin >> w[i];
            REMAX(ma, w[i]);
      }

      int cnm1 = 0, cnm0 = 0;
      FOI(i, 1, N) {
            if(w[i] == ma) cnm0 ++;
            if(w[i] == ma - 1) cnm1 ++;
      }

      FOI(i, 1, N - 1) {
            cin >> a >> b;
            eds[a].pb(b);
            eds[b].pb(a);
      }

      if(!cnm1 && !cnm0) {
            cout << ma;
            return 0;
      }
      if(!cnm0) {
            int cool = 0;
            FOI(i, 1, N) {
                  int c1 = (w[i] == ma - 1);
                  for(int v : eds[i])
                        if(w[v] == ma - 1)
                              c1 ++;
                  if(c1 == cnm1)
                        cool = 1;
            }
            if(cool)
                  cout << ma;
            else
                  cout << ma + 1;
            return 0;
      }
      FOI(i, 1, N) {
            int cool = 0;
            FOI(i, 1, N) {
                  int c1 = (w[i] == ma);
                  for(int v : eds[i])
                        if(w[v] == ma)
                              c1 ++;
                  if(c1 == cnm0)
                        cool = 1;
            }
            if(cool)
                  cout << ma + 1;
            else
                  cout << ma + 2;
            return 0;
      }

      return 0;
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
int a[MAX];
main(){
	long long int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++)
			maxa=max(a[i],maxa);
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=1;i<=n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%lld",&n)){
		for(int i=0;i<n;i++){
			scanf("%lld",&a[i]);
			G[i].clear();
		}
		for(int i=0;i<n-1;i++){
			long long int a,b;
			scanf("%lld%lld",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++){
	//		printf("%lld\n",a[i]);
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		//	printf("%lld\n",ans);
		}
		if(ans==-1000000001){
			for(int i=0;i<n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++)
			maxa=max(a[i],maxa);
		long long int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
				if(cnt==c2)
					ans=maxa;
			}
		}
		if(ans==-1000000001){
			for(int i=1;i<=n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
int a[MAX];
main(){
	int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
			G[i].clear();
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		int maxa=-1000000001;
		for(int i=0;i<n;i++){
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=0;i<n&&ans==-1000000001;i++){
				int res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v-1]==maxa)
						res++;
				//	printf("%d %d %d\n",a[v-1],v,maxa);
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%d\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%lld",&n)){
		for(int i=0;i<n;i++){
			scanf("%lld",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			long long int a,b;
			scanf("%lld%lld",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++){
		//	printf("%lld\n",a[i]);
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=0;i<n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			//	printf("%lld\n",ans);
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
int a[MAX];
main(){
	int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		int maxa=-1000000001;
		for(int i=0;i<n;i++)
			maxa=max(a[i],maxa);
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
				if(cnt==c2)
					ans=maxa;
			}
		}
		if(ans==-1000000001){
			for(int i=1;i<=n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
int a[MAX];
main(){
	int n;
	while(~scanf("%d",&n)){
		for(int i=1;i<=n;i++){
			scanf("%d",&a[i]);
			G[i].clear();
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		int maxa=-1000000001;
		for(int i=0;i<n;i++){
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=1;i<=n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=1;i<=n&&ans==-1000000001;i++){
				int res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%d\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%lld",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++){
		//	printf("%lld\n",a[i]);
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=0;i<n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			//	printf("%lld\n",ans);
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;i++){
			scanf("%d",&a[i]);
		}
		for(int i=0;i<n-1;i++){
			int a,b;
			scanf("%d%d",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++)
			maxa=max(a[i],maxa);
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
		}
		if(ans==-1000000001){
			for(int i=1;i<=n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> ii;
const ll inf=1e10;
const int N=2e6+20;
ll n,a[N],vis[N],can[N];
vector<int> e[N];
void solve()
{
	ll C1=0,C2=0,mx=-inf,u;
	for(int i=1;i<=n;i++)
		mx=max(a[i],mx);
	for(int i=1;i<=n;i++)
	{
		if(a[i]==mx)
			C1++,u=i;
		else if(a[i]==mx-1)
			C2++;
	}
	ll ans=inf;
	if(C1==1)//
	{
		int cnt=0;
		for(int i=0;i<e[u].size();i++)
		{
			int v=e[u][i];
			if(a[v]==mx-1)
				cnt++;
		}
		if(cnt==C2)
			ans=mx;
	}
	if(ans==inf)
	{
		for(int i=1;i<=n&&ans==inf;i++)//遍历边O(n),找到相邻为1内,有C1个mx
		{
			ll res=0;
			if(a[i]==mx)
				res++;
			for(int j=0;j<e[i].size();j++)
			{
				int v=e[i][j];
				if(a[v]==mx)
					res++;
			}
			if(res==C1)
				ans=mx+1;
		}
	}
	if(ans==inf)
		ans=mx+2;
	cout<<ans<<endl;
}
int main()
{
	while(cin>>n)
	{
		for(int i=1;i<=n;i++)
			scanf("%I64d",&a[i]),e[i].clear();
		int u,v;
		for(int i=1;i<=n-1;i++)
		{
			scanf("%d%d",&u,&v);
			e[u].push_back(v);
			e[v].push_back(u);
		}
		solve();
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 300005
vector<int> G[MAX];
long long int a[MAX];
main(){
	long long int n;
	while(~scanf("%lld",&n)){
		for(int i=0;i<n;i++){
			scanf("%lld",&a[i]);
			G[i].clear();
		}
		for(int i=0;i<n-1;i++){
			long long int a,b;
			scanf("%lld%lld",&a,&b);
			G[a].push_back(b);
			G[b].push_back(a);
		}
		long long int maxa=-1000000001;
		for(int i=0;i<n;i++){
			printf("%lld\n",a[i]);
			maxa=max(a[i],maxa);
		}
		int c1=0,c2=0,u;
		for(int i=0;i<n;i++){
			if(a[i]==maxa)
				c1++,u=i;
			else if(a[i]==maxa-1)
				c2++;
		}
		long long int ans=-1000000001;
		if(c1==1){
			int cnt=0;
			for(int i=0;i<G[u].size();i++){
				int v=G[u][i];
				if(a[v]==maxa-1)
					cnt++;
			}
			if(cnt==c2)
				ans=maxa;
			printf("%lld\n",ans);
		}
		if(ans==-1000000001){
			for(int i=0;i<n&&ans==-1000000001;i++){
				long long res=0;
				if(a[i]==maxa)
					res++;
				for(int j=0;j<G[i].size();j++){
					int v=G[i][j];
					if(a[v]==maxa)
						res++;
				}
				if(res==c1)
					ans=maxa+1;
			}
		}
		if(ans==-1000000001)
			ans=maxa+2;
		printf("%lld\n",ans);
	}
}


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+1)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

pil tree[4*N]; int A[N], n ;
bool hacked[N];
vector <int> adj[N];

void build(int node, int start, int end)
{
	/* Builds the segment tree */
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else if (s1.s == s2.s and adj[s1.f] > adj[s2.f] )
        return s1 ;
    else
        return s2 ;
}

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    build(0, 0, n-1);
    pil best = query(0, 0, n-1, 0, n-1);

    ll mx = best.s, req = -INF ;

    int node = best.f, next ;

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        req = -INF ; next = node ;

        for(auto head : adj[node])
        {

            if(hacked[head])
                continue ;

            A[head]++ ; // update(0, 0, n-1, head, 1);

            if(A[head] > req)
            {
                req = A[head] ; next = head ;
            }
            else if ( A[head] == req and adj[head] > adj[next] )
            {
                req = A[head] ; next = head ;
            }

            // printii(node, head);

            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    A[tail]++ ; // update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        A[node] = -INF ;
        //update(0, 0, n-1, node, -INF);
        /*
        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;
        */
        if(req > mx)
            mx = req ;
        node = next ;
    }

    printl(mx);

    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+3)
#define INF 10000000000001
const int inf = INT_MAX ;
const int mod = 1e9 + 7 ;

// pil tree[4*N];
int A[N],  n ;
multiset <int> ms ;
vector <int> adj[N];

int main()
{
    geti(n);
    FOR(n)
    {
        geti(A[i]);
        ms.insert(A[i]);
    }

    int tail, head, mx = inf ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    FOR(n)
    {
        int temp_max = A[i] ;
        // Using find so that all A[i] are not erased
        ms.erase(ms.find(A[i]));

        for(auto head : adj[i])
        {
            temp_max = max(temp_max, A[head] + 1);
            ms.erase(ms.find(A[head])); // Same reason for find
        }

        if(!ms.empty())
            temp_max = max(temp_max, *ms.rbegin() + 2);

        for(auto head : adj[i])
            ms.insert(A[head]);

        ms.insert(A[i]);
        mx = min(mx, temp_max);

    }

    printi(mx);
    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+1)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

pil tree[4*N]; int A[N], n ;
bool hacked[N];
vector <int> adj[N];

void build(int node, int start, int end)
{
	/* Builds the segment tree */
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else
        return s2 ;
}

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    build(0, 0, n-1);
    pil best = query(0, 0, n-1, 0, n-1);

    ll mx = best.s, req ;

    int node = best.f ;

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        for(auto head : adj[node])
        {
            update(0, 0, n-1, head, 1);
            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        update(0, 0, n-1, node, -INF);

        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;

    }

    printl(mx);

    return 0;
}


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+3)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

// pil tree[4*N];
int A[N],  n ;
multiset <int> ms ;
vector <int> adj[N];

int main()
{
    geti(n);
    FOR(n)
    {
        geti(A[i]);
        ms.insert(A[i]);
    }

    int tail, head, mx = inf ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    FOR(n)
    {
        int temp_max = A[i] ;
        // Using find so that all A[i] are not erased
        ms.erase(ms.find(A[i]));

        for(auto head : adj[i])
        {
            temp_max = max(temp_max, A[head] + 1);
            ms.erase(ms.find(A[head])); // Same reason for find
        }

        if(!ms.empty())
            temp_max = max(temp_max, *ms.rbegin() + 2);

        for(auto head : adj[i])
            ms.insert(A[head]);

        ms.insert(A[i]);

        mx = min(mx, temp_max);

    }

    printi(mx);
    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+1)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

pil tree[4*N]; int A[N], n ;
bool hacked[N];
vector <int> adj[N];

void build(int node, int start, int end)
{
	/* Builds the segment tree */
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else if (s1.s == s2.s and adj[s1.f] > adj[s2.f] )
        return s1 ;
    else
        return s2 ;
}

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    build(0, 0, n-1);
    pil best = query(0, 0, n-1, 0, n-1);

    ll mx = best.s, req ;

    int node = best.f ;

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        for(auto head : adj[node])
        {

            if(hacked[head])
                continue ;

            update(0, 0, n-1, head, 1);
            // printii(node, head);

            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        update(0, 0, n-1, node, -INF);

        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;

    }

    printl(mx);

    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+1)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

pil tree[4*N];
ll A[N] ; int  n ;
bool hacked[N];
vector <int> adj[N];

void build(int node, int start, int end)
{
	/* Builds the segment tree */
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else if (s1.s == s2.s and adj[s1.f] > adj[s2.f] )
        return s1 ;
    else
        return s2 ;
}

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    //build(0, 0, n-1);
    //pil best = query(0, 0, n-1, 0, n-1);

    ll mx = -INF, req = -INF ;
    int node = 0, next ;

    FOR(n)
    {
        if(A[i] > mx or ( A[i] == mx and adj[i] > adj[node] ) )
        {
            mx = A[i]; node = i ;
        }
    }

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        req = -INF ; next = node ;

        for(auto head : adj[node])
        {

            if(hacked[head])
                continue ;

            A[head]++ ; // update(0, 0, n-1, head, 1);

            if(A[head] > req)
            {
                req = A[head] ; next = head ;
            }
            else if ( A[head] == req and adj[head] > adj[next] )
            {
                req = A[head] ; next = head ;
            }

            //printii(node, head);

            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    A[tail]++ ; // update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        A[node] = -INF ;
        //update(0, 0, n-1, node, -INF);
        /*
        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;
        */
        if(req > mx)
            mx = req ;
        node = next ;
    }

    printl(mx);

    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+3)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

// pil tree[4*N];
int A[N],  n ;
bool hacked[N];
vector <int> adj[N];

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    int mx = -inf , req = -inf ;
    int node = 0, next ;

    FOR(n)
    {
        if(A[i] > mx or ( A[i] == mx and adj[i].size() > adj[node].size() ) )
            mx = A[i], node = i ;

    }

    priority_queue<pi> heap ;
    heap.push({A[node], node});

    while(!heap.empty())
    {
        node = heap.top().s ;
        req = heap.top().f ;

        heap.pop();

        hacked[node] = true ;
        mx = max(mx, req);

        for(auto head : adj[node])
        {
            if(!hacked[head]) // Online bank k ( i -> k -> j )
            {
                A[head]++ ;
                heap.push({A[head], head});
                for(auto tail : adj[head]) // Semi neighbouring bank
                    A[tail]++;
            }
        }
    }

    cout << mx << endl ;
    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+1)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

pil tree[4*N];
ll A[N] ; int  n ;
bool hacked[N];
vector <int> adj[N];

void build(int node, int start, int end)
{
	/* Builds the segment tree */
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else if (s1.s == s2.s and adj[s1.f] > adj[s2.f] )
        return s1 ;
    else
        return s2 ;
}

int main()
{
    geti(n);
    FOR(n)
        getl(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    //build(0, 0, n-1);
    //pil best = query(0, 0, n-1, 0, n-1);

    ll mx = -INF, req = -INF ;
    int node = 0, next ;

    FOR(n)
    {
        if(A[i] > mx or ( A[i] == mx and adj[i] > adj[node] ) )
        {
            mx = A[i]; node = i ;
        }
    }

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        req = -INF ; next = node ;

        for(auto head : adj[node])
        {

            if(hacked[head])
                continue ;

            A[head]++ ; // update(0, 0, n-1, head, 1);

            if(A[head] > req)
            {
                req = A[head] ; next = head ;
            }
            else if ( A[head] == req and adj[head] > adj[next] )
            {
                req = A[head] ; next = head ;
            }

            //printii(node, head);

            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    A[tail]++ ; // update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        A[node] = -INF ;
        //update(0, 0, n-1, node, -INF);
        /*
        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;
        */
        if(req > mx)
            mx = req ;
        node = next ;
    }

    printl(mx);

    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+3)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

// pil tree[4*N];
ll A[N] ; int  n ;
bool hacked[N];
vector <int> adj[N];

/*

void build(int node, int start, int end)
{
	if (start == end)
		tree[node] = make_pair( start, A[start] ) ;

	else
	{
		int mid = (start + end)/2;
		build(2*node + 1, start, mid);
		build(2*node + 2, mid+1, end);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;
		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

void update(int node, int start, int end, int idx, int val)
{
	if (start == end)
	{
		A[idx] += val;
		tree[node].s += val;
	}
	else
	{
		int mid = (start + end)/2;

		if (idx >= start && idx <= mid)
			update(2*node + 1, start, mid, idx, val);
		else
			update(2*node + 2, mid+1, end, idx, val);

		pil left = tree[node*2 + 1], right = tree[node*2+2] ;

		if(left.s > right.s)
            tree[node] = make_pair( left.f, left.s );
        else if ( left.s == right.s and adj[left.f] > adj[right.f] )
            tree[node] = make_pair( left.f, left.s );
        else
            tree[node] = make_pair( right.f, right.s );
	}
}

pil query(int node, int start, int end, int l, int r)
{
	if (r < start || end < l)
		return make_pair( -1, -INF );

	if (l <= start && r >= end)
		return make_pair( tree[node].f, tree[node].s ) ;

	int mid = (start + end)/2;
	pil s1 = query(node*2 + 1, start, mid, l, r);
	pil s2 = query(node*2 + 2, mid + 1, end, l, r);

	if(s1.s > s2.s)
        return s1 ;
    else if (s1.s == s2.s and adj[s1.f] > adj[s2.f] )
        return s1 ;
    else
        return s2 ;
}

*/

int main()
{
    geti(n);
    FOR(n)
        getl(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    //build(0, 0, n-1);
    //pil best = query(0, 0, n-1, 0, n-1);

    ll mx = -INF, req = -INF ;
    int node = 0, next ;

    FOR(n)
    {
        if(A[i] > mx or ( A[i] == mx and adj[i] > adj[node] ) )
        {
            mx = A[i]; node = i ;
        }
    }

    // printl(mx);
    // printi(node);

    while(!hacked[node])
    {
        req = -INF ; next = node ;

        for(auto head : adj[node])
        {

            A[head]++ ; // update(0, 0, n-1, head, 1);

            if(hacked[head])
                continue ;

            if(A[head] > req)
            {
                req = A[head] ; next = head ;
            }
            else if ( A[head] == req and adj[head] > adj[next] )
            {
                req = A[head] ; next = head ;
            }

            //printii(node, head);

            for(auto tail : adj[head])
            {
                if(tail != node)
                {
                    A[tail]++ ; // update(0, 0, n-1, tail, 1);
                }
            }
        }

        hacked[node] = true ;
        A[node] = -INF ;
        //update(0, 0, n-1, node, -INF);
        /*
        best = query(0, 0, n-1, 0, n-1);
        if(best.s > mx)
            mx = best.s ;
        node = best.f ;
        */
        if(req > mx)
            mx = req ;
        node = next ;
    }

    printl(mx);

    return 0;
}
/*
3

2 2 2

3 2

1 2
*/


#include <bits/stdc++.h>
using namespace std ;

#define geti(a) scanf("%d", &a) // i.e. get_int
#define getii(a, b) scanf("%d %d", &a, &b)
#define getiii(a, b, c) scanf("%d %d %d", &a, &b, &c)

#define getl(a) scanf("%lld", &a) // i.e. get_long_long_int
#define getll(a, b) scanf("%lld %lld", &a, &b)
#define getlll(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)

#define gets(a) scanf("%s", &a) // i.e. get_string
#define getss(a, b) scanf("%s %s", &a, &b)

#define printi(a) printf("%d\n", a)
#define printl(a) printf("%lld\n", a)
#define printii(a, b) printf("%d %d\n", a, b)
#define printiii(a, b, c) printf("%d %d %d\n", a, b, c)
#define printll(a, b) printf("%lld %lld\n", a, b)
#define prints(a) printf("%s\n", a)
#define printss(a, b) printf("%s %s\n", a, b)
#define printline printf("\n")

#define ll long long int
#define pb push_back

#define FAST_IO ios_base::sync_with_stdio(0) ; cin.tie(0)
#define SET(list, val) memset(list, val, sizeof(list))

#define pi pair<int, int>
#define pl pair<ll, ll>
#define pii pair<int, pi>
#define pil pair<int, ll>
#define f first
#define s second

#define FOR(n) for(int i = 0; i < n; i++) // From 0 to n-1
#define FORA(a, b) for(int i = (a); i <= (b); i++) // From a to b to increasing
#define DFOR(n) for(int i = n; i >= 0; i--) // From n to 0
#define DFORA(a, b) for(int i = (a); i >= (b); i--) // From a to b decrementing

#define N (int) (3*1e5+3)
#define INF 10000000000001
const int inf = 1e9 + 1 ;
const int mod = 1e9 + 7 ;

// pil tree[4*N];
int A[N],  n ;
bool hacked[N];
vector <int> adj[N];

int main()
{
    geti(n);
    FOR(n)
        geti(A[i]);

    int tail, head ;
    FOR(n-1)
    {
        getii(tail, head);
        adj[tail-1].pb(head-1);
        adj[head-1].pb(tail-1);
    }

    SET(hacked, 0);

    int mx = -inf , req = -inf ;
    int node = 0, next ;

    FOR(n)
    {
        if(A[i] > mx or ( A[i] == mx and adj[i] > adj[node] ) )
            mx = A[i], node = i ;

    }

    priority_queue<pi> heap ;
    heap.push({A[node], node});

    while(!heap.empty())
    {
        node = heap.top().s ;
        req = heap.top().f ;

        heap.pop();

        hacked[node] = true ;
        mx = max(mx, req);

        for(auto head : adj[node])
        {
            if(!hacked[head]) // Online bank k ( i -> k -> j )
            {
                A[head]++ ;
                heap.push({A[head], head});
                for(auto tail : adj[head]) // Semi neighbouring bank
                    A[tail]++;
            }
        }
    }

    cout << mx << endl ;
    return 0;
}
/*
3

2 2 2

3 2

1 2
*/