#include <bits/stdc++.h>
using namespace std;
template <typename T1, typename T2>
void chkmin(T1 &x, T2 y) {
  if (x > y) x = y;
}
template <typename T1, typename T2>
void chkmax(T1 &x, T2 y) {
  if (x < y) x = y;
}
namespace fastio {
char rbuf[1 << 23], *p1 = rbuf, *p2 = rbuf, wbuf[1 << 23], *p3 = wbuf;
inline char getc() {
  return p1 == p2 &&
                 (p2 = (p1 = rbuf) + fread(rbuf, 1, 1 << 23, stdin), p1 == p2)
             ? -1
             : *p1++;
}
inline void putc(char x) { (*p3++ = x); }
template <typename T>
void read(T &x) {
  x = 0;
  char c = getchar();
  T neg = 0;
  while (!isdigit(c)) neg |= !(c ^ '-'), c = getchar();
  while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
  if (neg) x = (~x) + 1;
}
template <typename T>
void recursive_print(T x) {
  if (!x) return;
  recursive_print(x / 10);
  putc(x % 10 ^ 48);
}
template <typename T>
void print(T x) {
  if (!x) putc('0');
  if (x < 0) putc('-'), x = ~x + 1;
  recursive_print(x);
}
void print_final() { fwrite(wbuf, 1, p3 - wbuf, stdout); }
}  // namespace fastio
const int MAXN = 1e5;
int n, a[MAXN + 5];
vector<int> g[MAXN + 5];
vector<pair<long long, long long> > pre[MAXN + 5];
vector<pair<long long, long long> > suf[MAXN + 5];
pair<long long, long long> out[MAXN + 5], dp[MAXN + 5];
pair<long long, long long> merge(pair<long long, long long> x, long long y) {
  long long a[3] = {0};
  a[0] = x.first;
  a[1] = x.second;
  a[2] = y;
  sort(a, a + 3);
  reverse(a, a + 3);
  return make_pair(a[0], a[1]);
}
void dfs1(int x = 1, int f = 0) {
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    if (y == f) continue;
    dfs1(y, x);
    dp[x] = merge(dp[x], dp[y].first + a[y]);
  }
}
void dfs2(int x = 1, int f = 0) {
  pre[x].resize(g[x].size() + 2);
  suf[x].resize(g[x].size() + 2);
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    if (y == f)
      pre[x][i + 1] = merge(pre[x][i], out[x].first + a[f]);
    else
      pre[x][i + 1] = merge(pre[x][i], dp[y].first + a[y]);
  }
  for (int i = (int)g[x].size() - 1; ~i; i--) {
    int y = g[x][i];
    if (y == f)
      suf[x][i + 1] = merge(suf[x][i + 2], out[x].first + a[f]);
    else
      suf[x][i + 1] = merge(suf[x][i + 2], dp[y].first + a[y]);
  }
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    if (y == f) continue;
    long long a[4] = {0};
    a[0] = pre[x][i].first;
    a[1] = pre[x][i].second;
    a[2] = suf[x][i + 2].first;
    a[3] = suf[x][i + 2].second;
    sort(a, a + 4);
    reverse(a, a + 4);
    out[y] = make_pair(a[0], a[1]);
    dfs2(y, x);
  }
}
long long mx[MAXN + 5], ans = 0;
void dfs3(int x = 1, int f = 0) {
  mx[x] = dp[x].first + dp[x].second + a[x];
  multiset<long long> st;
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    if (y == f) continue;
    dfs3(y, x);
    chkmax(mx[x], mx[y]);
    st.insert(mx[y]);
  }
  if (st.size() >= 2) {
    long long v1 = *st.rbegin();
    st.erase(st.find(v1));
    long long v2 = *st.rbegin();
    chkmax(ans, v1 + v2);
  }
}
multiset<long long> st;
void dfs4(int x = 1, int f = 0) {
  if (x != 1) {
    st.insert(out[x].first + out[x].second + a[f]);
    chkmax(ans, dp[x].first + dp[x].second + a[x] + (*st.rbegin()));
  }
  for (int i = 0; i < g[x].size(); i++) {
    int y = g[x][i];
    if (y == f) continue;
    dfs4(y, x);
  }
  if (x != 1) st.erase(st.find(out[x].first + out[x].second + a[f]));
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
  for (int i = 1, u, v; i < n; i++)
    scanf("%d%d", &u, &v), g[u].push_back(v), g[v].push_back(u);
  dfs1();
  dfs2();
  dfs3();
  dfs4();
  printf("%lld\n", ans);
  return 0;
}
