#include<cstdio>
#define Rint register int
using namespace std;
typedef long long LL;
const int N = 100003, mod = 51061;
int sta[N], top;
namespace LCT {
void swap(int &a, int &b){a ^= b ^= a ^= b;}
struct Node {
int v, fa, siz, ch[2], sum, add, mul;
bool rev;
} e[N];
void pushup(int x){
e[x].sum = (e[e[x].ch[0]].sum + e[e[x].ch[1]].sum + e[x].v) % mod;
e[x].siz = e[e[x].ch[0]].siz + e[e[x].ch[1]].siz + 1;
}
void pushrev(int x){
e[x].rev ^= 1;
swap(e[x].ch[0], e[x].ch[1]);
}
void pushtag(int x, int add, int mul){
if(!x) return;
e[x].sum = ((LL) e[x].sum * mul + (LL) add * e[x].siz) % mod;
e[x].add = ((LL) e[x].add * mul + add) % mod;
e[x].v = ((LL) e[x].v * mul + add) % mod;
e[x].mul = (LL) e[x].mul * mul % mod;
}
void pushdown(int x){
if(e[x].rev){
e[x].rev = false;
if(e[x].ch[0]) pushrev(e[x].ch[0]);
if(e[x].ch[1]) pushrev(e[x].ch[1]);
}
pushtag(e[x].ch[0], e[x].add, e[x].mul);
pushtag(e[x].ch[1], e[x].add, e[x].mul);
e[x].add = 0; e[x].mul = 1;
}
bool nroot(int x){
return e[e[x].fa].ch[0] == x || e[e[x].fa].ch[1] == x;
}
void rotate(int x){
int y = e[x].fa, z = e[y].fa, zson = e[z].ch[1] == y, yson = e[y].ch[1] == x, B = e[x].ch[yson ^ 1];
if(nroot(y)) e[z].ch[zson] = x;
e[x].ch[yson ^ 1] = y;
e[y].ch[yson] = B;
if(B) e[B].fa = y;
e[y].fa = x;
e[x].fa = z;
pushup(y);
}
void splay(int x){
int now = x;
sta[++ top] = x;
while(nroot(now)) sta[++ top] = now = e[now].fa;
while(top) pushdown(sta[top --]);
while(nroot(x)){
int y = e[x].fa, z = e[y].fa;
if(nroot(y))
rotate((e[z].ch[1] == y) ^ (e[y].ch[1] == x) ? x : y);
rotate(x);
}
pushup(x);
}
void access(int x){
for(Rint y = 0;x;y = x, x = e[x].fa){
splay(x); e[x].ch[1] = y; pushup(x);
}
}
void makeroot(int x){
access(x); splay(x); pushrev(x);
}
int findroot(int x){
access(x); splay(x);
while(e[x].ch[0]) {pushdown(x); x = e[x].ch[0];}
return x;
}
void split(int x, int y){
makeroot(x); access(y); splay(y);
}
void link(int x, int y){
makeroot(x);
e[x].fa = y;
}
void cut(int x, int y){
makeroot(x);
if(findroot(y) == x && e[x].fa == y && !e[x].ch[1]){
e[x].fa = e[y].ch[0] = 0;
pushup(y);
}
}
}
using namespace LCT;
int n, q;
int main(){
scanf("%d%d", &n, &q);
for(Rint i = 1;i <= n;i ++)
e[i].v = e[i].sum = e[i].mul = 1;
for(Rint i = 1;i < n;i ++){
int a, b;
scanf("%d%d", &a, &b);
link(a, b);
}
while(q --){
char opt[5];
scanf("%s", opt);
int a, b, c, d;
switch(opt[0]){
case '+':
scanf("%d%d%d", &a, &b, &c);
split(a, b);
pushtag(b, c, 1);
break;
case '-':
scanf("%d%d%d%d", &a, &b, &c, &d);
cut(a, b); link(c, d);
break;
case '*':
scanf("%d%d%d", &a, &b, &c);
split(a, b);
pushtag(b, 0, c);
break;
case '/':
scanf("%d%d", &a, &b);
split(a, b);
printf("%d\n", e[b].sum);
}
}
}