#include <bits/stdc++.h>
using namespace std;
void read(vector<long long>& c, long long size) {
  for (int i = 0; i < size; i++) {
    int q;
    scanf("%d", &q);
    c.push_back(q);
  }
}
void read(vector<pair<long long, long long> >& c, long long size) {
  for (int i = 0; i < size; i++) {
    int q;
    int r;
    scanf("%d", &q);
    scanf("%d", &r);
    c.push_back(make_pair(q, r));
  }
}
void print(vector<long long>& coeffs) {
  for (int i = 0; i < coeffs.size(); i++) {
    cout << coeffs[i] << " ";
  }
  cout << endl;
}
long long op(long long a, long long b, int& l) {
  if (l % 2 == 0) {
    l++;
    return a + b;
  }
  if (l % 2 == 1) {
    l++;
    return a - b;
  }
}
long long power(long long a, long long b) {
  if (b == 0) {
    return 1;
  } else {
    long long q = power(a, b / 2);
    long long r = (q * q) % 1000000007;
    if (b % 2) {
      return (r * a) % 1000000007;
    } else {
      return r;
    }
  }
}
long long inv(long long a) { return power(a, 1000000007 - 2); }
bool input() {
  string q;
  cin >> q;
  return (q == "TAK");
}
int print(long long q, long long l, long long r) {
  cout << q << " " << l << " " << r << endl;
  fflush(stdout);
  if (q == 1) {
    return input();
  }
  return -1;
}
long long bs(long long l, long long r) {
  while (l < r) {
    long long mid = (l + r) / 2;
    int q = print(1, mid, mid + 1);
    if (q == 1) {
      r = mid;
    } else {
      l = mid + 1;
    }
  }
  return l;
}
long long gcd(long long a, long long b) {
  if (a < b) {
    return gcd(b, a);
  }
  if (b == 0) {
    return a;
  }
  return gcd(b, a % b);
}
vector<vector<long long> > adj(300007);
vector<long long> a(300007);
void dfs(long long node, long long parent, long long& ans, long long max1,
         long long max1o, long long max2o) {
  long long i;
  long long max1_oc = 0;
  long long max2_oc = 0;
  if (a[node] == max1) {
    max1_oc++;
  }
  if (a[node] == max1 - 1) {
    max2_oc++;
  }
  for (i = 0; i < adj[node].size(); i++) {
    long long index = adj[node][i];
    if (a[index] == max1) {
      max1_oc++;
    }
    if (a[index] == max1 - 1) {
      max2_oc++;
    }
    if (index != parent) {
      dfs(index, node, ans, max1, max1o, max2o);
    }
  }
  if (max1_oc == max1o) {
    if (max2_oc == max2o) {
      if (max1o == 1 && a[node] == max1) {
        ans = min(ans, max1);
      } else {
        ans = min(ans, max1 + 1);
      }
    } else {
      ans = min(ans, max1 + 1);
    }
  } else {
    ans = min(ans, max1 + 2);
  }
}
int main() {
  long long m, n, k;
  long long f;
  long long l, r;
  long long i, j;
  cin >> n;
  for (i = 1; i <= n; i++) {
    scanf("%lld", &a[i]);
  }
  long long max1 = INT_MIN;
  map<long long, long long> occurs;
  for (i = 1; i <= n; i++) {
    max1 = max(max1, a[i]);
    occurs[a[i]]++;
  }
  for (i = 0; i < n - 1; i++) {
    scanf("%lld", &l);
    scanf("%lld", &r);
    adj[l].push_back(r);
    adj[r].push_back(l);
  }
  long long ans = INT_MAX;
  dfs(1, 1, ans, max1, occurs[max1], occurs[max1 - 1]);
  cout << ans << endl;
}
