//树型动态规划之舞会
#include<bits/stdc++.h>
using namespace std;
const int M=6010;
struct TNode{
int data;//快乐指数
int parent;//父亲
int k;//孩子数量,即结点的度
int child[M];//最多10个孩子
};
TNode tree[M];//树的头结点
int f[M][2];//f[i][0]表示不选i顶点的最大快乐指数;f[i][1]表示选顶点i时的最大快乐指数
int n,root;//n表示可选课总数;root根要查找
void dp(int x);//x为根编号
int main()
{
freopen("wuhui.in","r",stdin);
freopen("wuhui.out","w",stdout);
cin>>n;
for(int i=1;i<=n;i++) tree[i].parent=-1;//初始化父亲
for(int i=1;i<=n;i++)
{
int a;
cin>>a;
f[i][1]=a;//初始顶点i的快乐指数为a
}
for(int i=1;i<=n-1;i++)//输入n-1条边
{
int a,b;
cin>>a>>b;//b是a的直接上司
tree[b].child[++tree[b].k]=a;
tree[a].parent=b;
}
for(int i=1;i<=n-1;i++)//查找父亲
{
if(tree[i].parent==-1) root=i;
}
dp(root);//递推
/*测试代码
for(int i=1;i<=n-1;i++)
cout<<f[i][0]<<" "<<f[i][1]<<endl;
*/
cout<<max(f[root][0],f[root][1])<<endl;//输出根结点选或不选的最大值
}
void dp(int x)
{
for(int i=1;i<=tree[x].k;i++)//遍历所有孩子
{
int y=tree[x].child[i];//y为结点x的第i个孩子
dp(y);//深搜
//核心代码
f[x][0]+=max(f[y][0],f[y][1]);
f[x][1]+=f[y][0];
}
}