#include <bits/stdc++.h>
#define rep(i, n) for(int i = 0; i < n; i++)
#define all(a) a.begin(), a.end()
template <class T>
inline bool chmax(T& a, T b) {
    if(a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
    if(a > b) {
        a = b;
        return 1;
    }
    return 0;
}
using namespace std;

struct UnionFind {  //素集合データ構造
   private:
    vector<int> par;

   public:
    UnionFind(int n) : par(n, -1) {}
    int find(int x) {
        if(par.at(x) < 0)
            return x;
        else
            return par.at(x) = find(par.at(x));
    }
    void unite(int x, int y) {
        x = find(x);
        y = find(y);
        if(x == y) return;
        if(size(x) < size(y)) swap(x, y);
        par.at(x) += par.at(y);
        par.at(y) = x;
    }
    int size(int x) { return -par.at(find(x)); }
    bool same(int x, int y) { return find(x) == find(y); }
    void reset(int n) { par = vector<int>(n, -1); }
};

struct RootedTree {  //根付き木
    struct Edge {    //根付き木の辺、属性を追加可能
        int from, to;
        Edge() {}
        Edge(int from, int to) : from(from), to(to) {}
    };

   private:
    int n, root, l;
    vector<int> depth;
    vector<vector<int>> par;
    vector<vector<Edge>> graph;

   public:
    RootedTree(int n) : n(n), depth(n), graph(n) {
        l = 0;
        while((1 << l) < n) l++;
        par = vector<vector<int>>(l, vector<int>(n + 1, n));
    }
    void addEdge(int from, int to, bool directed) {
        Edge e(from, to);
        graph[e.from].push_back(e);
        if(!directed) {
            swap(e.from, e.to);
            graph[e.from].push_back(e);
        }
    }
    void dfs(int v, int p = -1, int d = 0) {
        if(p != -1) par[0][v] = p;
        depth[v] = d;
        for(Edge e : graph[v]) {
            if(e.to == p) continue;
            dfs(e.to, v, d + 1);
        }
    }
    void init(int r = 0) {
        root = r;
        dfs(root);
        rep(i, l - 1) rep(j, n) par[i + 1][j] = par[i][par[i][j]];
    }
    int parent(int v) { return par[0][v]; }
    int lca(int x, int y) {
        if(depth[x] > depth[y]) swap(x, y);
        int dif = depth[y] - depth[x];
        for(int i = l - 1; i >= 0; i--) {
            if(dif & (1 << i)) {
                y = par[i][y];
            }
        }
        if(x == y) return x;
        for(int i = l - 1; i >= 0; i--) {
            int nx = par[i][x], ny = par[i][y];
            if(nx != ny) {
                x = nx;
                y = ny;
            }
        }
        return par[0][x];
    }
    int depdif(int x, int y) {
        int z = lca(x, y);
        return depth[x] + depth[y] - 2 * depth[z];
    }
    vector<Edge> operator[](int i) {  //[]でアクセス
        return graph[i];
    }
};

int main() {
    int N, Q;
    cin >> N >> Q;
    RootedTree G(N);
    rep(i, N - 1) {
        int a, b;
        cin >> a >> b;
        G.addEdge(a - 1, b - 1, false);
    }
    G.init();
    // rep(i, N) { cout << G.parent(i) << endl; }
    vector<int> ans(N + 1, 0);
    while(Q--) {
        int p, x;
        cin >> p >> x;
        ans[p - 1] += x;
    }
    stack<int> q;
    q.push(0);
    while(!q.empty()) {
        int i = q.top();
        q.pop();
        for(auto e : G[i]) {
            if(e.to != G.parent(i)) {
                ans[e.to] += ans[i];
                q.push(e.to);
            }
        }
    }
    rep(i, N) cout << ans[i] << (i == N - 1 ? "\n" : " ");
}

Measured memory_bytes: 34928