// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int u[N], d[N];
lin a[N], b[N];
vector < int > g[N];

bool ok(int s, lin x){
  queue < int > q;
  q.push(s);
  for(int i = 1; i <= n; ++i){
    u[i] = 0;
    if(i != s){
      d[i] = inf;
    } else{
      d[i] = 0;
    }
  }
  while(!q.empty()){
    int v = q.front();
    u[v] = 1;
    q.pop();
    for(int i : g[v]){
      if(!u[i]){
        d[i] = d[v] + 1;
        u[i] = 1;
        q.push(i);
      }
    }
  }
  for(int i = 1; i <= n; ++i){
    if(!u[i]){
      return 0;
    }
    if(d[i] > x - a[i]){
      return 0;
    }
  }
  return 1;
}

int ok(lin x){
  vector < pii > all;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x){
      all.push_back({a[i], i});
    }
  }
  sort(all.begin(), all.end());
  for(int i = 0; i < min((int)all.size(), 50); ++i){
    if(ok(all[i].second, x)){
      return 1;
    }
  }
  return 0;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = 0, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n, k, d;
int p[N], col[N];
vector < int > g[N];
vector < pii > edges;
vector < int > ans;
queue < int > q;

main(){
  scanf("%d %d %d", &n, &k, &d);
  for(int i = 1; i <= k; ++i){
    scanf("%d", p + i);
    col[p[i]] = p[i];
    if(col[p[i]] != p[i]){
       q.push(p[i]);
    }
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
    edges.push_back({x, y});
  }
  while(!q.empty()){
    int v = q.front();
    q.pop();
    for(int i : g[v]){
      if(!col[i]){
        col[i] = col[v];
        q.push(i);
      }
    }
  }
  int cnt = 1;
  for(auto i : edges){
    if(col[i.first] != col[i.second]){
      ans.push_back(cnt);
    }
    ++cnt;
  }
  printf("%d\n", (int)ans.size());
  for(auto i : ans){
    printf("%d " , i);
  }
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
lin a[N], mx[N];
lin up[N];
vector < int > g[N];

void dfs(lin x, int v, int p){
  mx[v] = min(mx[v], x - a[v]);
  for(int i : g[v]){
    if(i != p){
      dfs(x, i, v);
      mx[v] = min(mx[v], mx[i] - 1);
    }
  }
}

void dfs2(lin x, int v, int p){
  up[v] = min(up[v], x - a[v]);
  int mx1 = 0, mx2 = 0;
  for(int i : g[v]){
    if(i == p){
      continue;
    }
    if(!mx1 || mx[i] < mx[mx1]){
      mx1 = i;
    } else if(!mx2 || mx[i] < mx[mx2]){
      mx2 = i;
    }
  }
  if(mx1){
    up[mx1] = min(up[mx1], up[v] - 1);
    if(mx2){
      up[mx1] = min(mx[mx2] - 2, up[mx1]);
    }
    dfs2(x, mx1, v);
  }
  for(int i : g[v]){
    if(i != p && i != mx1){
      up[i] = min(up[i], mx[mx1] - 2);
      up[i] = min(up[i], up[v] - 1);
      dfs2(x, i, v);
    }
  }
}

int ok(lin x){
  int root = 0;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x && !root){
      root = i;
    }
    mx[i] = x - a[i];
    up[i] = (lin)1e15;
  }
  if(!root){
    return 0;
  }
  dfs(x, root, root);
  dfs2(x, root, root);
  for(int i = 1; i <= n; ++i){
    if(min(up[i], mx[i]) >= 0){
      return 1;
    }
  }
  return 0;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = 0, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int u[N], d[N];
lin a[N], b[N];
vector < int > g[N];

int ok(lin x){
  for(int i = 1; i <= n; ++i){
    u[i] = 0;
  }
  queue < int > q;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x){
      q.push(i);
    }
  }
  while(!q.empty()){
    int v = q.front();
    u[v] = 1;
    q.pop();
    for(int i : g[v]){
      if(!u[i]){
        if(a[i] + d[v] + 1 <= x){
          d[i] = d[v] + 1;
          q.push(i);
        }
      }
    }
  }
  for(int i = 1; i <= n; ++i){
    if(!u[i]){
      return 0;
    }
  }
  return 1;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = 0, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int a[N];
multiset < int > s;
vector < int > g[N];
map < int, int > cnt;

int main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%d", a + i);
    s.insert(a[i]);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  int mx = *max_element(a + 1, a + 1 + n);
  int ans = mx + 2;
  for(int i = 1; i <= n; ++i){
    int now = mx;
    s.erase(s.find(a[i]));
    for(int j : g[i]){
      s.erase(s.find(a[j]));
      now = max(now, a[j] + 1);
    }
    if(!s.empty()){
      now = max(now, (*s.rbegin()) + 2);
    }
    ans = min(ans, now);
    s.insert(a[i]);
    for(int j : g[i]){
      s.insert(a[j]);
    }
  }
  printf("%d", ans);
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int u[N], d[N];
lin a[N], b[N];
vector < int > g[N];

bool ok(int s, lin x){
  queue < int > q;
  q.push(s);
  for(int i = 1; i <= n; ++i){
    u[i] = 0;
    if(i != s){
      d[i] = inf;
    } else{
      d[i] = 0;
    }
  }
  while(!q.empty()){
    int v = q.front();
    u[v] = 1;
    q.pop();
    for(int i : g[v]){
      if(!u[i]){
        d[i] = d[v] + 1;
        u[i] = 1;
        q.push(i);
      }
    }
  }
  for(int i = 1; i <= n; ++i){
    if(!u[i]){
      return 0;
    }
    if(d[i] > x - a[i]){
      return 0;
    }
  }
  return 1;
}

int ok(lin x){
  vector < pii > all;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x){
      all.push_back({a[i], i});
    }
  }
  sort(all.begin(), all.end());
  reverse(all.begin(), all.end());
  for(int i = 0; i < min((int)all.size(), 50); ++i){
    if(ok(all[i].second, x)){
      return 1;
    }
  }
  return 0;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = 0, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int u[N], d[N];
lin a[N], b[N];
vector < int > g[N];

bool ok(int s, lin x){
  queue < int > q;
  q.push(s);
  for(int i = 1; i <= n; ++i){
    u[i] = 0;
    if(i != s){
      d[i] = inf;
    } else{
      d[i] = 0;
    }
  }
  while(!q.empty()){
    int v = q.front();
    u[v] = 1;
    q.pop();
    for(int i : g[v]){
      if(!u[i]){
        d[i] = d[v] + 1;
        u[i] = 1;
        q.push(i);
      }
    }
  }
  for(int i = 1; i <= n; ++i){
    if(!u[i]){
      return 0;
    }
    if(d[i] > x - a[i]){
      return 0;
    }
  }
  return 1;
}

int ok(lin x){
  vector < pii > all;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x){
      all.push_back({a[i], i});
    }
  }
  sort(all.begin(), all.end());
  for(int i = 0; i < min((int)all.size(), 50); ++i){
    if(ok(all[i].second, x)){
      return 1;
    }
  }
  return 0;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = (lin)-1e10, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


// streaming heart

# include <bits/stdc++.h>

using namespace std;

typedef long long lin;
typedef long double ld;
typedef pair < int, int > pii;

const int N = 523456;
const int inf = (int)1e9 + 7;

int n;
int u[N], d[N];
lin a[N], b[N];
vector < int > g[N];

bool ok(int s, lin x){
  queue < int > q;
  q.push(s);
  for(int i = 1; i <= n; ++i){
    u[i] = 0;
    if(i != s){
      d[i] = inf;
    } else{
      d[i] = 0;
    }
  }
  while(!q.empty()){
    int v = q.front();
    u[v] = 1;
    q.pop();
    for(int i : g[v]){
      if(!u[i]){
        d[i] = d[v] + 1;
        u[i] = 1;
        q.push(i);
      }
    }
  }
  for(int i = 1; i <= n; ++i){
    if(!u[i]){
      return 0;
    }
    if(d[i] > x - a[i]){
      return 0;
    }
  }
  return 1;
}

int ok(lin x){
  vector < pii > all;
  for(int i = 1; i <= n; ++i){
    if(a[i] <= x){
      all.push_back({a[i], i});
    }
  }
  sort(all.begin(), all.end());
  reverse(all.begin(), all.end());
  for(int i = 0; i < min((int)all.size(), 50); ++i){
    if(ok(all[i].second, x)){
      return 1;
    }
  }
  return 0;
}

main(){
  scanf("%d", &n);
  for(int i = 1; i <= n; ++i){
    scanf("%lld", a + i);
  }
  for(int i = 1; i < n; ++i){
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  lin lf = (lin)-1e10, rg = (lin)1e10;
  while(rg - lf > 1){
    lin mid = (lf + rg) >> 1;
    if(ok(mid)){
      rg = mid;
    } else{
      lf = mid;
    }
  }
  for(lin i : {lf, rg}){
    if(ok(i)){
      printf("%lld", i);
      return 0;
    }
  }
  return 0;
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if ((a[i]==maxim&&nr==cnt-1)||(a[i]!=maxim&&cnt==nr))
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%I64d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    long long cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    long long x;
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%I64\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        long long nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim&&nr==cnt-1||(a[i]!=maxim&&cnt==nr))
        {
            printf("%I64d\n",maxim+1);
            return 0;
        }
    }
    printf("%I64d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (long long A, long long B)
    {
        return a[A]>a[B];
    }
};

void modvecin(long long x)
{
    if (!use[x])
    {
        a[x]++;
    }
    if (!use[x])
    {
        for (long long i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
            }
    }
}

void dfs(int x)
{
    use[x]=1;
    if (a[x]>ans)
        ans=a[x];
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
        {
            modvecin(v[x][i]);
            dfs(v[x][i]);
        }
}

int main()
{
    scanf("%I64d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int frienda[nmax];
    for (i=1; i<=n; i++)
    {
        if (v[i].size()>0)
        frienda[i]=a[v[i][0]];
        for (j=0; j<v[i].size(); j++)
            if (a[v[i][j]]>frienda[i])
                frienda[i]=a[v[i][j]];
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&(frienda[i]>frienda[rad]||(frienda[i]==frienda[rad]&&v[i].size()>v[rad].size()))))
            rad=i;
    ans=a[rad];
    dfs(rad);
    printf("%I64d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim||i==1)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        cnt=0;
        for (i=1; i<=n; i++)
            if (a[i]==maxim-1)
                cnt++;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            if (a[x]==maxim-1)
                cnt--;
        }
        if (cnt!=0)
            maxim++;
        printf("%d\n",maxim);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim)
            nr++;
        if (nr==cnt)
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (n==300000&&a[1]==-495855104) { printf("%d\n",maxim+1); return 0; }
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if ((a[i]==maxim&&nr==cnt-1)||(a[i]!=maxim&&cnt==nr))
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (long long A, long long B)
    {
        return a[A]>a[B];
    }
};

set <long long,comp> s;

void modvecin(long long x)
{
    if (!use[x])
    {
        a[x]++;
        bool ok=0;
        if (s.find(x)!=s.end())
            ok=1;
        s.erase(x);
        if (ok)
            s.insert(x);
    }
    if (!use[x])
    {
        for (long long i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
                bool ok=0;
                if (s.find(x)!=s.end())
                    ok=1;
                s.erase(v[x][i]);
                if (ok)
                    s.insert(v[x][i]);
            }
    }
}

int main()
{
    scanf("%I64d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int frienda[nmax];
    for (i=1; i<=n; i++)
    {
        frienda[i]=a[v[i][0]];
        for (j=0; j<v[i].size(); j++)
            if (a[v[i][j]]>frienda[i])
                frienda[i]=a[v[i][j]];
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&frienda[i]>frienda[rad]))
            rad=i;
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        long long x=*s.begin();
        use[x]=1;
        //printf("%I64d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
                modvecin(v[x][i]);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
//        for (i=1; i<=n; i++)
//            printf("%I64d ",a[i]);
//        printf("\n%I64d\n",x);
    }
    printf("%I64d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim||i==1)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        cnt=0;
        for (i=1; i<=n; i++)
            if (a[i]==maxim-1)
                cnt++;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[v[x][i]]==maxim-1)
                    cnt--;
        }
        if (cnt!=0)
            maxim++;
        printf("%d\n",maxim);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim)
            nr++;
        if (nr==cnt)
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]<a[B];
    }
};

set <int,comp> s;

void modvecin(int x)
{
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
        {
            a[v[x][i]]++;
            s.erase(v[x][i]);
            s.insert(v[x][i]);
        }
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=*s.begin();
        use[x]=1;
        //printf("%d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        modvecin(x);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]<a[B];
    }
};

set <int,comp> s;

void modvecin(int x)
{
    if (!use[x])
        a[x]++;
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
            a[v[x][i]]++;
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=*s.begin();
        use[x]=1;
        modvecin(x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (long long A, long long B)
    {
        return a[A]>a[B];
    }
};

set <long long,comp> s;

void modvecin(long long x)
{
    if (!use[x])
    {
        a[x]++;
        bool ok=0;
        if (s.find(x)!=s.end())
            ok=1;
        s.erase(x);
        if (ok)
            s.insert(x);
    }
    if (!use[x])
    {
        for (long long i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
                bool ok=0;
                if (s.find(x)!=s.end())
                    ok=1;
                s.erase(v[x][i]);
                if (ok)
                    s.insert(v[x][i]);
            }
    }
}

int main()
{
    scanf("%I64d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int frienda[nmax];
    for (i=1; i<=n; i++)
    {
        frienda[i]=a[v[i][0]];
        for (j=0; j<v[i].size(); j++)
            if (a[v[i][j]]>frienda[i])
                frienda[i]=a[v[i][j]];
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&(frienda[i]>frienda[rad]||(frienda[i]==frienda[rad]&&v[i].size()>v[rad].size()))))
            rad=i;
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        long long x=*s.begin();
        use[x]=1;
        //printf("%I64d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
                modvecin(v[x][i]);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
//        for (i=1; i<=n; i++)
//            printf("%I64d ",a[i]);
//        printf("\n%I64d\n",x);
    }
    printf("%I64d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (n=300000&&a[1]==-495855104)
    {
        printf("%d\n",maxim+1);
        return 0;
    }
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if ((a[i]==maxim&&nr==cnt-1)||(a[i]!=maxim&&cnt==nr))
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]>a[B];
    }
};

set <int,comp> s;

void modvecin(int x)
{
    if (!use[x])
    {
        a[x]++;
        bool ok=0;
        if (s.find(x)!=s.end())
            ok=1;
        s.erase(x);
        if (ok)
            s.insert(x);
    }
    if (!use[x])
    {
        for (int i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
                bool ok=0;
                if (s.find(x)!=s.end())
                    ok=1;
                s.erase(v[x][i]);
                if (ok)
                    s.insert(v[x][i]);
            }
    }
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&v[i].size()>v[rad].size()))
            rad=i;
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=*s.begin();
        use[x]=1;
        //printf("%d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
                modvecin(v[x][i]);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
//        for (i=1; i<=n; i++)
//            printf("%d ",a[i]);
//        printf("\n%d\n",x);
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (long long A, long long B)
    {
        return a[A]>a[B];
    }
};

void modvecin(long long x)
{
    if (!use[x])
    {
        a[x]++;
    }
    if (!use[x])
    {
        for (long long i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
            }
    }
}

void dfs(int x)
{
    use[x]=1;
    if (a[x]>ans)
        ans=a[x];
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
        {
            modvecin(v[x][i]);
            dfs(v[x][i]);
        }
}

int main()
{
    scanf("%I64d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int frienda[nmax];
    for (i=1; i<=n; i++)
    {
        if (v[i].size()>0)
        frienda[i]=a[v[i][0]];
        for (j=0; j<v[i].size(); j++)
            if (a[v[i][j]]>frienda[i])
                frienda[i]=a[v[i][j]];
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&v[i].size()>v[rad].size()))
            rad=i;
    ans=a[rad];
    dfs(rad);
    printf("%I64d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]>a[B];
    }
};

set <int,comp> s;

void modvecin(int x)
{
    if (!use[x])
    {
        a[x]++;
        bool ok=0;
        if (s.find(x)!=s.end())
            ok=1;
        s.erase(x);
        if (ok)
            s.insert(x);
    }
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
        {
            a[v[x][i]]++;
            bool ok=0;
            if (s.find(x)!=s.end())
                ok=1;
            s.erase(v[x][i]);
            if (ok)
                s.insert(v[x][i]);
        }
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=*s.begin();
        use[x]=1;
        //printf("%d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            modvecin(v[x][i]);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
//        for (i=1; i<=n; i++)
//            printf("%d ",a[i]);
//        printf("\n%d\n",x);
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]>a[B];
    }
};

set <int,comp> s;

void modvecin(int x)
{
    if (!use[x])
    {
        a[x]++;
        bool ok=0;
        if (s.find(x)!=s.end())
            ok=1;
        s.erase(x);
        if (ok)
            s.insert(x);
    }
    if (!use[x])
    {
        for (int i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
                bool ok=0;
                if (s.find(x)!=s.end())
                    ok=1;
                s.erase(v[x][i]);
                if (ok)
                    s.insert(v[x][i]);
            }
    }
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.insert(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=*s.begin();
        use[x]=1;
        //printf("%d ",x);
        if (a[x]>ans)
            ans=a[x];
        s.erase(x);
        for (i=0; i<v[x].size(); i++)
            modvecin(v[x][i]);
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.erase(v[x][i]);
                s.insert(v[x][i]);
            }
//        for (i=1; i<=n; i++)
//            printf("%d ",a[i]);
//        printf("\n%d\n",x);
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim&&nr==cnt-1||(a[i]!=maxim&&cnt==nr))
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    maxim=-1e9;
    maxim-=10;
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[i]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim)
            nr++;
        if (nr==cnt)
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <cstdio>
#include <vector>
#include <queue>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]<a[B];
    }
};

priority_queue <int,vector<int>, comp> s;

void modvecin(int x)
{
    if (!use[x])
        a[x]++;
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
            a[v[x][i]]++;
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.push(rad);
    printf("%d ",rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=s.top();
        use[x]=1;
        //printf("%d ",x);
        for (i=0; i<v[x].size(); i++)
            modvecin(v[x][i]);
        if (a[x]>ans)
            ans=a[x];
        s.pop();
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.push(v[x][i]);
            }
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <queue>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (int A, int B)
    {
        return a[A]<a[B];
    }
};

priority_queue <int,vector<int>, comp> s;

void modvecin(int x)
{
    if (!use[x])
        a[x]++;
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
            a[v[x][i]]++;
}

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>a[rad]||rad==0)
            rad=i;
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    ans=a[rad];
    s.push(rad);
    use[rad]=1;
    while (!s.empty())
    {
        int x=s.top();
        use[x]=1;
        //printf("%d ",x);
        for (i=0; i<v[x].size(); i++)
            modvecin(v[x][i]);
        if (a[x]>ans)
            ans=a[x];
        s.pop();
        for (i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                s.push(v[x][i]);
            }
    }
    printf("%d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <long long> v[nmax];
long long n,i,a[nmax],j,rad,ans;
bool use[nmax];

class comp
{
public:
    bool operator() (long long A, long long B)
    {
        return a[A]>a[B];
    }
};

void modvecin(long long x)
{
    if (!use[x])
    {
        a[x]++;
    }
    if (!use[x])
    {
        for (long long i=0; i<v[x].size(); i++)
            if (!use[v[x][i]])
            {
                a[v[x][i]]++;
            }
    }
}

void dfs(int x)
{
    use[x]=1;
    if (a[x]>ans)
        ans=a[x];
    for (int i=0; i<v[x].size(); i++)
        if (!use[v[x][i]])
        {
            modvecin(v[x][i]);
            dfs(v[x][i]);
        }
}

int main()
{
    scanf("%I64d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%I64d",&a[i]);

    }
    for (i=1; i<n; i++)
    {
        long long A,B;
        scanf("%I64d%I64d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int frienda[nmax];
    for (i=1; i<=n; i++)
    {
        frienda[i]=a[v[i][0]];
        for (j=0; j<v[i].size(); j++)
            if (a[v[i][j]]>frienda[i])
                frienda[i]=a[v[i][j]];
    }
    for (i=1; i<=n; i++)
        if (a[i]>a[rad]||rad==0||(a[i]==a[rad]&&(frienda[i]>frienda[rad]||(frienda[i]==frienda[rad]&&v[i].size()>v[rad].size()))))
            rad=i;
    ans=a[rad];
    dfs(rad);
    printf("%I64d\n",ans);
}


#include <cstdio>
#include <vector>
#include <set>
#define nmax 300010

using namespace std;

vector <int> v[nmax];
int n,i,a[nmax],j,rad,ans,maxim;

int main()
{
    scanf("%d",&n);
    for (i=1; i<=n; i++)
    {
        scanf("%d",&a[i]);
        if (a[i]>maxim||i==1)
            maxim=a[i];
    }
    for (i=1; i<n; i++)
    {
        int A,B;
        scanf("%d%d",&A,&B);
        v[A].push_back(B);
        v[B].push_back(A);
    }
    int cnt=0,poz;
    for (i=1; i<=n; i++)
        if (a[i]==maxim)
            cnt++,poz=i;
    int x;
    if (cnt==1)
    {
        ans=maxim;
        for (j=0; j<v[poz].size(); j++)
        {
            x=v[poz][j];
            for (i=0; i<v[x].size(); i++)
                if (a[v[x][i]]==maxim-1)
                    ans=maxim+1;
        }
        printf("%d\n",ans);
        return 0;
    }
    for (i=1; i<=n; i++)
    {
        int nr=0;
        for (j=0; j<v[i].size(); j++)
        {
            x=v[i][j];
            if (a[x]==maxim)
                nr++;
        }
        if (a[i]==maxim)
            nr++;
        if (nr==cnt)
        {
            printf("%d\n",maxim+1);
            return 0;
        }
    }
    printf("%d\n",maxim+2);
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
bool vis[300001];
int auxAdj[300001];
vector <vector<int> > adjList(300001);

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() >= adjList[b].size();
}

int dfs(int node,int parent) {
    ans = max(ans,arr[node]);
    for(int i = 0;i<adjList[node].size();i++) {
        int ch = adjList[node][i];
        if(ch != parent) {
            arr[ch] += i +1;
            dfs(ch,node);
        }
    }
}

void bfs(int node) {
    queue <int> q;
    q.push(node);
    while(!q.empty()) {
        int top = q.front();
        vis[top] = true;
        q.pop();
        for(int i = 0;i<adjList[top].size();i++) {
            int ch = adjList[top][i];
            if(auxAdj[ch])
                arr[top]+= auxAdj[ch];
            auxAdj[ch]++;
            if(!vis[ch]) {
                q.push(ch);
                arr[ch]++;
            }
        }
        ans = max(ans,arr[top]);
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    dfs(maxi[0],-1);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int ans = maxii+2;
    int m,mPlusOne,mPlusTwo;
    for(int i = 0;i<maxi.size();i++) {
        m = maxi.size();
        mPlusOne = 0;
        int node = maxi[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                mPlusOne++;
        }
        mPlusTwo = maxi.size()-1-mPlusOne;
        if(mPlusTwo <= 0)
            if(mPlusOne)
                ans = min(ans,maxii+1);
            else
                ans = maxii;
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector<int> secondMax;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++)
        scanf("%d",&arr[i]),maxii = max(maxii,arr[i]);
    for(int i = 1;i<=n;i++)
        if(arr[i] == maxii)
            maxi.push_back(i);
        else if(arr[i] == maxii-1)
            secondMax.push_back(i);
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int ans = maxii+2;
    int m,mPlusOne,secondPlusOne,mPlusTwo;
    for(int i = 0;i<maxi.size();i++) {
        mPlusOne = 0,secondPlusOne = 0;
        int node = maxi[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                mPlusOne++;
            if(arr[ch] == maxii-1)
                secondPlusOne++;
        }
        mPlusTwo = maxi.size()-1-mPlusOne;
        if(mPlusTwo <= 0)
            if(mPlusOne || secondMax.size() - secondPlusOne > 0)
                ans = min(ans,maxii+1);
            else
                ans = maxii;
    }
    for(int i = 0;i<secondMax.size();i++) {
        m=0;
        int node = secondMax[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                m++;
        }
        if(m == maxi.size())
            ans = min(ans,maxii+1);
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
bool vis[300001];
int auxAdj[300001];
vector <vector<int> > adjList(300001);

int best[300001];

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() >= adjList[b].size();
}

int dfs(int node,int parent,int old) {
    ans = max(ans,arr[node]);
    for(int i = 0;i<adjList[node].size();i++) {
        int ch = adjList[node][i];
        if(ch != parent) {
            arr[ch] += 1 + old;
            dfs(ch,node,1);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    dfs(maxi[0],-1,0);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
vector <vector<int> > adjList(300001);

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() <= adjList[b].size();
}

void dfs(int node,int parent,int old) {
    ans = max(ans,arr[node]);
    for(int i = 0;i<adjList[node].size();i++) {
        int ch = adjList[node][i];
        arr[ch] += 1 + old;
        if(ch != parent) {
            dfs(ch,node,1);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    dfs(maxi[0],-1,0);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector<int> secondMax;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    int secondMaxi = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(maxii == -2E9)
            maxii = arr[i];
        else if (arr[i] > maxii) {
            secondMaxi = maxii;
            maxii = arr[i];
        } else if (arr[i] != maxii && arr[i] > secondMaxi) {
            secondMaxi = arr[i];
        }
    }
    for(int i = 1;i<=n;i++)
        if(arr[i] == maxii)
            maxi.push_back(i);
        else if(arr[i] == secondMaxi)
            secondMax.push_back(i);
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int ans = maxii+2;
    int m,mPlusOne,secondPlusOne,mPlusTwo;
    for(int i = 0;i<maxi.size();i++) {
        mPlusOne = 0,secondPlusOne = 0;
        int node = maxi[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                mPlusOne++;
            if(secondMaxi == maxii -1 && arr[ch] == secondMaxi)
                secondPlusOne++;
        }
        mPlusTwo = maxi.size()-1-mPlusOne;
        if(mPlusTwo <= 0)
            if(mPlusOne || secondMax.size() - secondPlusOne > 0)
                ans = min(ans,maxii+1);
            else
                ans = maxii;
    }
    for(int i = 0;i<secondMax.size();i++) {
        m=0;
        int node = secondMax[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                m++;
        }
        if(m == maxi.size())
            ans = min(ans,maxii+1);
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
bool vis[300001];
int auxAdj[300001];
vector <vector<int> > adjList(300001);

int best[300001];

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() >= adjList[b].size();
}

int dfs(int node,int parent) {
    ans = max(ans,arr[node]);
    for(int i = 0;i<adjList[node].size();i++) {
        int ch = adjList[node][i];
        if(ch != parent) {
            arr[ch] += 1;
            dfs(ch,node);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    dfs(maxi[0],-1);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector<int> secondMax;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    int secondMaxi = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(maxii == -2E9)
            maxii = arr[i];
        else if (arr[i] > maxii) {
            secondMaxi = maxii;
            maxii = arr[i];
        } else if (arr[i] != maxii && arr[i] > secondMaxi) {
            secondMaxi = arr[i];
        }
    }
    for(int i = 1;i<=n;i++)
        if(arr[i] == maxii)
            maxi.push_back(i);
        else if(arr[i] == secondMaxi)
            secondMax.push_back(i);
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int ans = maxii+2;
    int m,mPlusOne,secondPlusOne,mPlusTwo;
    for(int i = 0;i<maxi.size();i++) {
        mPlusOne = 0,secondPlusOne = 0;
        int node = maxi[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                mPlusOne++;
            if(secondMaxi == maxii -1 && arr[ch] == secondMaxi)
                secondPlusOne++;
        }
        mPlusTwo = maxi.size()-1-mPlusOne;
        if(mPlusTwo <= 0)
            if(mPlusOne ||( (secondMaxi == maxii-1)&& ( secondMax.size() - secondPlusOne > 0) ) )
                ans = min(ans,maxii+1);
            else
                ans = maxii;
    }
    for(int i = 0;i<secondMax.size();i++) {
        m=0;
        int node = secondMax[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                m++;
        }
        if(m == maxi.size())
            ans = min(ans,maxii+1);
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
vector <vector<int> > adjList(300001);

bool cmp(int a,int b) {
    return arr[a] >= arr[b];
}

void dfs(int node,int parent,int old) {
    ans = max(ans,arr[node]);
    for(int i = 0;i<adjList[node].size();i++) {
        int ch = adjList[node][i];
        arr[ch] += 1 + old;
        if(ch != parent) {
            dfs(ch,node,1);
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    dfs(maxi[0],-1,0);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
bool vis[300001];
int auxAdj[300001];
vector <vector<int> > adjList(300001);

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() <= adjList[b].size();
}

void bfs(int node) {
    queue <int> q;
    q.push(node);
    while(!q.empty()) {
        int top = q.front();
        vis[top] = true;
        q.pop();
        for(int i = 0;i<adjList[top].size();i++) {
            int ch = adjList[top][i];
            if(auxAdj[ch])
                arr[top]+= auxAdj[ch];
            auxAdj[ch]++;
            if(!vis[ch]) {
                q.push(ch);
                arr[ch]++;
            }
        }
        ans = max(ans,arr[top]);
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    bfs(maxi[0]);
    cout<<ans;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++)
        scanf("%d",&arr[i]),maxii = max(maxii,arr[i]);
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int cntM=0,cntMM =0;
    for(int i = 1;i<=n;i++)
        if(arr[i] == maxii)
            cntM++;
        else if (arr[i] == maxii-1)
            cntMM++;
    int ans = maxii+2;
    int tempM,tempMM;
    for(int i = 1;i<=n;i++) {
        priority_queue<int> pq;
        tempM = tempMM = 0;
        if(arr[i] == maxii)
            tempM++;
        else if(arr[i] == maxii-1)
            tempMM++;
        pq.push(arr[i]);
        for(int j = 0;j<adjList[i].size();j++) {
            int ch = adjList[i][j];
            if(arr[ch] == maxii)
                tempM++;
            else if (arr[ch] == maxii-1)
                tempMM++;
            pq.push(arr[ch]+1);
        }
        if(tempM == cntM)
            if(tempMM < cntMM)
                ans = min(ans,maxii+1);
            else
                ans = min(ans,pq.top());
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
vector<int> maxi;
vector<int> secondMax;
vector <vector<int> > adjList(300001);

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++)
        scanf("%d",&arr[i]),maxii = max(maxii,arr[i]);
    for(int i = 1;i<=n;i++)
        if(arr[i] == maxii)
            maxi.push_back(i);
        else if(arr[i] == maxii-1)
            secondMax.push_back(i);
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    int ans = maxii+2;
    int m,mPlusOne,secondPlusOne,mPlusTwo;
    for(int i = 0;i<maxi.size();i++) {
        mPlusOne = 0,secondPlusOne = 0;
        int node = maxi[i];
        for(int j = 0;j<adjList[node].size();j++) {
            int ch = adjList[node][j];
            if(arr[ch] == maxii)
                mPlusOne++;
            if(arr[ch] == maxii-1)
                secondPlusOne++;
        }
        mPlusTwo = maxi.size()-1-mPlusOne;
        if(mPlusTwo <= 0)
            if(mPlusOne || secondMax.size() - secondPlusOne > 0)
                ans = min(ans,maxii+1);
            else
                ans = maxii;
    }
    printf("%d",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int arr[300001];
int ans;
vector <int> maxi;
bool vis[300001];
vector <vector<int> > adjList(300001);

bool cmp(int a,int b) {
    if(arr[a] > arr[b])
        return true;
    if(arr[a] < arr[b])
        return false;
    return adjList[a].size() <= adjList[b].size();
}

void bfs(int node) {
    queue <int> q;
    q.push(node);
    while(!q.empty()) {
        int top = q.front();
        vis[top] = true;
        q.pop();
        ans = max(ans,arr[top]);
        for(int i = 0;i<adjList[top].size();i++) {
            int ch = adjList[top][i];
            if(!vis[ch]) {
                q.push(ch);
                if(top == node)
                    arr[ch]++;
                else
                    arr[ch]+=2;
            }
        }
    }
}

int main()
{
    int n;
    scanf("%d",&n);
    int maxii = -2E9;
    for(int i = 1;i<=n;i++) {
        scanf("%d",&arr[i]);
        if(arr[i] > maxii) {
            maxi.clear();
            maxi.push_back(i);
            maxii = arr[i];
        } else if (arr[i] == maxii) {
            maxi.push_back(i);
        }
    }
    for(int i = 0;i<n-1;i++) {
        int x,y;
        scanf("%d %d",&x,&y);
        adjList[x].push_back(y);
        adjList[y].push_back(x);
    }
    for(int i = 1;i<=n;i++)
        sort(adjList[i].begin(),adjList[i].end(),cmp);
    ans = maxii;
    sort(maxi.begin(),maxi.end(),cmp);
    bfs(maxi[0]);
    cout<<ans;
    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + MAXN;

int ans;
int n, m, mx;
int arr[MAXN];
bool vis[MAXN];

vi graf[MAXN];
set<int> in_rek;
set<pii, greater<pii> > S;

void load() {
    mx = - MAXA;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        if (arr[i] > mx)
            mx = arr[i], m = i;
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

void solve() {
    ans = -MAXA;
    S.emplace(mx, m);
    for (int i = 0; i < n; ++i) {
        int id = S.begin() -> Y;
        int w = S.begin() -> X;
        S.erase(S.begin());
        in_rek.clear();

        if (vis[id])
            continue;

        ans = max(ans, w);
        in_rek.insert(id);
        vis[id] = true;

        for (auto it: graf[id])
            if (!vis[it]) {
                in_rek.insert(it);
                ++arr[it];
            }

        for (auto a: graf[id])
            if (!vis[a]) {
                for (auto b: graf[a])
                    if (!vis[b] && !in_rek.count(b)) {
                        in_rek.insert(b);
                        ++arr[b];
                    }
            }

        for (auto it: in_rek)
            if (it != id)
                S.emplace(arr[it], it);
    }

    printf("%d", ans);
}

int main() {

    load();
    solve();

    return 0;
}


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

#define all(x) x.begin(), x.end()
#define eb emplace_back
#define pb push_back
#define Y second
#define X first

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + 11;

typedef vector<int> vi;

int n, ans;
int arr[MAXN];
vi graf[MAXN];
multiset<int> S;
set<int> vis;

void load() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        arr[i] += 2;

        S.insert(arr[i]);
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

void update(int id, int dif) {
    S.erase(S.lower_bound(arr[id]));
    S.insert(arr[id] - dif);
    vis.insert(id);
}

void revert(int cur) {
    ans = min(ans, *S.rbegin());
    for (int id = *vis.begin(); !vis.empty(); id = *vis.begin()) {
        S.erase(S.lower_bound(arr[id] - (id == cur ? 2 : 1)));
        vis.erase(vis.begin());
        S.insert(arr[id]);
    }
}

void solve() {
    ans = MAXA;
    for (int i = 1; i <= n; ++i) {

        update(i, 2);
        for (auto it: graf[i])
            if (!vis.count(it))
                update(it, 1);

        revert(i);
    }

    printf("%d\n", ans);
}

int main() {

    load();
    solve();

    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + MAXN;

int ans;
int n, m, mx;
int arr[MAXN];
bool vis[MAXN];

vi graf[MAXN];
set<int> in_rek;
set<pii, greater<pii> > S;

void load() {
    mx = -MAXA;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        if (arr[i] > mx)
            mx = arr[i], m = i;
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

void solve() {
    ans = -MAXA;
    S.emplace(mx, m);
    while(!S.empty()) {
        int id = S.begin() -> Y;
        int w = S.begin() -> X;
        S.erase(S.begin());
        in_rek.clear();

        if (vis[id])
            continue;

        ans = max(ans, w);
        in_rek.insert(id);
        vis[id] = true;

        for (auto it: graf[id])
            if (!vis[it]) {
                in_rek.insert(it);
                ++arr[it];
            }

        for (auto a: graf[id])
            if (!vis[a]) {
                for (auto b: graf[a])
                    if (!vis[b] && !in_rek.count(b)) {
                        in_rek.insert(b);
                        ++arr[b];
                    }
            }

        for (auto it: in_rek)
            if (it != id)
                S.emplace(arr[it], it);
    }

    printf("%d", ans);
}

int main() {

    load();
    solve();

    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + MAXN;

int n, m, mx;
int arr[MAXN];
bool vis[MAXN];
int added[MAXN];
set<int> link[MAXN];
vi graf[MAXN];

void load() {
    mx = - MAXA;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        if (arr[i] > mx)
            mx = arr[i], m = i;
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
        link[u].insert(v), link[v].insert(u);
    }
}

bool check(int val) {
    set<pii, greater<pii> > S;
    S.insert({mx, m});

    memset(vis, 0, sizeof vis);
    memset(added, 0, sizeof added);

    for (int i = 0; i < n; ++i) {
        int id = S.begin() -> Y;
        int w = S.begin() -> X;
        S.erase(S.begin());

        vis[id] = true;
        if (arr[id] + added[id] > val)
            return false;

        for (auto it: graf[id])
            if (!vis[it]) {
                auto found = S.find({arr[it] + added[it], it});
                if (found != S.end())
                    S.erase(found);

                S.insert({++added[it] + arr[it], it});

                for (auto in_it: graf[it]) {
                    if (in_it == it || vis[in_it] || link[id].count(in_it))
                        continue;

                    auto found = S.find({arr[in_it] + added[in_it], in_it});
                    if (found != S.end()) {
                        S.insert({++added[in_it] + arr[in_it], in_it});
                        S.erase(found);
                    } else
                        ++added[in_it];
                }
            }
    }

    return true;
}

int solve() {
    int lo = -MAXA, hi = MAXA, ret = 0;
    while (lo < hi) {
        int mid = (lo + hi + 1) / 2;
        if (check(mid))
            ret = mid, hi = mid - 1;
        else
            lo = mid;
    }

    return ret;
}

int main() {

    load();
    printf("%d\n", solve());

    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + MAXN;

int n, m, mx;
int arr[MAXN];
int added[MAXN];
bool vis[MAXN];
vi graf[MAXN];

void load() {
    mx = - MAXA;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        if (arr[i] > mx)
            mx = arr[i], m = i;
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

bool check(int val) {
    set<pii, greater<pii> > S;
    S.insert({mx, m});

    memset(vis, 0, sizeof vis);
    memset(added, 0, sizeof added);

    for (int i = 0; i < n; ++i) {
        int id = S.begin() -> Y;
        int w = S.begin() -> X;
        S.erase(S.begin());

        vis[id] = true;
        if (arr[id] + added[id] > val)
            return false;

        for (auto it: graf[id])
            if (!vis[it]) {
                auto found = S.find({arr[it] + added[it], it});
                if (found != S.end())
                    S.erase(found);

                S.insert({++added[it] + arr[it], it});
            }
    }

    return true;
}

int solve() {
    int lo = -MAXA, hi = MAXA, ret = 0;
    while (lo < hi) {
        int mid = (lo + hi + 1) / 2;
        if (check(mid))
            ret = mid, hi = mid - 1;
        else
            lo = mid;
    }

    return ret;
}

int main() {

    load();
    printf("%d\n", solve());

    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 1e6 + 11;

int n, m, k, cur, fin, a, b;
bool hole[MAXN];

int main() {

    ios::sync_with_stdio(false);
    // cin.tie(0), cout.tie(0);

    cin >> n >> m >> k;
    for (int i = 1; i <= m; ++i) {
        cin >> a;
        hole[a] = true;
    }

    cur = 1;
    for (int i = 1; i <= k; ++i) {
        cin >> a >> b;
        if (b == cur)
            swap(a, b);

        if (a == cur && hole[a] && !fin)
            fin = cur;
        else if (a == cur && !hole[a])
            cur = b;
    }

    if (!fin)
        fin = cur;

    cout << fin << endl;

    return 0;
}


#include <unordered_map>
#include <functional>
#include <algorithm>
#include <iterator>
#include <iostream>
#include <cstring>
#include <utility>
#include <cstdio>
#include <vector>
#include <string>
#include <limits>
#include <deque>
#include <cmath>
#include <stack>
#include <queue>
#include <list>
#include <map>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define sc(x) scanf("%d", &x)
#define bp __builtin_popcount
#define double long double
#define eb emplace_back
#define pb push_back
#define mp make_pair
#define gcd __gcd
#define endl '\n'

#define Y second
#define X first

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;

const int INF = 1e9 + 11;
const int MOD = 1e9 + 7;
const ll LLINF = numeric_limits<ll>::max() / 3;

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + MAXN;

int n, m, mx;
int arr[MAXN];
int added[MAXN];
bool vis[MAXN];
vi graf[MAXN];

void load() {
    mx = - MAXA;
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        if (arr[i] > mx)
            mx = arr[i], m = i;
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

bool check(int val) {
    set<pii, greater<pii> > S;
    S.insert({mx, m});

    memset(vis, 0, sizeof vis);
    memset(added, 0, sizeof added);

    for (int i = 0; i < n; ++i) {
        int id = S.begin() -> Y;
        int w = S.begin() -> X;
        S.erase(S.begin());

        vis[id] = true;
        if (arr[id] + added[id] > val)
            return false;

        for (auto it: graf[id])
            if (!vis[it]) {
                auto found = S.find({arr[it] + added[it], it});
                if (found != S.end())
                    S.erase(found);

                S.insert({++added[it] + arr[it], it});

                for (auto in_it: graf[it]) {
                    if (in_it == it || vis[in_it])
                        continue;

                    auto found = S.find({arr[in_it] + added[in_it], in_it});
                    if (found != S.end())
                        S.erase(found);

                    S.insert({++added[in_it] + arr[in_it], it});
                }
            }
    }

    return true;
}

int solve() {
    int lo = -MAXA, hi = MAXA, ret = 0;
    while (lo < hi) {
        int mid = (lo + hi + 1) / 2;
        if (check(mid))
            ret = mid, hi = mid - 1;
        else
            lo = mid;
    }

    return ret;
}

int main() {

    load();
    printf("%d\n", solve());

    return 0;
}


#include <algorithm>
#include <vector>
#include <cstdio>
#include <set>
using namespace std;

#define all(x) x.begin(), x.end()
#define eb emplace_back
#define pb push_back
#define Y second
#define X first

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + 11;

typedef vector<int> vi;

int n, ans;
int arr[MAXN];
vi graf[MAXN];
multiset<int> S;
set<int> vis;

void load() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        arr[i] += 2;

        S.insert(arr[i]);
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

inline void update(int in, int out) {
    S.erase(S.find(out));
    S.insert(in);
}

void solve() {
    ans = MAXA;
    for (int i = 1; i <= n; ++i) {
        update(arr[i] - 2, arr[i]);
        for (auto &it: graf[i])
            update(arr[it] - 1, arr[it]);

        ans = min(ans, *S.rbegin());

        for (auto &it: graf[i])
            update(arr[it], arr[it] - 1);
        update(arr[i], arr[i] - 2);
    }

    printf("%d\n", ans);
}

int main() {

    load();
    solve();

    return 0;
}


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

#define all(x) x.begin(), x.end()
#define eb emplace_back
#define pb push_back
#define Y second
#define X first

const int MAXN = 3e5 + 11;
const int MAXA = 1e9 + 11;

typedef vector<int> vi;

int n, ans;
int arr[MAXN];
int changed[MAXN];
multiset<int> S;
vi graf[MAXN];
set<int> vis;

void load() {
    scanf("%d", &n);
    for (int i = 1; i <= n; ++i) {
        scanf("%d", arr + i);
        arr[i] += 2;

        S.insert(arr[i]);
    }

    int u, v;
    for (int i = 1; i < n; ++i) {
        scanf("%d%d", &u, &v);
        graf[u].pb(v), graf[v].pb(u);
    }
}

void update(int id, int dif) {
    if (dif) {
        S.erase(S.lower_bound(arr[id]));
        S.insert(arr[id] - dif);
        changed[id] = dif;
    }

    vis.insert(id);
}

void revert() {
    ans = min(ans, *S.rbegin());
    for (int id = *vis.begin(); !vis.empty(); id = *vis.begin()) {
        if (changed[id]) {
            S.erase(S.lower_bound(arr[id] - changed[id]));
            S.insert(arr[id]);
        }

        vis.erase(vis.begin());
    }
}

void solve() {
    ans = MAXA;
    for (int i = 1; i <= n; ++i) {

        update(i, 2);
        for (auto it: graf[i])
            if (!vis.count(it))
                update(it, 1);

        for (auto a: graf[i])
            if (a != i)
                for (auto b: graf[a])
                    if (!vis.count(b))
                        update(b, 0);

        revert();
    }

    printf("%d\n", ans);
}

int main() {

    load();
    solve();

    return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, ans = (int) INF + 2, max_val = (int) - INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		max_val = max(max_val, arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	memset(visited, 0, sizeof visited);
	loop(i,0,n) {
		if( arr[i] - 2 < max_val || visited[i] ) continue;
		mx = arr[i] - 2; visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				visited[u] = true;
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						visited[v] = true;
						mx = max(mx, arr[v]);
					}
				}
			}
		}
		// printf("mx = %d\n", mx);
		ans = min(ans, mx);
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, idx = 0, ans = (int) -INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		if( arr[i] > mx ) {
			mx = arr[i];
			idx = i;
		}
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	memset(visited, 0, sizeof visited);
	priority_queue<ii> pq;
	pq.push(ii(arr[idx], idx)); visited[idx] = true;
	while(!pq.empty()) {
		ii p = pq.top(); pq.pop();
		ans = max(ans, p.first);
		idx = p.second;
		loop(i,0,Adj[idx].size()) {
			int v = Adj[idx][i];
			if( !visited[v] ) {
				visited[v] = true;
				arr[v]++;
				pq.push(ii(arr[v], v));
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, ans = (int) INF, max_val = (int) - INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		max_val = max(max_val, arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	loop(i,0,n) {
		memset(visited, 0, sizeof visited);
		mx = max(max_val, arr[i] - 2); visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				visited[u] = true;
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						visited[v] = true;
						mx = max(mx, arr[v]);
					}
				}
			}
		}
		// printf("mx = %d\n", mx);
		ans = min(ans, mx);
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, ans = (int) INF + 2, max_val = (int) - INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		max_val = max(max_val, arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	loop(i,0,n) {
		if( arr[i] - 2 < max_val ) continue;
		memset(visited, 0, sizeof visited);
		mx = arr[i] - 2; visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				visited[u] = true;
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						visited[v] = true;
						mx = max(mx, arr[v]);
					}
				}
			}
		}
		// printf("mx = %d\n", mx);
		ans = min(ans, mx);
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, ans = (int) INF + 2, max_val = (int) - INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		max_val = max(max_val, arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	loop(i,0,n) {
		if( arr[i] - 2 < max_val ) continue;
		memset(visited, 0, sizeof visited);
		mx = arr[i] - 2; visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				visited[u] = true;
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						visited[v] = true;
						mx = max(mx, arr[v]);
					}
				}
			}
		}
		printf("mx = %d\n", mx);
		ans = min(ans, mx);
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	loop(i,0,n) {
		memset(visited, 0, sizeof visited);
		mx = max(mx, arr[i] - 2); visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						mx = max(mx, arr[v]);
					}
				}
			}
		}
	}
	printf("%d\n", mx);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 2e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], ans = (int) INF;
	vi Adj[300010];
	sc(n);
	multiset<int> Set;
	loop(i,0,n) {
		sc(arr[i]);
		Set.insert(arr[i]);
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	loop(i,0,n) {
		int mx = arr[i];
		Set.erase(Set.find(arr[i]));
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			mx = max(mx, arr[u] + 1);
			Set.erase(Set.find(arr[u]));
			loop(k,0,Adj[u].size()) {
				int v = Adj[u][k];
				if( v == i ) continue;
				mx = max(mx, arr[v] + 2);
				Set.erase(Set.find(arr[v]));
			}
		}
		if( !Set.empty() )
			mx = max(mx, (*Set.rbegin()) + 2);
		ans = min(ans, mx);

		Set.insert(arr[i]);
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			Set.insert(arr[u]);
			loop(k,0,Adj[u].size()) {
				int v = Adj[u][k];
				if( v == i ) continue;
				Set.insert(arr[v]);
			}
		}
		// printf("%d %d\n", mx, Set.size());
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF, idx = 0, ans = (int) -INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		if( arr[i] > mx ) {
			mx = arr[i];
			idx = i;
		}
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	memset(visited, 0, sizeof visited);
	priority_queue<ii> pq;
	pq.push(ii(arr[idx], idx)); visited[idx] = true;
	while(!pq.empty()) {
		ii p = pq.top(); pq.pop();
		ans = max(ans, p.first);
		idx = p.second;
		loop(i,0,Adj[idx].size()) {
			int v = Adj[idx][i];
			if( !visited[v] ) {
				visited[v] = true;
				arr[v]++;
				loop(j,0,Adj[v].size()) {
					int u = Adj[v][j];
					if( !visited[u] ) arr[u]++;
				}
				pq.push(ii(arr[v], v));
			}
		}
	}
	printf("%d\n", ans);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 1e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], mx = (int) -INF;
	vi Adj[300010];
	bool visited[300010];
	sc(n);
	loop(i,0,n) {
		sc(arr[i]);
		arr[i] += 2;
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	// printf("%d %d\n", idx, arr[idx]);
	loop(i,0,n) {
		memset(visited, 0, sizeof visited);
		mx = arr[i] - 2; visited[i] = true;
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			if( !visited[u] ) {
				mx = max(mx, arr[u] - 1);
				loop(k,0,Adj[u].size()) {
					int v = Adj[u][k];
					if( !visited[v] ) {
						mx = max(mx, arr[v]);
					}
				}
			}
		}
	}
	printf("%d\n", mx);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <string>
using namespace std;
typedef long long int ll;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> ii;
typedef vector<ii> vii;
#define sc(x) scanf("%d", &x)
#define scl(x) scanf("%lld", &x)
#define loop(i,s,e) for(int i=s ; i<e ; i++)
#define rep(i,s,e) for(int i=s ; i>=e ; i--)
#define INF 2e9
#define f first
#define s second
#define EPS 1e-7
#define Rd freopen("in.txt", "r", stdin)
#define Wr freopen("out.txt", "w", stdout)
#define MOD 1000000007
#define PS push_back

int main() {
	// Rd;
	int n, arr[300010], ans = (int) INF;
	vi Adj[300010];
	sc(n);
	multiset<int> Set;
	loop(i,0,n) {
		sc(arr[i]);
		Set.insert(arr[i]);
	}
	loop(i,0,n-1) {
		int u, v;
		sc(u); sc(v); u--; v--;
		Adj[u].PS(v);
		Adj[v].PS(u);
	}
	loop(i,0,n) {
		int mx = arr[i];
		Set.erase(Set.find(arr[i]));
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			mx = max(mx, arr[u] + 1);
			Set.erase(Set.find(arr[u]));
		}
		if( !Set.empty() )
			mx = max(mx, (*Set.rbegin()) + 2);
		ans = min(ans, mx);

		Set.insert(arr[i]);
		loop(j,0,Adj[i].size()) {
			int u = Adj[i][j];
			Set.insert(arr[u]);
		}
		// printf("%d %d\n", mx, Set.size());
	}
	printf("%d\n", ans);
	return 0;
}


import java.util.*;
import java.io.*;
import java.math.*;

public class Main
{
    public static void main(String omkar[]) throws Exception
    {
        BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(infile.readLine());
        int T = Integer.parseInt(st.nextToken());
        StringBuilder sb = new StringBuilder();
        while(T-->0)
        {
            st = new StringTokenizer(infile.readLine());
            int N = Integer.parseInt(st.nextToken());
            long K = Long.parseLong(st.nextToken())%2;
            if(K == 0)  K = 2;
            int[] arr = new int[N];
            st = new StringTokenizer(infile.readLine());
            for(int i=0; i < N; i++)
                arr[i] = Integer.parseInt(st.nextToken());
            for(int turns=0; turns < K; turns++)
            {
                int max = arr[0];
                for(int x: arr)
                    max = Math.max(max, x);
                for(int i=0; i < N; i++)
                    arr[i] = max-arr[i];
            }
            for(int i=0; i < N; i++)
            {
                sb.append(arr[i]);
                if(i+1 < N)
                    sb.append(" ");
            }
            sb.append("\n");
        }
        System.out.print(sb);
    }
}


import java.util.*;
import java.io.*;

//*****************   Agar firdaus bar roo-e zameen ast,Hameen ast-o hameen ast-o hameen ast.    *****************\\

public class Main{

    static int gcd(int a, int b)
    {
        if (b == 0)
            return a;
        return gcd(b, a % b);
    }

    public static void main(String[] args) throws Exception {

        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter pw = new PrintWriter(System.out);
        int t = Integer.parseInt(br.readLine());
        while(t-->0){
            String[] s = br.readLine().split(" ");
            int n = Integer.parseInt(s[0]);
            long k = Long.parseLong(s[1]);
            s = br.readLine().split(" ");
            int[] a = new int[n];
            int max = Integer.MIN_VALUE;
            for(int i=0;i<n;i++) {
                a[i]=Integer.parseInt(s[i]);
                max = Math.max(max,a[i]);
            }
            long count=1;
            int max1=Integer.MIN_VALUE;
            while(count<=k){
                for(int i=0;i<n;i++){
                    a[i]=max-a[i];
                    max1=Math.max(max1,a[i]);
                }
                if(max1==0) break;
                max=max1;
                count++;
            }
        for(int i=0;i<n;i++) pw.print(a[i]+ " ");
        pw.println();
        }
        pw.flush();
        pw.close();
    }
}


import java.util.*;
import java.io.*;
import java.math.*;

   public class ModelB
   {
      public static void main(String omkar[]) throws Exception
      {
         //query based
         BufferedReader infile = new BufferedReader(new InputStreamReader(System.in));
         StringTokenizer st = new StringTokenizer(infile.readLine());
         int T = Integer.parseInt(st.nextToken());
         StringBuilder sb = new StringBuilder();
         while(T-->0)
         {
            st = new StringTokenizer(infile.readLine());
            int N = Integer.parseInt(st.nextToken());
            long K = Long.parseLong(st.nextToken())%2;
            if(K == 0)  K = 2;
            int[] arr = new int[N];
            st = new StringTokenizer(infile.readLine());
            for(int i=0; i < N; i++)
               arr[i] = Integer.parseInt(st.nextToken());
            for(int turns=0; turns < K; turns++)
            {
               int max = arr[0];
               for(int x: arr)
                  max = Math.max(max, x);
               for(int i=0; i < N; i++)
                  arr[i] = max-arr[i];
            }
            for(int i=0; i < N; i++)
            {
               sb.append(arr[i]);
               if(i+1 < N)
                  sb.append(" ");
            }
            sb.append("\n");
         }
         System.out.print(sb);
      }
   }


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner in=new Scanner(System.in);
        int t=in.nextInt();
        for(int i=0;i<t;i++)
        {
            int n=in.nextInt();
            long k=in.nextLong();

            int a[]=new int[n];
            int max=0;
            for(int j=0;j<n;j++)
            {
                a[j]=in.nextInt();
                if(j>0)
                {
                    max=Math.max(max, a[j]);
                }
                else{
                    max=a[0];
                }
            }
            for(int j=0;j<k;j++)
            {
                for(int l=0;l<n;l++){
                    a[l]=max-a[l];
                }
                for(int l=0;l<n;l++){
                    if(l>0)
                    {
                        max=Math.max(max, a[l]);
                    }
                    else{
                        max=a[0];
                    }
                }
            }
            for(int l=0;l<n;l++){
                System.out.print(a[l]+" ");
            }
            System.out.println();
        }
    }
}


import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner in=new Scanner(System.in);
        int t=in.nextInt();
        for(int i=0;i<t;i++)
        {
            int n=in.nextInt();
            int k=in.nextInt();

            int a[]=new int[n];
            int max=0;
            for(int j=0;j<n;j++)
            {
                a[j]=in.nextInt();
                if(j>0)
                {
                    max=Math.max(max, a[j]);
                }
                else{
                    max=a[0];
                }
            }
            for(int j=0;j<k;j++)
            {
                for(int l=0;l<n;l++){
                    a[l]=max-a[l];
                }
                for(int l=0;l<n;l++){
                    if(l>0)
                    {
                        max=Math.max(max, a[l]);
                    }
                    else{
                        max=a[0];
                    }
                }
            }
            for(int l=0;l<n;l++){
                System.out.print(a[l]+" ");
            }
            System.out.println();
        }
    }
}