#include <bits/stdc++.h>
using namespace std;
const int maxn = 100010;
vector<int> G[maxn];
long long mx_path[maxn], mx_dis[maxn];
long long lmx_path[maxn], rmx_path[maxn];
pair<long long, long long> lmx_dis[maxn], rmx_dis[maxn];
long long val[maxn];
long long ans = 0;
void add(int x, int y) {
  G[x].push_back(y);
  G[y].push_back(x);
}
void dfs(int x, int fa) {
  vector<long long> tmp(3);
  for (auto y : G[x]) {
    if (y == fa) continue;
    dfs(y, x);
    tmp[0] = mx_dis[y];
    sort(tmp.begin(), tmp.end());
    mx_path[x] = max(mx_path[y], mx_path[x]);
  }
  mx_dis[x] = tmp[2] + val[x];
  mx_path[x] = max(mx_path[x], tmp[1] + tmp[2] + val[x]);
  return;
}
int tot, a[maxn];
struct node {
  int x, fa;
  long long mx_p, mx_d;
};
queue<node> q;
void solve() {
  q.push((node){1, 0, 0, 0});
  while (q.size()) {
    node tmp = q.front();
    q.pop();
    tot = 0;
    int x = tmp.x, fa = tmp.fa;
    tot = 0;
    for (int i = 0; i < G[x].size(); i++) {
      if (G[x][i] == fa) continue;
      a[++tot] = G[x][i];
    }
    rmx_path[tot + 1] = rmx_path[tot + 2] = 0;
    rmx_dis[tot + 1] = rmx_dis[tot + 2] = make_pair(0, 0);
    for (int i = 1; i <= tot; i++) {
      lmx_path[i] = max(lmx_path[i - 1], mx_path[a[i]]);
      lmx_dis[i] = lmx_dis[i - 1];
      if (mx_dis[a[i]] >= lmx_dis[i].first) {
        lmx_dis[i].second = lmx_dis[i].first;
        lmx_dis[i].first = mx_dis[a[i]];
      } else if (mx_dis[a[i]] > lmx_dis[i].second) {
        lmx_dis[i].second = mx_dis[a[i]];
      }
    }
    for (int i = tot; i >= 1; i--) {
      rmx_path[i] = max(rmx_path[i + 1], mx_path[a[i]]);
      rmx_dis[i] = rmx_dis[i + 1];
      if (mx_dis[a[i]] >= rmx_dis[i].first) {
        rmx_dis[i].second = rmx_dis[i].first;
        rmx_dis[i].first = mx_dis[a[i]];
      } else if (mx_dis[a[i]] > rmx_dis[i].second) {
        rmx_dis[i].second = mx_dis[a[i]];
      }
    }
    long long tmp1 = 0;
    for (int i = 1; i <= tot; i++) {
      long long tmp2 = 0;
      tmp2 = max(tmp2, lmx_path[i - 1]);
      tmp2 = max(tmp2, rmx_path[i + 1]);
      tmp2 = max(tmp2, tmp.mx_p);
      tmp2 = max(tmp2, val[x] + lmx_dis[i - 1].first + tmp.mx_d);
      tmp2 = max(tmp2, val[x] + rmx_dis[i + 1].first + tmp.mx_d);
      tmp2 = max(tmp2, val[x] + lmx_dis[i - 1].first + lmx_dis[i - 1].second);
      tmp2 = max(tmp2, val[x] + rmx_dis[i + 1].first + rmx_dis[i + 1].second);
      tmp2 = max(tmp2, val[x] + lmx_dis[i - 1].first + rmx_dis[i + 1].first);
      tmp2 = max(tmp2, val[x] + tmp.mx_d +
                           max(lmx_dis[i - 1].first, rmx_dis[i + 1].first));
      q.push((node){
          a[i], x, tmp2,
          val[x] +
              max(max(lmx_dis[i - 1].first, rmx_dis[i + 1].first), tmp.mx_d)});
      tmp2 += mx_path[a[i]];
      tmp1 = max(tmp1, tmp2);
    }
    ans = max(ans, tmp1);
    ans = max(ans, tmp.mx_p + mx_path[x]);
  }
}
int main() {
  int n, x, y;
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%lld", &val[i]);
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &x, &y);
    add(x, y);
  }
  dfs(1, 0);
  solve();
  printf("%lld\n", ans);
}
