#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
typedef long long ll;
using namespace __gnu_pbds;
using namespace std;
#define ff first
#define ss second
#define pi pair<int, int>
#define pll pair<long long, long long>
#define vi vector<int>
#define vll vector<long long>
#define vpi vector<pair<int,int>>
#define vpll vector<pair<long long, long long>>
#define pb push_back
#define count_bits(x) __builtin_popcountll((x))
#define all(x) (x).begin(),(x).end()
#define sz(x) (ll)(x).size()
#define forall(it,x) for(auto& it:(x))
#define mp make_pair
pi operator+(pi a, pi b) { return mp(a.ff+b.ff, a.ss+b.ss); }
pi operator-(pi a, pi b) { return mp(a.ff-b.ff, a.ss-b.ss); }
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
int D;
int M = 400'010;
vector<vector<int>> g(M);
vector<int> par(M), sajz(M), is_off(M), par_idx(M), dist(M), T(M), parent(M), old_T(M);
vector<vector<int>> ans(M), anst0(M);
vector<vector<vector<int>>> st_ans(M), st_anst0(M);
void sajz_dfs(int v, int p) {
parent[v] = p;
sajz[v] = 1;
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
sajz_dfs(u,v);
sajz[v] += sajz[u];
}
}
ll find_centroid(ll v, ll ts) {
for(auto u : g[v]) {
if(is_off[u]) continue;
if(u==parent[v]) {
if(ts-sajz[v] > ts/2) return find_centroid(u,ts);
} else {
if(sajz[u] > ts/2) return find_centroid(u,ts);
}
}
return v;
}
vector<int> zb;
void zb_dfs(int v, int p) {
zb.pb(v);
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
zb_dfs(u,v);
}
}
void dist_dfs(int v, int p) {
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
dist[u] = dist[v] + 1;
dist_dfs(u,v);
}
}
void newT_dfs(int v, int p) {
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
T[u] = min(T[u], T[v] + 1);
newT_dfs(u,v);
}
}
void zeroT_dfs(int v, int p) {
T[v] = 0;
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
zeroT_dfs(u,v);
}
}
void oldT_dfs(int v, int p) {
T[v] = old_T[v];
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
oldT_dfs(u,v);
}
}
vector<vector<int>> get_dist(M), is_full(M);
void full_dfs(int v, int p, int ctr, int d, int best) {
best = min(best, d + T[v]);
int val = 0;
if(d >= best) val = 1;
is_full[v].pb(val);
get_dist[v].pb(d);
for(auto u : g[v]) {
if(u==p || is_off[u]) continue;
full_dfs(u,v,ctr,d+1,best);
}
}
int ctd(int v) {
sajz_dfs(v, v);
v = find_centroid(v, sajz[v]);
full_dfs(v,v,v,0,T[v]);
dist[v] = 0;
dist_dfs(v,v);
newT_dfs(v,v);
while(zb.size()) zb.pop_back();
zb_dfs(v,v);
int max_dist = 0;
for(auto x : zb) max_dist = max(max_dist, dist[x]);
ans[v].assign(max_dist + 1, 0);
anst0[v].assign(max_dist + 1, 0);
for(auto x : zb) {
int L = T[x] - dist[x];
int R = D - dist[x];
if(L < 0) L=0;
if(R > max_dist) R=max_dist;
if(R >= 0) {
anst0[v][0]++;
if(R + 1 <= max_dist) anst0[v][R+1]--;
}
if(L > R) continue;
ans[v][L]++;
if(R + 1 <= max_dist) ans[v][R+1]--;
}
for(int i=1; i<=max_dist; ++i) ans[v][i] += ans[v][i-1];
for(int i=1; i<=max_dist; ++i) anst0[v][i] += anst0[v][i-1];
for(auto u : g[v]) {
if(is_off[u]) continue;
while(zb.size()) zb.pop_back();
zb_dfs(u, v);
st_ans[v].pb({});
st_anst0[v].pb({});
int max_d = 0;
for(auto x : zb) max_d = max(max_d, dist[x]);
st_ans[v].back().assign(max_d+1, 0);
st_anst0[v].back().assign(max_d+1, 0);
for(auto x : zb) {
int L = T[x] - dist[x];
int R = D - dist[x];
if(L < 0) L=0;
if(R > max_d) R=max_d;
if(R >= 0) {
st_anst0[v].back()[0]++;
if(R + 1 <= max_d) st_anst0[v].back()[R+1]--;
}
if(L > R) continue;
st_ans[v].back()[L]++;
if(R + 1 <= max_d) st_ans[v].back()[R+1]--;
}
for(int i=1; i<=max_d; ++i) st_ans[v].back()[i] += st_ans[v].back()[i-1];
for(int i=1; i<=max_d; ++i) st_anst0[v].back()[i] += st_anst0[v].back()[i-1];
}
oldT_dfs(v,v);
is_off[v] = 1;
int idx = 0;
for(auto u : g[v]) {
if(is_off[u]) continue;
int ctr = ctd(u);
par[ctr] = v;
par_idx[ctr] = idx;
++idx;
}
return v;
}
signed main() {
ios_base::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
int n;
cin >> n >> D;
for(int i=1; i<=n; ++i) cin >> T[i];
old_T = T;
for(int i=1; i<n; ++i) {
int a, b;
cin >> a >> b;
g[a].pb(b);
g[b].pb(a);
}
int ctr = ctd(1);
par[ctr] = -1;
for(int i=1; i<=n; ++i) {
int v = i;
int idx = -1;
ll res = 0;
while(v != -1) {
int my_d = get_dist[i].back();
get_dist[i].pop_back();
int isf = is_full[i].back();
is_full[i].pop_back();
if(my_d <= D) {
if(!isf) {
res += ans[v][my_d];
if(idx != -1) res -= st_ans[v][idx][my_d];
} else {
res += anst0[v][my_d];
if(idx != -1) res -= st_anst0[v][idx][my_d];
}
}
idx = par_idx[v];
v = par[v];
}
cout << res << "\n";
}
return 0;
}