/**
Author : Kamonasish Roy (Bullet)
Basic DP on Tree But Medium Level, Because we need to optimize.
First we need to calculate all depth level node.
then we caluculate all its child
if it has two child transition:
DP[parent][lenght]=max(DP[child1][lenght-1],DP[child2][lenght-1])+his own weight
similary , if it has one child, we should consider it.
This way we can build a dp table.
after that we can merge if it has two child,
like Dp[parent][k]=MAX(Dp[child1][i],DP[child2][k-i])...i=2 to K-1.
Why K-1, beacause Parent itselt in the path.
But If graph is a tree, then we may have more two children.
Then we can use prefix and suffix sum...then we marge.
We can count it on the vector max prefix and suffix sum all possible his
children.
Basically re-rooting dp technique, we can use here to merge the path sum.
**/
#include<bits/stdc++.h>
using namespace std;
const long long M=1e5+10,MOD=1e9+7;
typedef long long ll;
#define debug(x) cout<<x<<endl
ll dp[M][501];
vector<int>edge[M];
int a[M];
vector<int>par[M];
void dfs(int x,int p,int n,int k){
dp[x][1]=a[x];
for(auto u:edge[x]){
if(u==p)continue;
dfs(u,x,n,k);
par[x].push_back(u);
for(int i=2;i<=k;i++){
dp[x][i]=max(dp[x][i],dp[u][i-1]+dp[x][1]);
}
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int t=1;
// cin>>t;
while(t--){
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<n;i++){
int u,v;
cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
for(int i=1;i<=n;i++){
for(int j=0;j<=k;j++)dp[i][j]=-1e12;
}
dfs(1,-1,n,k);
ll mx=0;
for(int i=1;i<=n;i++)mx=max(mx,dp[i][k]);
for(int i=1;i<=n && k>2;i++){
if((int)par[i].size()<=1)continue;
vector<ll>First_best(k+1,-1e12);
vector<ll>Second_best(k+1,-1e12);
for(auto it:par[i]){
for(int start=1;start<=k;start++){
if(First_best[start]<=dp[it][start]){
Second_best[start]=First_best[start];
First_best[start]=dp[it][start];
}
else{
Second_best[start]=max(Second_best[start],dp[it][start]);
}
}
}
for(auto it:par[i]){
int l=1,r=k-2;
while(r>0){
ll second=First_best[r];
if(dp[it][r]==First_best[r])second=Second_best[r];
mx=max(mx,dp[it][l]+second+dp[i][1]);
l++;
r--;
}
}
}
cout<<mx<<"\n";
}
return 0;
}