#include <bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
int n;
int val[maxn];
//to 成员变量表示该边指向的目标节点
struct Edge {
int to;
};
vector<Edge> edge[maxn]; // 使用vector存储邻接表
int head[maxn], cnt;
int f[maxn][2];
void add(int from, int to) {
edge[from].push_back({to}); // 将边添加到邻接表中
}
void dfs(int u, int fa) {
for (auto &e : edge[u]) { // 遍历u的邻接表
int v = e.to;
if (v != fa)
continue;
dfs(v, u);
f[u][0] += max(f[v][0], f[v][1]); // 更新当前节点的最大权值
f[u][1] += f[v][0]; // 更新当前节点的次大权值
}
}
int main() {
scanf("%d", &n); // 输入点的数量
for (int i = 1; i <= n; ++i)
scanf("%d", &val[i]), f[i][1] = val[i]; // 输入每个点的权值
for (int i = 1; i < n; ++i) { // 构建树
int u, v;
scanf("%d%d", &u, &v);
add(u, v), add(v, u); // 添加边到邻接表
}
dfs(1, 0); // 从根节点开始深度优先搜索
printf("%d\n", max(f[1][0], f[1][1])); // 输出最大权值
return 0;
}