#include <bits/stdc++.h>
using namespace std;
int INF = 1e9 + 1e8;
double eps = 0.0000001;
double pi = 3.1415926535;
struct point {
  double x = 0, y = 0;
  point(double a, double b) {
    x = a;
    y = b;
  }
};
struct Vect {
  double x = 0, y = 0;
  Vect(double a, double b) {
    x = a;
    y = b;
  }
  Vect(point a, point b) {
    x = b.x - a.x;
    y = b.y - a.y;
  }
  double dist() { return hypot(x, y); }
};
double sc_pr(Vect a, Vect b) { return a.x * b.x + a.y * b.y; }
double vect_pr(Vect a, Vect b) { return a.x * b.y - a.y * b.x; }
double line(point A, point B, double &a, double &b, double &c) {
  a = A.y - B.y;
  b = B.x - A.x;
  c = A.x * B.y - B.x * A.y;
}
double dist_otr(point p, point a, point b) {
  Vect AP(a, p), AB(a, b), BA(b, a), BP(b, p), PA(p, a), PB(p, b);
  if (sc_pr(AP, AB) >= 0 && sc_pr(BA, BP) >= 0)
    return fabs(vect_pr(AP, AB)) / AB.dist();
  else
    return min(PA.dist(), PB.dist());
}
double dist_otr1(point p, point a, point b) {
  Vect AP(a, p), AB(a, b), BA(b, a), BP(b, p), PA(p, a), PB(p, b);
  return max(PA.dist(), PB.dist());
}
bool comp(point a1, point a2) {
  point p(0, 0), b(10, 0);
  Vect PA1(p, a1), PA2(p, a2), PB(p, b);
  double q1 = -atan2(vect_pr(PA1, PB), sc_pr(PA1, PB));
  double q2 = -atan2(vect_pr(PA2, PB), sc_pr(PA2, PB));
  if (q1 < 0) q1 = q1 + 10;
  if (q2 < 0) q2 = q2 + 10;
  if (fabs(q1 - q2) < eps) {
    if (PA1.dist() < PA2.dist())
      return 1;
    else
      return 0;
  }
  return (q1 < q2);
}
double gr(point a1, point a2) {
  point p(0, 0);
  Vect PA1(p, a1), PA2(p, a2);
  return atan2(vect_pr(PA1, PA2), sc_pr(PA1, PA2));
}
bool per_otr_line(point A, point B, double a, double b, double c) {
  if (fabs(b) >= eps) {
    point P(1e7, -(a * 1e7 + c) / b), C(-1e7, -(-a * 1e7 + c) / b);
    Vect PC(P, C), PA(P, A), PB(P, B);
    double q1 = vect_pr(PC, PA);
    double q2 = vect_pr(PC, PB);
    if (q1 > 0 && q2 > 0 || q1 < 0 && q2 < 0) return 0;
    return 1;
  }
  point P(-c / a, -1e7), C(-c / a, 1e7);
  Vect PC(P, C), PA(P, A), PB(P, B);
  double q1 = vect_pr(PC, PA);
  double q2 = vect_pr(PC, PB);
  if (q1 > 0 && q2 > 0 || q1 < 0 && q2 < 0) return 0;
  return 1;
}
int main() {
  ios_base::sync_with_stdio(0);
  int n;
  cin >> n;
  multiset<int> Q;
  vector<int> bank(n);
  for (int i = 0; i < n; i++) {
    int a;
    cin >> a;
    bank[i] = a;
    Q.insert(a);
  }
  vector<vector<int>> edges(n);
  for (int i = 0; i < n - 1; i++) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    edges[a].push_back(b);
    edges[b].push_back(a);
  }
  int anss = INF;
  for (int i = 0; i < n; i++) {
    int ans = -INF;
    int u = i;
    ans = max(ans, bank[u]);
    Q.erase(Q.find(bank[u]));
    for (auto elem : edges[u]) {
      ans = max(ans, bank[elem] + 1);
      Q.erase(Q.find(bank[elem]));
    }
    if (Q.size() > 0) {
      auto it = Q.end();
      it--;
      ans = max(ans, *it + 2);
    }
    Q.insert(bank[u]);
    for (auto elem : edges[u]) Q.insert(bank[elem]);
    anss = min(anss, ans);
  }
  cout << anss;
  return 0;
}
