#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 10;
int n;
long long l, r;
int a[300010], t[300010];
vector<int> e[300010];
bool judge(long long x) {
  for (int i = 1; i <= n; i++) t[i] = a[i];
  int maxn = -inf;
  int c = -1;
  int cnt = 0;
  for (int i = 1; i <= n; i++) {
    if (a[i] > x) return false;
    t[i] += 2;
    if (t[i] > x) cnt++;
  }
  if (n == 1) return true;
  if (cnt == 0) return true;
  for (int i = 1; i <= n; i++) {
    int tmp = cnt;
    if (t[i] > x) tmp--;
    for (int j = 0; j < e[i].size(); j++) {
      int xx = e[i][j];
      if (xx == i) continue;
      if (t[xx] == x + 1) tmp--;
    }
    if (tmp == 0) return true;
  }
  return false;
}
long long binarysearch() {
  long long ans = l;
  while (l <= r) {
    long long mid = (l + r) / 2;
    if (judge(mid)) {
      ans = mid;
      r = mid - 1;
    } else
      l = mid + 1;
  }
  return ans;
}
int main(void) {
  int i, j;
  while (scanf("%d", &n) == 1) {
    for (i = 1; i <= n; i++) {
      scanf("%d", &a[i]);
      e[i].clear();
      l = min(l, (long long)a[i]);
      r = max(r, (long long)a[i]);
    }
    r += n;
    for (i = 1; i < n; i++) {
      int x, y;
      scanf("%d%d", &x, &y);
      e[x].push_back(y);
      e[y].push_back(x);
    }
    long long ans = binarysearch();
    cout << ans << endl;
  }
  return 0;
}
