__mt19937__ @ 2025-01-01 16:55:15
#include <bits/stdc++.h>
#define endl '\n'
const int N = 3000010;
const int M = N << 1;
const int L = 18;
struct edge_node {
int next, to;
} edge_vector[N];
std :: vector <std :: pair <int, int> > S[N], Q[N];
int _father[N][L], deep[N];
int bin1[M], bin2[M];
int answer[N], W[N], head[N];
int n, m, cnt;
template <typename _this>
void swap (_this & first, _this & second) {
_this tmp = first;
first = second;
second = tmp;
return ;
}
void add_edge (int _start_node, int _end_node) {
++ cnt;
edge_vector[cnt].to = _end_node;
edge_vector[cnt].next = head[_start_node];
head[_start_node] = cnt;
return ;
}
void init (int _this_node, int _father_node) {
_father[_this_node][0] = _father_node;
for (int i = 1; _father[_this_node][i - 1]; ++ i) {
_father[_this_node][i] = _father[_father[_this_node][i - 1]][i - 1];
}
for (int i = head[_this_node]; i; i = edge_vector[i].next) {
int visit = edge_vector[i].to;
if (visit == _father_node) {
continue;
}
deep[visit] = deep[_this_node] + 1;
init (visit, _this_node);
}
return;
}
int LCA (int left, int right) {
if (deep[left] < deep[right]) {
swap (left, right);
}
for (int i = L; ~ i; -- i) {
if (deep[left] - (1 << i) >= deep[right]) {
left = _father[left][i];
}
}
if (left == right) {
return left;
}
for (int i = L; ~ i; -- i) {
if (_father[left][i] != _father[right][i]) {
left = _father[left][i];
right = _father[right][i];
}
}
return _father[left][0];
}
void update (int _start_, int _end_) {
int P = LCA (_start_, _end_);
S[_start_].push_back (std :: make_pair (deep[_start_], 1));
S[_father[P][0]].push_back (std :: make_pair (deep[_start_], -1));
Q[_end_].push_back (std :: make_pair (deep[_start_] - (deep[P] << 1) + n, 1));
Q[P].push_back (std :: make_pair (deep[_start_] - (deep[P] << 1) + n, -1));
return ;
}
void deep_first_search (int _this_node, int _father_node) {
int V1 = W[_this_node] + deep[_this_node], V2 = deep[_this_node] - W[_this_node] + n;
int P_first = bin1[V1], P_second = bin2[V2];
for (int i = head[_this_node]; i; i = edge_vector[i].next) {
int visit = edge_vector[i].to;
if (visit == _father_node) {
continue;
}
deep_first_search (visit, _this_node);
}
for (int i = 0; i < S[_this_node].size (); ++ i) {
bin1[S[_this_node][i].first] += S[_this_node][i].second;
}
for (int i = 0; i < Q[_this_node].size (); ++ i) {
bin2[Q[_this_node][i].first] += Q[_this_node][i].second;
}
answer[_this_node] = bin1[V1] + bin2[V2] - P_first - P_second;
return ;
}
int main (void) {
std :: ios :: sync_with_stdio (false);
std :: cin.tie (nullptr);
std :: cout.tie (nullptr);
std :: cin >> n >> m;
for (int i = 1; i < n; ++ i) {
int st, ed;
std :: cin >> st >> ed;
add_edge (st, ed);
add_edge (ed, st);
}
for (int i = 1; i <= n; ++ i) {
std :: cin >> W[i];
}
init (1, 0);
for (int i = 1; i <= m; ++ i) {
int _s, _t;
std :: cin >> _s >> _t;
update (_s, _t);
}
deep_first_search (1, 0);
for (int i = 1; i <= n; ++ i) {
std :: cout << answer[i] << ' ';
}
return 0;
}