#include<bits/stdc++.h>
#define int long long
#define mem(x,y) memset(x,y,sizeof(x))
#define frein freopen("in.in","r",stdin)
#define freout freopen("out.out","w",stdout)
#define debug(x) cout << (#x) << " = " << x << endl;
using namespace std;
int read(){
int s = 0,w = 1;
char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-')w = -1;ch = getchar();}
while(ch >= '0' && ch <= '9')s = s * 10 + ch - '0',ch = getchar();
return s * w;
}
int n,m;
const int mod = 51061;
struct LCT{
struct node{
int fa;
int son[2];
int sum;
int w;
int siz;
}e[1000010];
bool lazy[1000010];
int la1[1000010],la2[1000010];
inline void update(int i){
e[i].sum = (e[e[i].son[0]].sum + e[e[i].son[1]].sum + e[i].w) % mod;
e[i].siz = e[e[i].son[0]].siz + e[e[i].son[1]].siz + 1;
}
inline void pushrev(int i){
swap(e[i].son[0], e[i].son[1]);
lazy[i] ^= 1;
}
inline void pushmul(int i, int d){
e[i].sum = e[i].sum * d % mod;
e[i].w = e[i].w * d % mod;
la1[i] = la1[i] * d % mod;
la2[i] = la2[i] * d % mod;
}
inline void pushadd(int i, int d){
e[i].sum = (e[i].sum + d * e[i].siz) % mod;
e[i].w = (e[i].w + d) % mod;
la2[i] = la2[i] * d % mod;
}
inline void pushdown(int i){
if(lazy[i]){
if (e[i].son[0]) pushrev(e[i].son[0]);
if (e[i].son[1]) pushrev(e[i].son[1]);
lazy[i] = 0;
}
if(la1[i] != 1){
pushmul(e[i].son[0], la1[i]);
pushmul(e[i].son[1], la1[i]);
la1[i] = 1;
}
if(la2[i]){
pushadd(e[i].son[0], la2[i]);
pushadd(e[i].son[1], la2[i]);
la2[i] = 0;
}
}
inline bool get(int i){return e[e[i].fa].son[1] == i;}
inline bool isrt(int i){return e[e[i].fa].son[0] != i && e[e[i].fa].son[1] != i;}
inline void rotate(int x){
int y = e[x].fa,z = e[y].fa,l,r;
int k = l = get(x);
r = l ^ 1;
e[y].son[k] = e[x].son[k ^ 1];
e[e[x].son[k ^ 1]].fa = y;
e[x].son[k ^ 1] = y;
if(!isrt(y))e[z].son[e[z].son[1] == y] = x;
e[x].fa = z;
e[y].fa = x;
update(y),update(x);
}
inline void splay(int x){
stack <int> q;
q.push(x);
for(int i = x;!isrt(i);)q.push(i = e[i].fa);
while(!q.empty()){
int v = q.top();
q.pop();
pushdown(v);
}
while(!isrt(x)){
int y = e[x].fa,z = e[y].fa;
if(!isrt(y)){
if(get(x) == get(y))rotate(y);
else rotate(x);
}
rotate(x);
}
update(x);
}
inline void access(int i){
for(int t = 0;i;t = i,i = e[i].fa){
splay(i);
e[i].son[1] = t;
update(i);
}
}
inline void makert(int i){
access(i);
splay(i);
pushrev(i);
}
inline int find(int i){
access(i);
splay(i);
while(e[i].son[0])i = e[i].son[0];
return i;
}
inline void split(int x,int y){
makert(x);
access(y);
splay(y);
}
inline void cut(int x,int y){
split(x,y);
e[y].son[0] = e[x].fa = 0;
}
inline void link(int x,int y){
makert(x);
e[x].fa = y;
}
}t;
signed main(){
cin>>n>>m;
for(int i = 1;i <= n;i ++)t.e[i].w = t.e[i].sum = t.e[i].siz = t.la1[i] = 1;
for(int i = 1;i <= n - 1;i ++){
int x,y;
x = read(),y = read();
t.link(x,y);
}
while(m --){
char op;
int x,y,xx,yy,w;
scanf(" %c ",&op);
x = read(),y = read();
if(op == '+'){
w = read();
t.split(x,y);
t.pushadd(y, w);
}
else if(op == '-'){
xx = read(),yy = read();
t.cut(x,y);
t.link(xx,yy);
}
else if(op == '*'){
w = read();
t.split(x,y);
t.pushmul(y,w);
}
else {
t.split(x,y);
printf("%lld\n",t.e[y].sum);
}
}
}
如上,全WA