#include <bits/stdc++.h>
using namespace std;
const int inf = 1e9 + 10, N = 3e5;
struct Edge {
  int v, f;
};
vector<Edge> adj[N + 1];
int g[N + 1], h[N + 1], a[N + 1], up[N + 1], fa[N + 1], ans[N + 1];
int dfs1(int u, int p) {
  fa[u] = p;
  g[u] = -inf;
  for (int i = (0), i_end = (adj[u].size()); i < i_end; ++i) {
    int v = adj[u][i].v;
    if (v != p) g[u] = max(g[u], dfs1(v, u));
  }
  return h[u] = max(g[u], a[u]);
}
void dfs2(int u, int p, int f) {
  up[u] = max(up[p], a[u]);
  ans[u] = max(f, up[fa[p]]);
  for (int i = (0), i_end = (adj[u].size()); i < i_end; ++i) {
    int v = adj[u][i].v;
    if (v != p) {
      ans[u] = max(ans[u], g[v]);
      dfs2(v, u, max(f, adj[u][i].f));
    }
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = (1), i_end = (n + 1); i < i_end; ++i) scanf("%d", &a[i]);
  for (int i = (0), i_end = (n - 1); i < i_end; ++i) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back((Edge){v, -inf});
    adj[v].push_back((Edge){u, -inf});
  }
  dfs1(1, 0);
  for (int i = (1), i_end = (n + 1); i < i_end; ++i) {
    int mx1 = -inf, mx2 = -inf;
    for (int j = (0), j_end = (adj[i].size()); j < j_end; ++j) {
      int v = adj[i][j].v;
      if (v == fa[i]) continue;
      int t = h[v];
      if (t >= mx1) {
        mx2 = mx1;
        mx1 = t;
      } else if (t > mx2) {
        mx2 = t;
      }
    }
    for (int j = (0), j_end = (adj[i].size()); j < j_end; ++j)
      adj[i][j].f = h[adj[i][j].v] == mx1 ? mx2 : mx1;
  }
  up[0] = -inf;
  dfs2(1, 0, -inf);
  for (int i = (1), i_end = (n + 1); i < i_end; ++i) {
    ans[i] = max(ans[i] + 2, a[i]);
    for (int j = (0), j_end = (adj[i].size()); j < j_end; ++j)
      ans[i] = max(ans[i], a[adj[i][j].v] + 1);
  }
  printf("%d\n", *min_element(ans + 1, ans + n + 1));
}
