#include <bits/stdc++.h>
using namespace std;
long double pi = 3.14159265358979323846;
vector<long long> al[500005];
long long vis[500005], color[500005], I[101][101];
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
bool isPrime(int n) {
  if (n <= 1) return false;
  if (n <= 3) return true;
  if (n % 2 == 0 || n % 3 == 0) return false;
  for (int i = 5; i * i <= n; i = i + 6)
    if (n % i == 0 || n % (i + 2) == 0) return false;
  return true;
}
long long bpow(long long n, long long po) {
  long long res = 1;
  while (po > 0) {
    if (po % 2) {
      res = (res * n) % 1000000007;
      po--;
    } else {
      n = (n * n) % 1000000007;
      po /= 2;
    }
  }
  return res;
}
void swap(long long *a, long long *b) {
  long long temp = *a;
  *a = *b;
  *b = temp;
}
long long fact(long long n) {
  if ((n == 0) || (n == 1))
    return 1;
  else
    return n * fact(n - 1);
}
long long modInverse(long long n, long long p) { return bpow(n, p - 2); }
long long fac[300001];
long long nCr(long long n, long long r) {
  if (r == 0) return 1;
  return (fac[n] * modInverse(fac[r], 1000000007) % 1000000007 *
          modInverse(fac[n - r], 1000000007) % 1000000007) %
         1000000007;
}
void mmul(long long A[][101], long long B[][101], long long dim) {
  long long res[dim][dim];
  for (long long i = 0; i < dim; i++)
    for (long long j = 0; j < dim; j++) {
      res[i][j] = 0;
      for (long long k = 0; k < dim; k++)
        res[i][j] = (res[i][j] + A[i][k] * B[k][j]) % 1000000007;
    }
  for (long long i = 0; i < dim; i++)
    for (long long j = 0; j < dim; j++) A[i][j] = res[i][j];
}
void mpow(long long A[][101], long long dim, long long po) {
  for (long long i = 0; i < dim; i++)
    for (long long j = 0; j < dim; j++) {
      if (i == j)
        I[i][j] = 1;
      else
        I[i][j] = 0;
    }
  while (po > 0) {
    if (po % 2 == 1) {
      mmul(I, A, dim);
      po--;
    } else {
      mmul(A, A, dim);
      po /= 2;
    }
  }
  for (long long i = 0; i < dim; i++)
    for (long long j = 0; j < dim; j++) A[i][j] = I[i][j];
}
long long n, q, tree[400004][2];
string s, f;
void build(long long si, long long ss, long long se) {
  if (ss == se) {
    tree[si][f[ss - 1] - '0'] = 1;
    tree[si][1 - f[ss - 1] + '0'] = 0;
    return;
  }
  long long sm = (ss + se) / 2;
  build(2 * si, ss, sm);
  build(2 * si + 1, sm + 1, se);
  tree[si][0] = tree[2 * si][0] + tree[2 * si + 1][0];
  tree[si][1] = tree[2 * si][1] + tree[2 * si + 1][1];
  return;
}
void update(long long si, long long ss, long long se, long long us,
            long long ue, long long val) {
  if (ss >= us && se <= ue) {
    tree[si][val] = se - ss + 1;
    tree[si][1 - val] = 0;
    return;
  }
  if (se < us || ss > ue) return;
  long long sm = (ss + se) / 2;
  update(2 * si, ss, sm, us, ue, val);
  update(2 * si + 1, sm + 1, se, us, ue, val);
  tree[si][0] = tree[2 * si][0] + tree[2 * si + 1][0];
  tree[si][1] = tree[2 * si][1] + tree[2 * si + 1][1];
  return;
}
long long query(long long si, long long ss, long long se, long long qs,
                long long qe) {
  if (se < qs || ss > qe) return 0;
  if (tree[si][0] == se - ss + 1) return min(se, qe) - max(ss, qs) + 1;
  if (tree[si][0] == 0) return 0;
  if (ss >= qs && se <= qe) return tree[si][0];
  long long sm = (ss + se) / 2;
  return query(2 * si, ss, sm, qs, qe) + query(2 * si + 1, sm + 1, se, qs, qe);
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long testcases = 1;
  while (testcases--) {
    long long n;
    cin >> n;
    long long a[n];
    for (long long i = 0; i < n; i++) cin >> a[i];
    map<long long, long long> mp;
    for (long long i = 0; i < n; i++) {
      mp[a[i]]++;
    }
    long long maxi = -1e17;
    for (long long i = 0; i < n; i++) maxi = max(maxi, a[i]);
    long long e, f;
    for (long long i = 0; i < n - 1; i++) {
      cin >> e >> f;
      al[e].push_back(f);
      al[f].push_back(e);
    }
    long long fans = 1e18;
    for (long long i = 0; i < n; i++) {
      long long ans = maxi;
      if (a[i] == maxi) {
        long long cc = 0, c = 0;
        for (long long j = 0; j < al[i + 1].size(); j++) {
          if (a[al[i + 1][j] - 1] == maxi) c++;
          if (a[al[i + 1][j] - 1] == maxi - 1) cc++;
        }
        if (c > 0) ans = max(ans, maxi + 1);
        if (mp[maxi] - 1 - c > 0) ans = max(ans, maxi + 2);
        if (mp[maxi - 1] - cc > 0) ans = max(ans, maxi + 1);
        fans = min(fans, ans);
      } else if (a[i] == maxi - 1) {
        long long cc = 0, c = 0;
        for (long long j = 0; j < al[i + 1].size(); j++) {
          if (a[al[i + 1][j] - 1] == maxi) c++;
          if (a[al[i + 1][j] - 1] == maxi - 1) cc++;
        }
        if (c > 0) ans = max(ans, maxi + 1);
        if (mp[maxi] - c > 0) ans = max(ans, maxi + 2);
        if (mp[maxi - 1] - 1 - cc > 0) ans = max(ans, maxi + 1);
        fans = min(ans, fans);
      } else {
        long long cc = 0, c = 0;
        for (long long j = 0; j < al[i + 1].size(); j++) {
          if (a[al[i + 1][j] - 1] == maxi) c++;
          if (a[al[i + 1][j] - 1] == maxi - 1) cc++;
        }
        if (c > 0) ans = max(ans, maxi + 1);
        if (mp[maxi] - c > 0) ans = max(ans, maxi + 2);
        if (mp[maxi - 1] - cc > 0) ans = max(ans, maxi + 1);
        fans = min(ans, fans);
      }
    }
    cout << fans;
  }
}
