#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;

#define LL long long
#define N 1000010

struct Edge {
    int to,from;
}e[N*2+10];
struct Tree {
    int sum,tag;
    int lson,rson;
}tree[N*2];

int deep[N],Top[N],idx[N],siz[N];
int n,m,p,root,son[N],tot = 1,cnt;
int head[N],fa[N],val[N],w[N],t;

inline void add_edge(int x,int y) {
    e[++cnt].from = y;
    e[cnt].to = head[x];
    head[x] = cnt;
}
inline void pushup(int x) {
    tree[x].sum = (tree[tree[x].lson].sum + tree[tree[x].rson].sum);
}
void pushdown(int x,int l,int r) {
    int mid = (l + r) >> 1;
    tree[tree[x].lson].sum = (tree[tree[x].lson].sum + tree[x].tag * (mid - l + 1));
    tree[tree[x].rson].sum = (tree[tree[x].rson].sum + tree[x].tag * (r - mid));
    tree[tree[x].lson].tag = (tree[tree[x].lson].tag + tree[x].tag);
    tree[tree[x].rson].tag = (tree[tree[x].rson].tag + tree[x].tag);
    tree[x].tag = 0;
}
void build(int x,int l,int r) {
    if(l == r) {
        tree[x].sum = w[l];
        return;
    }
    int mid = (l + r) >> 1;
    tree[x].lson = ++tot;
    build(tree[x].lson,l,mid);
    tree[x].rson = ++tot;
    build(tree[x].rson,mid+1,r);
    pushup(x);
}
void update(int x,int l,int r,int ll,int rr,int v) {
    if(l == ll && r == rr) {
        tree[x].sum = (tree[x].sum + (r - l + 1) * v);
        tree[x].tag = (tree[x].tag + v);
        return;
    }
    int mid = (l + r) >> 1;
    pushdown(x,l,r);
    if(rr <= mid) update(tree[x].lson,l,mid,ll,rr,v);
    else if(ll > mid) update(tree[x].rson,mid+1,r,ll,rr,v);
    else {
        update(tree[x].lson,l,mid,ll,mid,v);
        update(tree[x].rson,mid+1,r,mid+1,rr,v);
    }
    pushup(x);
}
inline int query(int x,int l,int r,int ll,int rr) {
    if(l == ll && r == rr) return tree[x].sum;
    int mid = (l + r) >> 1;
    pushdown(x,l,r);
    if(rr <= mid) return query(tree[x].lson,l,mid,ll,rr);
    else if(ll > mid) return query(tree[x].rson,mid + 1,r,ll,rr);
    else return (query(tree[x].lson,l,mid,ll,mid) + query(tree[x].rson,mid + 1,r,mid + 1,rr));
}
void dfs1(int x,int f,int depth) {
    fa[x] = f;
    siz[x] = 1;
    deep[x] = depth;
    int maxs = -1;
    for(int i = head[x] ; i ; i = e[i].to) {
        int u = e[i].from;
        if(u == f) continue;
        dfs1(u,x,depth + 1);
        siz[x] += siz[u];
        if(siz[u] > maxs) {
            son[x] = u;
            maxs = siz[u];
        }
    }
}
void dfs2(int x,int topf) {
    idx[x] = ++t;
    w[t] = val[x];
    Top[x] = topf;
    if(!son[x]) return;
    dfs2(son[x],topf);
    for(int i = head[x] ; i ; i = e[i].to) {
        int u = e[i].from;
        if(u == son[x] || u == fa[x]) continue;
        dfs2(u,u);
    }
}
inline int query_link(int x,int y) {
    int ans = 0;
    while(Top[x] != Top[y]) {
        if(deep[Top[x]] < deep[Top[y]]) swap(x,y);
        ans += query(1,1,n,idx[Top[x]],idx[x]);
        ans %= p;
        x = fa[Top[x]];
    }
    if(deep[x] > deep[y]) swap(x,y);
    ans = (ans + query(1,1,n,idx[x],idx[y]));
    return ans;
}
inline void update_link(int x,int y,int val) {
    while(Top[x] != Top[y]) {
        if(deep[Top[x]] < deep[Top[y]])	 swap(x,y);
        update(1,1,n,idx[Top[x]],idx[x],val);
        x = fa[Top[x]];
    }
    if(deep[x] > deep[y]) swap(x,y);
    update(1,1,n,idx[x],idx[y],val);
}
inline int query_tree(int x) {
    return query(1,1,n,idx[x],idx[x] + siz[x] - 1);	
}
inline void update_tree(int x,int val) {
    update(1,1,n,idx[x],idx[x] + siz[x] - 1,val);	
}

int main() {
    scanf("%d%d",&n,&m);
    for(int i = 1 ; i < n ; i++) {
        int a,b;
        scanf("%d%d",&a,&b);
        add_edge(a,b);
        add_edge(b,a);
    }
    dfs1(1,0,1);
    dfs2(1,1);
    build(1,1,n);
    while(m--) {
        int x,z;
        scanf("%d%d",&x,&z);
        update_tree(x,z);
    }
    for(int i = 1 ; i <= n ; i++)
        printf("%d ",query_link(i,i));
    //system("pause");
    return 0;
}

Measured memory_bytes: 51584