#include<bits/stdc++.h>
using namespace std;
typedef long long lint;
const int N=1e5+7;
const lint MOD=51061;
int n,q;
int s[N][2],f[N];
lint sum[N],val[N],add[N],mul[N];int siz[N],rev[N];
#define ls(v) s[v][0]
#define rs(v) s[v][1]
void pushup(int v){sum[v]=(sum[ls(v)]+sum[rs(v)]+val[v])%MOD,siz[v]=siz[ls(v)]+siz[rs(v)]+1;}
void update_add(int v,lint tag){(sum[v]+=tag*siz[v])%=MOD,(val[v]+=tag)%=MOD,(add[v]+=tag)%=MOD;}
void update_mul(int v,lint tag){(sum[v]*=tag)%=MOD,(val[v]*=tag)%=MOD,(add[v]*=tag)%=MOD,(mul[v]*=tag)%=MOD;}
void update_rev(int v,int tag){if(tag)swap(ls(v),rs(v)),rev[v]^=1;}
void pushdown(int v){
if(ls(v))update_rev(ls(v),rev[v]),update_mul(ls(v),mul[v]),update_add(ls(v),add[v]);
if(rs(v))update_rev(rs(v),rev[v]),update_mul(rs(v),mul[v]),update_add(rs(v),add[v]);
add[v]=0,mul[v]=1,rev[v]=0;
}
int get(int v){return rs(f[v])==v;}
int isroot(int v){return ls(f[v])!=v&&rs(f[v])!=v;}
void rotate(int v){
int fv=f[v],ffv=f[fv],c=get(v);
if(!isroot(fv))s[ffv][get(fv)]=v;
if(s[v][!c])f[s[v][!c]]=fv;
s[fv][c]=s[v][!c],f[s[v][!c]=fv]=v,f[v]=ffv;
pushup(fv),pushup(v);
}
void PD(int v){if(!isroot(v))PD(f[v]);pushdown(v);}
void splay(int v){PD(v);while(!isroot(v))rotate(v);}
int access(int v){int p=0;for(;v;p=v,v=f[v])splay(v),rs(v)=p,pushup(v);return p;}
void makeroot(int v){update_rev(access(v),1);}
void link(int u,int v){makeroot(u),f[u]=v;}
void cut(int u,int v){makeroot(u),access(v),splay(v),ls(v)=f[u]=0,pushup(v);}
int split(int u,int v){return makeroot(u),access(v);}
#undef ls
#undef rs
int main(){
int i;
cin>>n>>q;
for(i=1;i<=n;++i)sum[i]=val[i]=mul[i]=1,siz[i]=1;
while(--n){
int u,v;
cin>>u>>v,link(u,v);
}
while(q--){
char op;
cin>>op;
if(op=='+'||op=='*'){
int u,v;lint c;
cin>>u>>v>>c;
if(op=='+')update_add(split(u,v),c);
if(op=='*')update_mul(split(u,v),c);
}
if(op=='/'){
int u,v;
cin>>u>>v,printf("%lld\n",sum[split(u,v)]);
}
if(op=='-'){
int u1,v1,u2,v2;
cin>>u1>>v1>>u2>>v2,cut(u1,v1),link(u2,v2);
}
}
return 0;
}