#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #include <vector> using namespace std; #pragma comment(linker,"/STACK:102400000,102400000") const int maxn = 111111; long long ADD1[maxn],ADD2[maxn]; int side,node,wei[maxn],link[maxn],lnode[maxn]; //先转化为有根树 int fa[maxn]; //每个结点的父节点 int w[maxn]; //每个结点的与其父节点的连边在线段树中的位置 int top[maxn]; //每条重链中其首节点; int dep[maxn]; //每个节点的深度; int son[maxn]; //每个节点的重儿子 int siz[maxn]; //vector<int> eson[maxn]; int tot,head[maxn*2]; struct Edge{ int to,next; }edge[maxn*2]; void addedge(int u,int v){ edge[tot].to = v;edge[tot].next = head[u];head[u] = tot++; } void init_dfs(int u){ siz[u]=1; son[u]=0; for(int i = head[u];i != -1; i = edge[i].next)if(edge[i].to!=fa[u]){ int v=edge[i].to; fa[v]=u; dep[v]=dep[u]+1; init_dfs(v); if(siz[son[u]]< siz[v]) son[u]=v; siz[u]+=siz[v]; } } void build_tree(int u,int tp){ w[u]=side++; top[u]=tp; wei[u]=node++; if(son[u]!=0) { build_tree(son[u],tp); } for(int i = head[u];i != -1; i = edge[i].next)if(edge[i].to!=fa[u]&&edge[i].to!=son[u]){ build_tree(edge[i].to,edge[i].to); } } void init(int n){ for(int i=0;i<=n;i++) ADD1[i]=ADD2[i]=0; fa[1]=1; dep[1]=0; top[1]=1; init_dfs(1); side=0; node=1; build_tree(1,1); } int ql,qr,addv; int find(int u,int v){ int f1=top[u],f2=top[v]; int res=0; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } ql=w[f1]; qr=w[u]+1; ADD2[ql]+=addv; ADD2[qr]-=addv; u=fa[f1]; f1=top[u]; } if(u==v) return res; if(dep[u]<dep[v]) swap(u,v); ql=w[son[v]]; qr=w[u]+1; ADD2[ql]+=addv; ADD2[qr]-=addv; } void find_node(int u,int v){ int f1=top[u],f2=top[v]; int res=0; while(f1!=f2){ if(dep[f1]<dep[f2]){ swap(f1,f2); swap(u,v); } ql=wei[f1]; qr=wei[u]+1; ADD1[ql]+=addv; ADD1[qr]-=addv; u=fa[f1]; f1=top[u]; } if(dep[u]<dep[v]) swap(u,v); ql=wei[v]; qr=wei[u]+1; ADD1[ql]+=addv; ADD1[qr]-=addv; } template <class T> inline bool scan_d(T &ret) { char c; int sgn; if(c=getchar(),c==EOF) return 0; //EOF while(c!='-'&&(c<'0'||c>'9')) c=getchar(); sgn=(c=='-')?-1:1; ret=(c=='-')?0:(c-'0'); while(c=getchar(),c>='0'&&c<='9') ret=ret*10+(c-'0'); ret*=sgn; return 1; } inline void out(long long x) { if(x>9) out(x/10); putchar(x%10+'0'); } int d[maxn][3]; int main() { int T; int n,kase=1; scanf("%d",&T); while(T--){ int Q; scan_d(n); scan_d(Q); int x,y,z; tot=0; memset(head,-1,sizeof(head)); for(int i=1;i<n;i++){ scan_d(x); scan_d(y); d[i][0]=x; d[i][1]=y; d[i][2]=0; addedge(d[i][0],d[i][1]); addedge(d[i][1],d[i][0]); } init(n); for(int i=1;i<n;i++){ if(dep[d[i][0]]>dep[d[i][1]]) swap(d[i][0],d[i][1]); } char cmd[100]; while(Q--){ int u,v; scanf("%s",cmd); scan_d(u); scan_d(v); scan_d(addv); if(cmd[3]=='1'){ find_node(u,v); } else find(u,v); } for(int i=1;i<=n;i++){ ADD1[i]+=ADD1[i-1]; ADD2[i]+=ADD2[i-1]; } printf("Case #%d:\n",kase++); for(int i=1;i<=n;i++){ if(i!=1) printf(" "); out(ADD1[wei[i]]); } printf("\n"); for(int i=1;i<n;i++){ if(i!=1) printf(" "); out(ADD2[w[d[i][1]]]); } printf("\n"); } return 0; }