#include <bits/stdc++.h>
using namespace std;
const long long INF = 1e17L;
const int inf = 0x3f3f3f3f;
const int maxn = 3e5 + 5;
const int Mod = 1e9 + 7;
struct NODE {
  int v, id;
  friend bool operator<(NODE p, NODE q) { return p.v > q.v; }
} node[maxn];
struct E {
  int v, next;
} edge[maxn * 2];
int head[maxn], tot, a[maxn];
int n;
void init() {
  memset(head, -1, sizeof(head));
  tot = -1;
}
void addedge(int u, int v) {
  edge[++tot].v = v;
  edge[tot].next = head[u];
  head[u] = tot;
}
int dfs(int u, int fa, int h) {
  int ans = a[u] + h;
  for (int i = head[u]; i != -1; i = edge[i].next) {
    int v = edge[i].v;
    if (v == fa) continue;
    ans = max(ans, dfs(v, u, (h < 2) ? h + 1 : 2));
  }
  return ans;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &a[i]);
    node[i].v = a[i];
    node[i].id = i;
  }
  init();
  int u, v;
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &u, &v);
    addedge(u, v);
    addedge(v, u);
  }
  sort(node + 1, node + n + 1);
  int ans = inf;
  if (n == 1 || node[1].v > node[2].v) {
    ans = min(ans, dfs(node[1].id, 0, 0));
  } else {
    ans = min(ans, dfs(node[1].id, 0, 0));
    ans = min(ans, dfs(node[2].id, 0, 0));
    u = node[1].id, v = node[2].id;
    int t = -1, t1, t2;
    for (int i = head[u]; i != -1 && t == -1; i = edge[i].next) {
      t1 = edge[i].v;
      for (int j = head[t1]; j != -1; j = edge[j].next) {
        t2 = edge[j].v;
        if (t2 == v) {
          t = t1;
          break;
        }
      }
    }
    if (t != -1) ans = min(ans, dfs(t, 0, 0));
  }
  printf("%d\n", ans);
  return 0;
}
