#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MINF = -1e9;
int N, K;
vector<ll> A;
vector<vector<int>> g;
vector<vector<ll>> dp; // dp[i][j] = max weight path in subtree of i with exactly j nodes
ll ans = 0;
void dfs(int u, int p) {
dp[u][1] = A[u]; // base case
vector<multiset<ll>> val(K + 1);
for (int v : g[u]) {
if (v == p) continue;
dfs(v, u);
// For merging later
for (int j = 1; j <= K; ++j) {
if (dp[v][j] != MINF)
val[j].insert(dp[v][j]);
}
// Single chain path: extend chain by taking child
for (int j = 1; j < K; ++j) {
if (dp[v][j] != MINF)
dp[u][j + 1] = max(dp[u][j + 1], dp[v][j] + A[u]);
}
}
ans = max(ans, dp[u][K]);
for (int v : g[u]) {
if (v == p) continue;
for (int r = 1; r <= K - 2; ++r) {
ll left = dp[v][r];
ll rem = K - r - 1;
if (left == MINF) continue;
if (rem < 1) continue;
ll rightPart = dp[v][rem];
if (rightPart != MINF) {
val[rem].erase(val[rem].find(rightPart));
}
if (!val[rem].empty()) {
ll right = *val[rem].rbegin();
ans = max(ans, left + A[u] + right);
}
if (rightPart != MINF) {
val[rem].insert(rightPart);
}
}
}
for(int v : g[u]){
if (v == p) continue;
dp[v].clear();
}
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> K;
A.resize(N + 1);
g.resize(N + 1);
dp.assign(N + 1, vector<ll>(K + 1, MINF));
for (int i = 1; i <= N; ++i) {
cin >> A[i];
}
for (int i = 1; i < N; ++i) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
dfs(1, 0);
cout << ans << '\n';
return 0;
}