/*
树形DP
根节点一定有人 然后 剩下的人没到每个孩子去
因为孩子数可能很多 不好枚举 所以转二叉树 分两部分 O(sum)就可以了
当然 转二叉树候必须顾及原来树的一些性质 如不能只选左孩子
转化好了之后就是DP了
写的记忆化 递归每个节点 枚举分给左右孩子的人数
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1010
using namespace std;
int n,m,son[maxn][];
int f[maxn][maxn],a[maxn],ans;
int DP(int k,int sum)//到节点k时 还剩sum个人没有用
{
int i,maxx=;
if(f[k][sum]!=)return f[k][sum];//记忆化
if(k==||sum==)return ;//剪枝
f[k][sum]=a[k];//先整一个人在k处
for(i=;i<=sum;i++)//枚举给左孩子多少人 i-1
{
if(DP(son[k][],i-)+a[k]+DP(son[k][],sum-i)>maxx)
maxx=DP(son[k][],i-)+a[k]+DP(son[k][],sum-i);
if(DP(son[k][],i)>maxx)maxx=DP(son[k][],sum);//特殊情况 不要k 只要右孩子
//因为这是多叉树转化来的 所以可以实现相反的 不能只要左孩子 因为左孩子和k连在一起
}
if(f[k][sum]<maxx)
f[k][sum]=maxx;
return f[k][sum];
}
int main()
{
cin>>n>>m;
int i,x,y;
for(i=;i<=n;i++)cin>>a[i];
for(i=;i<=n;i++)
{
cin>>x>>y;
if(son[x][]==)son[x][]=y;
else
{
int fa=son[x][];
while(son[fa][])fa=son[fa][];
son[fa][]=y;
}
}
ans=DP(son[][],m);
cout<<ans;
return ;
}