#include <bits/stdc++.h>   const int N = 1e5 + 10;   const int LOGN = 20;   long long ans;   int n;   int pre[N << 1], to[N << 1], head[N], wcnt;   long long dis[N];   int val[N], fa[N];   int dep[N];   int table[LOGN][N << 1];   int LOG2[N << 1];   int idcnt;   int st[N];   inline int minp(int x, int y) { return (dep[x] < dep[y]) ? x : y; }   inline void swap(int &x, int &y) {     int t = x;     x = y;     y = t;   }   template <class T>   inline T max(const T &x, const T &y) {     return (x < y) ? y : x;   }   inline void addedge(int u, int v) {     wcnt++;     pre[wcnt] = head[u];     head[u] = wcnt;     to[wcnt] = v;   }   inline void add2edge(int u, int v) {     addedge(u, v);     addedge(v, u);   }   void init() {     int i, j, k;     for (i = int(2); i <= int(idcnt); i++) LOG2[i] = LOG2[i >> 1] + 1;     for (i = k = 1; k <= idcnt; i++, k <<= 1)       for (j = 1; j <= int(idcnt - k); j++)         table[i][j] = minp(table[i - 1][j], table[i - 1][j + k]);   }   inline long long getdis(int x, int y) {     int l, r, k, z;     l = st[x];     r = st[y];     if (l > r) swap(l, r);     k = LOG2[r - l + 1];     z = minp(table[k][l], table[k][r - (1 << k) + 1]);     return dis[x] + dis[y] - 2 * dis[z] + val[z];   }   struct Node {     int x, y;     long long d;     Node() {       x = y = 0;       d = -1;     }     Node(int x, int y) : x(x), y(y) { d = getdis(x, y); }     bool operator<(const Node &b) const { return d < b.d; }     Node operator+(const Node &b) const {       if (d == -1)         return b;       else if (b.d == -1)         return *this;       Node res = max(*this, b);       res = max(res, Node(x, b.x));       res = max(res, Node(x, b.y));       res = max(res, Node(y, b.x));       res = max(res, Node(y, b.y));       return res;     }   };   Node sum[N], g[N];   void predfs(int u) {     int i;     table[0][st[u] = ++idcnt] = u;     dis[u] = dis[fa[u]] + val[u];     for (i = head[u]; i; i = pre[i])       if (fa[u] ^ to[i]) {         fa[to[i]] = u;         dep[to[i]] = dep[u] + 1;         predfs(to[i]);         table[0][++idcnt] = u;       }   }   void dfs1(int u) {     int i;     sum[u] = Node(u, u);     for (i = head[u]; i; i = pre[i])       if (fa[u] ^ to[i]) {         dfs1(to[i]);         sum[u] = sum[u] + sum[to[i]];       }   }   void dfs2(int u) {     static Node pref[N], suff[N];     static int son[N];     int i, sn = 0;     for (i = head[u]; i; i = pre[i])       if (fa[u] ^ to[i]) son[++sn] = to[i];     pref[0] = suff[sn + 1] = g[u] + Node(u, u);     for (i = 1; i <= int(sn); i++) pref[i] = pref[i - 1] + sum[son[i]];     for (i = int(sn); i; i--) suff[i] = suff[i + 1] + sum[son[i]];     for (i = 1; i <= int(sn); i++) g[son[i]] = pref[i - 1] + suff[i + 1];     for (i = int(0); i <= int(sn + 1); i++) pref[i] = suff[i] = Node();     if (u > 1) ans = max(ans, sum[u].d + g[u].d);     for (i = head[u]; i; i = pre[i])       if (fa[u] ^ to[i]) dfs2(to[i]);   }   int main() {     int i;     int u, v;     scanf( %d , &n);     for (i = 1; i <= int(n); i++) scanf( %d , &val[i]);     for (i = 1; i <= int(n - 1); i++) {       scanf( %d %d , &u, &v);       add2edge(u, v);     }     predfs(1);     init();     dfs1(1);     ans = sum[1].d;     dfs2(1);     printf( %lld n , ans);     return 0;   }