#include <bits/stdc++.h>
using namespace std;
template <typename T>
T in() {
  char ch;
  T n = 0;
  bool ng = false;
  while (1) {
    ch = getchar();
    if (ch == '-') {
      ng = true;
      ch = getchar();
      break;
    }
    if (ch >= '0' && ch <= '9') break;
  }
  while (1) {
    n = n * 10 + (ch - '0');
    ch = getchar();
    if (ch < '0' || ch > '9') break;
  }
  return (ng ? -n : n);
}
template <typename T>
inline T POW(T B, T P) {
  if (P == 0) return 1;
  if (P & 1)
    return B * POW(B, P - 1);
  else
    return (POW(B, P / 2) * POW(B, P / 2));
}
template <typename T>
inline T Gcd(T a, T b) {
  if (a < 0) return Gcd(-a, b);
  if (b < 0) return Gcd(a, -b);
  return (b == 0) ? a : Gcd(b, a % b);
}
template <typename T>
inline T Lcm(T a, T b) {
  if (a < 0) return Lcm(-a, b);
  if (b < 0) return Lcm(a, -b);
  return a * (b / Gcd(a, b));
}
long long Bigmod(long long base, long long power, long long MOD) {
  long long ret = 1;
  while (power) {
    if (power & 1) ret = (ret * base) % MOD;
    base = (base * base) % MOD;
    power >>= 1;
  }
  return ret;
}
bool isVowel(char ch) {
  ch = toupper(ch);
  if (ch == 'A' || ch == 'U' || ch == 'I' || ch == 'O' || ch == 'E')
    return true;
  return false;
}
long long ModInverse(long long number, long long MOD) {
  return Bigmod(number, MOD - 2, MOD);
}
bool isConst(char ch) {
  if (isalpha(ch) && !isVowel(ch)) return true;
  return false;
}
int toInt(string s) {
  int sm;
  stringstream second(s);
  second >> sm;
  return sm;
}
vector<int> A[500007];
int a[500007];
long long int Dp[500007];
vector<pair<long long int, int> > dp[500007];
void Dfs1(int u, int p, long long int vl) {
  long long int mx1 = -1, mx2 = -1;
  dp[u].push_back(make_pair(vl, p));
  for (int i = 0; i < A[u].size(); i++) {
    int v = A[u][i];
    if (v == p) continue;
    int Ln = dp[u].size() - 1;
    int lft = max(0, Ln - 5);
    long long int now = vl;
    for (int j = Ln; j >= lft; j--) {
      int tp = dp[u][j].second;
      if (tp == v) continue;
      now = max(now, dp[u][j].first);
    }
    Dfs1(v, u, now + a[u]);
  }
  sort(dp[u].begin(), dp[u].end());
}
long long int Dfs(int u, int p) {
  long long int mx1 = -1, mx2 = -1;
  for (int i = 0; i < A[u].size(); i++) {
    int v = A[u][i];
    if (v == p) continue;
    long long int tp = Dfs(v, u);
    dp[u].push_back(make_pair(tp, v));
    if (tp > mx1) {
      mx2 = mx1;
      mx1 = tp;
    } else if (tp > mx2) {
      mx2 = tp;
    }
  }
  Dp[u] = max(0LL, mx1) + max(0LL, mx2) + a[u];
  sort(dp[u].begin(), dp[u].end());
  return ((0LL > mx1) ? 0LL : mx1) + a[u];
}
void Wow(int u, int p) {
  for (int i = 0; i < A[u].size(); i++) {
    int v = A[u][i];
    if (v == p) continue;
    Wow(v, u);
    Dp[u] = max(Dp[u], Dp[v]);
  }
}
long long int Ans;
void Dekhi(int u, int p) {
  for (int i = 0; i < A[u].size(); i++) {
    int v = A[u][i];
    if (v == p) continue;
    Dekhi(v, u);
  }
  if (p) {
    int Ln = dp[p].size() - 1;
    int lft = max(0, Ln - 5);
    long long int now = Dp[u] + a[p];
    for (int i = Ln; i >= lft; i--) {
      if (dp[p][i].second == u) continue;
      for (int j = i - 1; j >= lft; j--) {
        if (dp[p][j].second == u) continue;
        long long int tp = dp[p][i].first + dp[p][j].first;
        if (Ans < now + tp) {
          Ans = now + tp;
        }
      }
      long long int tp = dp[p][i].first;
      if (Ans < now + tp) {
        Ans = now + tp;
      }
    }
    Ans = max(Ans, now);
  }
  return;
}
int main() {
  int n;
  n = in<int>();
  for (int i = 1; i <= n; i++) a[i] = in<int>();
  for (int i = 1; i < n; i++) {
    int u, v;
    u = in<int>(), v = in<int>();
    A[u].push_back(v);
    A[v].push_back(u);
  }
  vector<int> root;
  for (int i = 1; i <= n; i++) {
    if (A[i].size() == 1) {
      root.push_back(i);
    }
  }
  for (int i = 0; i < root.size(); i++) {
    for (int j = 1; j <= n; j++) {
      dp[j].clear();
    }
    long long int tp = Dfs(root[i], 0);
    Dfs1(root[i], 0, 0);
    Wow(root[i], 0);
    Dekhi(root[i], 0);
    if (i == 10) break;
  }
  printf("%lld\n", Ans);
  return 0;
}
