# 1 "d.cpp"
#include <bits/stdc++.h>
using namespace std;



struct HLD {
 int n, pos;
 vector<vector<int>> G;
 vector<int> vid, head, sub, hvy, par, dep, inv, type, ps, pt;
 HLD(int nn) :
  n(nn), pos(0), G(n),
  vid(n, -1), head(n), sub(n, 1), hvy(n, -1),
  par(n), dep(n), inv(n), type(n), ps(n), pt(n) {}

 void add_edge(int u, int v) {
  G[u].push_back(v);
  G[v].push_back(u);
 }
 void build(int root = 0) {
  int c = 0;
  dfs(root);
  bfs(root, c++);
 }


 void dfs(int rt) {
  using T = pair<int, int>;
  stack<T> st;
  par[rt] = -1;
  dep[rt] = 0;
  st.emplace(rt, 0);
  while (!st.empty()) {
   int v = st.top().first;
   int &i = st.top().second;
   if (i < (int)G[v].size()) {
    int u = G[v][i++];
    if (u == par[v]) continue;
    par[u] = v;
    dep[u] = dep[v] + 1;
    st.emplace(u, 0);
   }
   else {
    st.pop();
    for (int j = 0; j < (int)G[v].size(); j++) {
     int &u = G[v][j];
     if (u == par[v]) swap(u, G[v].back());
     if (u == par[v]) continue;
     sub[v] += sub[u];
     if (sub[u] > sub[G[v].front()]) swap(u, G[v].front());
    }
   }
  }
 }


 void bfs(int r, int c) {
  using T = tuple<int, int, int>;
  stack<T> st;
  st.emplace(r, r, 0);
  while (!st.empty()) {
   int v, h;
   tie(v, h, ignore) = st.top();
   int &i = get<2>(st.top());
   if (!i) {
    type[v] = c;
    ps[v] = vid[v] = pos++;
    inv[vid[v]] = v;
    head[v] = h;
    hvy[v] = (G[v].empty() ? -1 : G[v][0]);
    if (hvy[v] == par[v]) hvy[v] = -1;
   }
   if (i < (int)G[v].size()) {
    int u = G[v][i++];
    if (u == par[v]) continue;
    st.emplace(u, (hvy[v] == u ? h : u), 0);
   }
   else {
    st.pop();
    pt[v] = pos;
   }
  }
 }


 void for_each_vertex(int u, int v, const function<void(int, int)>& f) {
  while (1) {
   if (vid[u] > vid[v])swap(u, v);
   f(max(vid[head[v]], vid[u]), vid[v]);
   if (head[u] != head[v]) v = par[head[v]];
   else break;
  }
 }



 void for_each_directed(int u, int v, const function<void(int, int, int)>& f) {
  if (vid[u] > vid[v]) {
   f(max(vid[head[u]], vid[v]), vid[u], 1);
   if (head[u] != head[v]) for_each_directed(par[head[u]], v, f);
  }
  else {
   f(max(vid[head[v]], vid[u]), vid[v], 0);
   if (head[u] != head[v]) for_each_directed(u, par[head[v]], f);
  }
 }


 void for_each_edge(int u, int v, const function<void(int, int)>&f) {
  while (1) {
   if (vid[u] > vid[v])swap(u, v);
   if (head[u] != head[v]) {
    f(vid[head[v]], vid[v]);
    v = par[head[v]];
   }
   else {
    if (u != v)f(vid[u] + 1, vid[v]);
    break;
   }
  }
 }





 int kth_up(int u, int k) {
  while (1) {
   if (dep[head[u]] > dep[u] - k) {
    k -= dep[u] - dep[head[u]] + 1;
    if (head[u] == 0) return 0;
    u = par[head[u]];
   }
   else {
    return inv[vid[u] - k];
   }
  }
 }


 int lca(int u, int v) {
  while (1) {
   if (vid[u] > vid[v])swap(u, v);
   if (head[u] == head[v])return u;
   v = par[head[v]];
  }
 }


 int distance(int u, int v) {
  return dep[u] + dep[v] - 2 * dep[lca(u, v)];
 }
};

struct Node {
 Node() :val(0) {}
 Node(long long x) :val(x) {}
 long long val;
};
struct Lazy {
 Lazy() :set(0), lazyval(0) {}

 bool set;
 long long lazyval;
};
long long out_range = 0;


typedef long long ll;
struct LazySegTreeP {

 long long N;
 vector<Node> dat;
 vector<Lazy> lazy;

 inline Node merge(Node& a, Node& b) {
  Node node;
  node.val = (a.val + b.val);

  return node;
 }


 void lazy_push(ll k, ll queryL, ll queryR) {
  if (lazy[k].set == 0)return;
  dat[k].val += (queryR - queryL)*lazy[k].lazyval;
  if (k < N - 1) {
   lazy_set(2 * k + 1, lazy[k].lazyval);
   lazy_set(2 * k + 2, lazy[k].lazyval);
  }
  lazy[k].lazyval = 0;
  lazy[k].set = 0;
 }


 inline void lazy_set(ll k, ll val) {
  lazy[k].set = 1;
  lazy[k].lazyval += val;
 }




 inline void fix(ll k) {
  dat[k] = merge(dat[k * 2 + 1], dat[k * 2 + 2]);
 }

 LazySegTreeP(int _N) {
  N = 1;
  while (N < _N)N *= 2;
  dat = vector<Node>(N * 2 - 1);
  lazy = vector<Lazy>(N * 2 - 1);
 }

 LazySegTreeP(vector<long long >& a, int _N) {
  N = 1;
  while (N < _N)N *= 2;
  dat = vector<Node>(N * 2 - 1);
  lazy = vector<Lazy>(N * 2 - 1);
  for (int i = 0; i < _N; ++i)dat[i + N - 1] = (Node{ a[i] });
  build();
 }
 void build() { for (int i = N - 2; i >= 0; i--) dat[i] = merge(dat[2 * i + 1], dat[2 * i + 2]); }

 ~LazySegTreeP() { vector<Node>().swap(dat); vector<Lazy>().swap(lazy); }



 inline void lazy_update(ll queryL, ll queryR, ll val, ll k = 0, ll nodeL = 0, ll nodeR = -1) {
  if (nodeR == -1)nodeR = N;
  lazy_push(k, nodeL, nodeR);


  if (nodeR <= queryL || queryR <= nodeL) { return; }
  if (queryL <= nodeL && nodeR <= queryR) {
   lazy_set(k, val);
   lazy_push(k, nodeL, nodeR);
   return;
  }



  ll nodeM = (nodeL + nodeR) / 2;
  lazy_update(queryL, queryR, val, k * 2 + 1, nodeL, nodeM);
  lazy_update(queryL, queryR, val, k * 2 + 2, nodeM, nodeR);

  fix(k);
  return;
 }


 Node query(ll queryL, ll queryR, ll k, ll nodeL, ll nodeR) {

  lazy_push(k, nodeL, nodeR);

  if (nodeR <= queryL || queryR <= nodeL) { return Node(out_range); }
  if (queryL <= nodeL && nodeR <= queryR) { return dat[k]; }

  ll nodeM = (nodeL + nodeR) / 2;
  Node vl = query(queryL, queryR, k * 2 + 1, nodeL, nodeM);
  Node vr = query(queryL, queryR, k * 2 + 2, nodeM, nodeR);
  return merge(vr, vl);
 }
 inline Node query(int a, int b) {
  return query(a, b, 0, 0, N);
 }
};


int main() {
 cin.tie(0);
 ios_base::sync_with_stdio(false);

 int N, Q;
 cin >> N >> Q;
 HLD hld(N);
 for (int i = 0; i < N - 1; i++) {
  int a, b;
  cin >> a >> b;
  a--, b--;
  hld.add_edge(a, b);
 }
 hld.build();
 LazySegTreeP seg(N);

 for (int q = 0; q < Q; q++) {
  int b, c;
  cin >> b >> c;
  b--;
  {
   seg.lazy_update(hld.ps[b], hld.pt[b], c);
  }
 }

 for (int i = 0; i < N; i++) {
  long long sum = 0;
  hld.for_each_vertex(i, i, [&](int l, int r) {
   sum += seg.query(l, r + 1).val;
  });
  cout << sum << " \n"[i + 1 == N];
 }

 return 0;
}


Measured memory_bytes: 34036