#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000 + 9;
const int ALPHA = 26 + 1;
int n;
vector<int> a;
long long maxAns;
vector<vector<int>> edges;
long long solved[MAXN][3][2];
void fill() {
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < 3; ++j) {
      for (int k = 0; k < 2; ++k) {
        solved[i][j][k] = -1;
      }
    }
  }
}
long long solve(int v, int pc, bool up, int parent) {
  struct Ans {
    Ans() {}
    Ans(int child, long long noup, long long up)
        : child(child), noup(noup), up(up) {}
    int child;
    long long noup = 0;
    long long up = 0;
  };
  if (solved[v][pc][up] == -1) {
    long long& val = solved[v][pc][up];
    val = 0;
    vector<Ans> Ps;
    vector<Ans> P2s;
    Ps.push_back(Ans(0, 0, 0));
    P2s.push_back(Ans(0, 0, 0));
    for (int i = 0; i < edges[v].size(); ++i) {
      int to = edges[v][i];
      if (to == parent) {
        continue;
      }
      Ans P;
      P.child = i;
      P.noup = solve(to, 1, false, v);
      P.up = solve(to, 1, true, v);
      {
        int dom = 0;
        for (int i = 0; i < Ps.size(); ++i) {
          if (Ps[i].up >= P.up && Ps[i].noup >= P.noup) {
            ++dom;
          }
          if (dom > 4) {
            break;
          }
        }
        if (dom <= 4) {
          Ps.push_back(P);
        }
      }
      if (pc == 2) {
        val = max(val, a[v] + solve(to, 2, true, v));
        if (!up) {
          val = max(val, solve(to, 2, false, v));
        }
        Ans P2;
        P2.child = i;
        P2.noup = solve(to, 2, false, v);
        P2.up = solve(to, 2, true, v);
        int dom = 0;
        for (int i = 0; i < P2s.size(); ++i) {
          if (P2s[i].up >= P2.up && P2s[i].noup >= P2.noup) {
            ++dom;
          }
          if (dom > 4) {
            break;
          }
        }
        if (dom <= 4) {
          P2s.push_back(P2);
        }
      }
    }
    if (pc == 1) {
      for (int i = 0; i < Ps.size(); ++i) {
        auto& p1 = Ps[i];
        val = max(val, a[v] + p1.up);
        if (!up) {
          val = max(val, p1.noup);
          for (int j = 0; j < Ps.size(); ++j) {
            if (i == j) {
              continue;
            }
            auto& p2 = Ps[j];
            val = max(val, p1.up + p2.up + a[v]);
          }
        }
      }
    } else {
      for (int i = 0; i < Ps.size(); ++i) {
        auto& p1 = Ps[i];
        val = max(val, a[v] + p1.noup);
        if (!up) {
          for (int j = 0; j < P2s.size(); ++j) {
            auto& p2 = P2s[j];
            if (p1.child == p2.child) {
              continue;
            }
            val = max(val, a[v] + p1.up + p2.up);
          }
        }
        for (int j = 0; j < Ps.size(); ++j) {
          if (i == j) {
            continue;
          }
          auto& p2 = Ps[j];
          val = max(val, p1.noup + p2.up + a[v]);
          if (!up) {
            val = max(val, p1.noup + p2.noup);
            for (int k = 0; k < Ps.size(); ++k) {
              if (i == k || j == k) {
                continue;
              }
              auto& p3 = Ps[k];
              val = max(val, p1.noup + p2.up + p3.up + a[v]);
            }
          }
        }
      }
    }
  }
  return solved[v][pc][up];
}
int main() {
  ios::sync_with_stdio(false);
  cin >> n;
  a.resize(n);
  edges.resize(n);
  fill();
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }
  for (int i = 0; i < n - 1; ++i) {
    int x, y;
    cin >> x >> y;
    --x;
    --y;
    edges[x].push_back(y);
    edges[y].push_back(x);
  }
  for (int i = 0; i < n; ++i) {
    random_shuffle(edges[i].begin(), edges[i].end());
  }
  cout << solve(0, 2, false, -1) << endl;
  return 0;
}
