#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <bitset>
#include <array>
#include <vector>
#include <queue>
#include <set>
#include <cmath> // 変数名にy1が使えなくなるかも…。
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <limits>
#include <functional>
#include <string>

typedef __int128_t int128_t;
std::istream &operator>>(std::istream& input, int128_t& value) { // int128_tの入力。入力が64bitに収まる前提。
    int64_t tmp; input >> tmp; value = tmp;
    return input;
}
std::ostream &operator<<(std::ostream& output, const int128_t value) { // int128_tの出力。出力が64bitに収まる前提。
    output << (int64_t)value;
    return output;
}

namespace std {
    template<> class hash<int128_t>{
        public:
        size_t operator () ( const int128_t &x ) const {
            int64_t INF64 = std::numeric_limits<int64_t>::max();
            int64_t y1 = x / INF64;
            int64_t y2 = x % INF64;
            return hash<int64_t>()(y1) ^ hash<int64_t>()(y2);
        }
    };
}

int128_t imax(const int128_t a, const int128_t b) { return std::max(a, b); } // std::max, std::min は型が違うとエラーになるため、ラッパーを作る。
int128_t imin(const int128_t a, const int128_t b) { return std::min(a, b); }

#define rep(i, begin, end) for(int64_t i = ((int64_t)begin); i <= ((int64_t)end); i++) // (int64_t)end としておくと、end = v.size() - 2 みたいな入力で、v.size()が1でも正常(end = -1になる）に挙動する。
#define rev(i, begin, end) for(int64_t i = ((int64_t)begin); ((int64_t)end) <= i; i--)

#define input1(begin, end, v1) v1.resize((end)+1); for (int i = (begin); i <= (end); i++) { std::cin >> v1[i]; }
#define input2(begin, end, v1, v2) v1.resize((end)+1); v2.resize((end)+1); for (int i = (begin); i <= (end); i++) { std::cin >> v1[i] >> v2[i]; } 
#define input3(begin, end, v1, v2, v3) v1.resize((end)+1); v2.resize((end)+1); v3.resize((end)+1); for (int i = (begin); i <= (end); i++) { std::cin >> v1[i] >> v2[i] >> v3[i]; }
#define input4(begin, end, v1, v2, v3, v4) v1.resize((end)+1); v2.resize((end)+1); v3.resize((end)+1); v4.resize((end)+1); for (int i = (begin); i <= (end); i++) { std::cin >> v1[i] >> v2[i] >> v3[i] >> v4[i]; } 
// input_arrayはbegin = 0のときのみ動作確認。Aの要素の型をテンプレートにして関数にしたほうが丁寧かもしれない。
#define input_array(begin, N, M, A) A.resize((begin)+(N)); for (int i = 0; i < (begin)+(N); i++) { A[i].resize((begin)+(M)); } for (int i = begin; i < (begin)+(N); i++) { for (int j = begin; j < (begin)+(M); j++) { std::cin >> A[i][j]; }}

std::vector<int> irange(const int begin, const int end) {
    std::vector<int> ret; for (int i = begin; i <= end; i++) { ret.push_back(i); }
    return ret;
}

template <typename T>
void printvec(const std::vector<T>& vec) {
    for (int i = 0; i < vec.size(); i++) { std::cout << vec[i] << " "; } std::cout << std::endl;
}

// 木のクラス。
// 有向グラフと同様に表現する。
// （Tipsに含まれている関数で、こちらに移植していないものがあるので注意。get_children, calc_diameter）
class Tree_New {
    public:
    struct Edge { 
        int to; int64_t cost;
    };
    typedef std::vector<std::vector<Edge>> adj_list;
    adj_list G;
    int node_num;
    Tree_New() {}
    Tree_New(const int node_num_in) {
        node_num = node_num_in;
        G.resize(node_num);
    }
    void add_directed_edge(const int from, const int to, const long long cost) {
        Edge edge; edge.to = to; edge.cost = cost;
        G[from].push_back(edge);
    }
    void add_undirected_edge(const int node1, const int node2, const long long cost) {
        add_directed_edge(node1, node2, cost);
        add_directed_edge(node2, node1, cost);
    }
    std::vector<int> cal_rank(const int root) { // root を根としたときのrankを計算する。
        assert(root < node_num);
        std::vector<int> rank; rank.resize(node_num, -1);
        std::function<void(int, int, int)> dfs = [&] (int n, int r, int parent) {
            rank[n] = r;
            for (Edge e : G[n]) {
                if (e.to != parent) {
                    dfs(e.to, r + 1, n);
                }
            }
        };
        dfs(root, 0, -1);
        return rank;
    }
    std::vector<int> rank_descending_ids(const int root, const int begin, const int end) { // root を根としたときに、rankの降順にノード番号を並べる。
        assert(begin <= root && root <= end);
        assert(end < node_num);
        std::vector<int> rank = cal_rank(root);
        std::vector<int> ret;
        for (int i = begin; i <= end; i++) {
            ret.push_back(i);
        }
        std::sort(ret.begin(), ret.end(), [&](const int i, const int j) {
            return rank[i] > rank[j];
        });
        return ret;
    }
    std::vector<int> cal_partial_size(const int root) {
        // root を根としたとして各頂点を根とした部分木のサイズを求める。
        assert(root < node_num);
        std::vector<int> ret; ret.resize(node_num, 0);
        std::function<void(int, int)> dfs = [&] (int n, int parent) {
            for (Edge e : G[n]) {
                if (e.to != parent) {
                    dfs(e.to, n);
                    ret[n] += ret[e.to];
                }
            }
            ret[n] += 1;
        };
        dfs(root, -1);
        return ret;
    }

    std::vector<int> cal_parent(const int root) { // root を根としたときの親を計算する。有向木では行うまでもない。rootの親はrootとしておく。
        assert(root < node_num);
        std::vector<int> ret; ret.resize(node_num, -1);
        std::function<void(int, int)> dfs = [&] (int n, int p) {
            ret[n] = p;
            for (Edge e : G[n]) {
                if (e.to != p) {
                    dfs(e.to, n);
                }
            }
        };
        dfs(root, root);
        return ret;
    }
    std::vector<std::vector<int>> cal_parent_doubling(const int root) {
        // parentのダブリング構築。ret[i][n]は、nから2^iだけ親の方へ進んだ節点になる。
        std::vector<std::vector<int>> ret;
        std::vector<int> parent = cal_parent(root);
        ret.push_back(parent);
        while (true) {
            std::vector<int> pd; pd.resize(node_num);
            bool end_flag = true;
            for (int i = 0; i < node_num; i++) {
                if (ret.back()[i] == root || ret.back()[i] == -1) {
                    pd[i] = ret.back()[i];
                } else {
                    pd[i] = ret.back()[ret.back()[i]];
                    if (pd[i] != root) { 
                        end_flag = false;
                    }
                }
            }
            ret.push_back(pd);
            if (end_flag) { break; }
        }
        return ret;
    }
    int cal_ancestor(int node, int num, const std::vector<std::vector<int>>& parent_doubling) {
        // parent_doublingを利用して、nodeからnumだけ根の方向に進んだノードを求める。
        for (int i = 0; 0 < num; i++) {
            if (num % 2 == 1) {
                node = parent_doubling[i][node];
            }
            num /= 2;
        }
        return node;
    }
    int lca(int u, int v, const std::vector<int>& rank, const std::vector<std::vector<int>>& parent_doubling) {
        // rank と parent_doublingから、least common ancestorを計算。
        if (rank[u] < rank[v]) {
            v = cal_ancestor(v, rank[v] - rank[u], parent_doubling);
        } else {
            u = cal_ancestor(u, rank[u] - rank[v], parent_doubling);
        }
        assert(rank[v] == rank[u]);
        if (u == v) { return u; }
        int lb = 0; int ub = rank[u];
        while (lb + 1 < ub) {
            int mid = (lb + ub) / 2;
            if (cal_ancestor(u, mid, parent_doubling) == cal_ancestor(v, mid, parent_doubling)) {
                ub = mid;
            } else {
                lb = mid;
            }
        }
        return cal_ancestor(u, ub, parent_doubling);
    }

    void dfs_in_order_child(int n, int parent, std::vector<std::pair<int, int>>& order) {
        order.push_back({parent, n});
        for (Edge e : G[n]) {
            if (e.to != parent) {
                dfs_in_order_child(e.to, n, order);
            }
        }
        order.push_back({n, parent});
    } 
    std::vector<std::pair<int, int>> dfs_in_order(const int root) { 
        // root を根としたdfsで、通りがけ順に辺を並べる。オイラーツアーというらしい。
        // 全ての辺が、子に向かう方向と根に向かう方向でそれぞれ1度カウントされるので、サイズは(N-1)*2となる。
        assert(root < node_num);
        std::vector<std::pair<int, int>> order;
        for (Edge e : G[root]) {
            dfs_in_order_child(e.to, root, order);
        }
        return order;
    }
};


//--code begin--

int128_t N, Q;
std::vector<int128_t> a, b, p, x;
//std::string ;
//std::vector<std::string> ;
//double ;
//std::vector<double> ;

const int128_t MAX_N = 2e5 + 10;
//const int128_t MOD = ;
//const int128_t INF = std::numeric_limits<int64_t>::max();
//using pair = std::pair<int64_t, int>;

Tree_New tree(MAX_N);
int128_t ret[MAX_N] = {};
int128_t sum[MAX_N] = {};

void dfs(int128_t node, int128_t parent_sum) {
    ret[node] = parent_sum + sum[node];
    for (auto e : tree.G[node]) {
        dfs(e.to, ret[node]);
    }
}

int main(int argc, char **argv) {
    std::cin >> N >> Q;

    input2(1, N - 1, a, b);
    input2(1, Q, p, x);

    rep (i, 1, N - 1) {
        tree.add_directed_edge(a[i], b[i], 1);
    }

    rep (i, 1, Q) {
        sum[p[i]] += x[i]; 
    }

    dfs(1, 0);

    rep (i, 1, N) {
        std::cout << ret[i] << " ";
    }
    std::cout << std::endl;


    return 0;
}

Measured memory_bytes: 38144