#include <bits/stdc++.h>
using namespace std;
const int N = 300010;
const int M = 1000010;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
long long qpow(long long a, long long b) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % mod;
    a = a * a % mod;
    b /= 2;
  }
  return ans;
}
long long qpow(long long a, long long b, long long c) {
  long long ans = 1;
  while (b) {
    if (b & 1) ans = ans * a % c;
    a = a * a % c;
    b /= 2;
  }
  return ans;
}
int n, a[N], head[N], tot, ans = 1000000010;
struct EDGE {
  int to, nex;
} e[N * 2];
multiset<int, greater<int> > s;
void add(int u, int v) {
  e[tot].to = v;
  e[tot].nex = head[u];
  head[u] = tot++;
}
void dfs(int x, int f) {
  vector<int> v;
  v.push_back(a[x]);
  int maxx = -1000000010;
  for (int i = head[x]; i != -1; i = e[i].nex)
    if (e[i].to != f) {
      v.push_back(a[e[i].to]);
      maxx = max(maxx, a[e[i].to]);
    }
  if (x != 1) {
    v.push_back(a[f]);
    maxx = max(maxx, a[f]);
  }
  for (int i = 0; i < ((int)v.size()); i++) s.erase(s.find(v[i]));
  if (((int)s.size()))
    ans = min(ans, max(a[x], max(maxx + 1, (*s.begin()) + 2)));
  else
    ans = min(ans, max(a[x], maxx + 1));
  for (int i = 0; i < ((int)v.size()); i++) s.insert(v[i]);
  for (int i = head[x]; i != -1; i = e[i].nex)
    if (e[i].to != f) dfs(e[i].to, x);
}
int main() {
  memset(head, -1, sizeof(head));
  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 u, v;
    scanf("%d%d", &u, &v);
    add(u, v);
    add(v, u);
  }
  dfs(1, 0);
  printf("%d\n", ans);
}
