码风较清晰,WA 20pts
#include <bits/stdc++.h>
#define int unsigned int
#define endl '\n'
#define mod 51061
using namespace std;
const int N = 1e5+1;
struct node{
int son[2],fa,siz,val;
int sum;
int mul,add,rev;
}tr[N];
#define ls(x) (tr[x].son[0])
#define rs(x) (tr[x].son[1])
#define fa(x) (tr[x].fa)
inline bool isroot(int x){return !(ls(fa(x))==x || rs(fa(x))==x);}
inline void pushup(int x){
tr[x].siz=tr[ls(x)].siz+tr[rs(x)].siz+1;
tr[x].sum=(tr[ls(x)].sum+tr[rs(x)].sum+tr[x].val)%mod;
}
inline void reverse(int x){swap(ls(x),rs(x));tr[x].rev^=1;}
inline void multiply(int x,int k){
tr[x].sum*=k;tr[x].val*=k;tr[x].add*=k;tr[x].mul*=k;
tr[x].sum%=mod;tr[x].val%=mod;tr[x].add%=mod;tr[x].mul%=mod;
}
inline void pls(int x,int k){
tr[x].sum+=tr[x].siz*k;tr[x].val+=k;tr[x].add+=k;
tr[x].sum%=mod;tr[x].val%=mod;tr[x].add%=mod;
}
void pushdown(int x){
if(tr[x].mul!=1){
if(ls(x))multiply(ls(x),tr[x].mul);
if(rs(x))multiply(rs(x),tr[x].mul);
tr[x].mul=1;
}
if(tr[x].add){
if(ls(x))pls(ls(x),tr[x].add);
if(rs(x))pls(rs(x),tr[x].add);
tr[x].add=0;
}
if(tr[x].rev){
if(ls(x))reverse(ls(x));
if(rs(x))reverse(rs(x));
tr[x].rev=0;
}
}
void pushall(int x){
if(!isroot(x))pushall(fa(x));
pushdown(x);
}
void rotate(int x){
int y=fa(x),z=fa(y);
int k=rs(y)==x;
if(!isroot(y))tr[z].son[rs(z)==y]=x;
fa(x)=z;
tr[y].son[k]=tr[x].son[k^1],fa(tr[x].son[k^1])=y;
tr[x].son[k^1]=y,fa(y)=x;
pushup(y);pushup(x);
}
void splay(int x){
pushall(x);
while(!isroot(x)){
int y=fa(x),z=fa(y);
if(!isroot(y)){
if((rs(z)==y) ^ (rs(y)==x))rotate(x);
else rotate(y);
}
rotate(x);
}
pushup(x);
}
void access(int x){
for(int y=0;x;y=x,x=fa(x)){
splay(x);rs(x)=y;pushup(x);
}
}
void makeroot(int x){
access(x);splay(x);reverse(x);
}
int findroot(int x){
access(x);splay(x);
while(ls(x)){
pushdown(x);
x=ls(x);
}
splay(x);
return x;
}
void link(int x,int y){
makeroot(x);
if(findroot(y)==x)return;
fa(x)=y;
}
void cut(int x,int y){
makeroot(x);
if(findroot(y)!=x || fa(y)!=x || ls(y))return;
fa(y)=rs(x)=0;
}
void split(int x,int y){
makeroot(x);access(y);splay(y);
}
signed main(){
ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
int n,q;
cin>>n>>q;
for(int i=1,x,y;i<n;i++){
cin>>x>>y;
link(x,y);
}
for(int i=1;i<=n;i++){
tr[i].val=tr[i].siz=tr[i].sum=tr[i].mul=1;
}
while(q--){
char ch;
cin>>ch;
if(ch=='+'){
int x,y,c;cin>>x>>y>>c;
split(x,y);pls(y,c);
}
if(ch=='-'){
int x1,y1,x2,y2;cin>>x1>>y1>>x2>>y2;
cut(x1,y1);link(x2,y2);
}
if(ch=='*'){
int x,y,c;cin>>x>>y>>c;
split(x,y);multiply(y,c);
}
if(ch=='/'){
int x,y;cin>>x>>y;
split(x,y);
cout<<tr[y].sum<<endl;
}
}
return 0;
}