#include <bits/stdc++.h>
using namespace std;
const int MAXN = 100000;
const int MAXK = 300;
long long maxWeight = 0;
vector<int> adj[MAXN + 1]; // Adjacency list to represent the tree
vector<long long> value(MAXN + 1); // Value assigned to each node
vector<vector<long long>> dp(MAXN + 1, vector<long long>(MAXK + 1, -1)); // DP table to store results
// Depth-first search to compute paths of exact length K
void dfs(int node, int parent) {
dp[node][0] = value[node]; // A path of length 1 starting at the node has a weight equal to the node's value
for (int child : adj[node]) {
if (child == parent) continue; // Skip the parent to avoid cycles
dfs(child, node); // Recurse into the child
// Merge results from child into current node's dp
for (int len = MAXK; len > 0; --len) { // Traverse backwards to avoid overwriting results
for (int i = 0; i < len; ++i) {
if (dp[child][i] != -1 && dp[node][len - i - 1] != -1) {
dp[node][len] = max(dp[node][len], dp[node][len - i - 1] + dp[child][i]);
}
}
}
}
// Check if any path of length K has been found at this node
if (dp[node][K] != -1) {
maxWeight = max(maxWeight, dp[node][K]);
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, K;
cin >> N >> K;
for (int i = 1; i <= N; ++i) {
cin >> value[i];
}
for (int i = 0; i < N - 1; ++i) {
int u, v;
cin >> u >> v;
adj[u].push_back(v);
adj[v].push_back(u);
}
// Perform DFS starting from node 1 (root)
dfs(1, -1);
// Output the maximum weight found
cout << (maxWeight == 0 ? 0 : maxWeight) << "\n";
return 0;
}