WA 15pts
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
inline ll max(ll x, ll y) {return x > y ? x : y;}
inline ll min(ll x, ll y) {return x < y ? x : y;}
inline void swap(int &x, int &y) {x ^= y ^= x ^= y;}
#define rei register int
#define rep(i, l, r) for(rei i = l, i##end = r; i <= i##end; ++i)
#define per(i, r, l) for(rei i = r, i##end = l; i >= i##end; --i)
#define ci const int
char inputbuf[1 << 23], *p1 = inputbuf, *p2 = inputbuf;
#define getchar() (p1 == p2 && (p2 = (p1 = inputbuf) + fread(inputbuf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
inline int read() {
int res = 0; char ch = getchar();
for(; ch < '0' || ch > '9'; ch = getchar())
if(ch == '-' || ch == '+' || ch == '*' || ch == '/')
return ch;
for(; ch >= '0' && ch <= '9'; ch = getchar())
res = res * 10 + (ch ^ 48);
return res;
}
const int N = 1e5 + 5, P = 51061;
int ch[N][2], fa[N], siz[N], n;
bool ft[N];
ll sum[N], val[N], mt[N], at[N];
inline void madd(ll &x, const ll &y) {
x += y;
if(x >= P) x -= P;
}
inline bool isrt(int p) {
return !fa[p] || ch[fa[p]][0] != p && ch[fa[p]][1] != p;
}
inline void update(int p) {
siz[0] = sum[0] = 0;
siz[p] = siz[ch[p][0]] + 1 + siz[ch[p][1]];
sum[p] = (sum[ch[p][0]] + val[p] + sum[ch[p][1]]) % P;
}
inline void flip_tag(int p) {
ft[p] = !ft[p];
swap(ch[p][0], ch[p][1]);
}
inline void add_tag(int p, const ll &x) {
madd(sum[p], x * siz[p] % P);
madd(at[p], x);
madd(val[p], x);
}
inline void mul_tag(int p, const ll &x) {
(sum[p] *= x) %= P;
(at[p] *= x) %= P;
(mt[p] *= x) %= P;
(val[p] *= x) %= P;
}
inline void push_down(int p) {
if(ft[p]) flip_tag(ch[p][0]), flip_tag(ch[p][1]);
if(mt[p] > 1) mul_tag(ch[p][0], mt[p]), mul_tag(ch[p][1], mt[p]);
if(at[p]) add_tag(ch[p][0], at[p]), add_tag(ch[p][1], at[p]);
ft[p] = at[p] = 0;
mt[p] = 1;
}
inline void push_all(int p) {
if(!isrt(p)) push_all(fa[p]);
push_down(p);
}
inline void connect(int f, int p, int c) {
fa[p] = f;
ch[f][c] = p;
}
inline int id(int p) {
return ch[fa[p]][1] == p;
}
inline void rotate(int p) {
int q = fa[p], r = fa[q], cp = id(p), cq = id(q), w = ch[p][cp ^ 1];
fa[p] = r;
if(!isrt(q)) ch[r][cq] = p;
connect(q, w, cp);
connect(p, q, cp ^ 1);
update(q);
update(p);
}
inline void splay(int p) {
push_all(p);
for(; !isrt(p); rotate(p))
if(!isrt(fa[p])) rotate(id(p) == id(fa[p]) ? fa[p] : p);
}
inline void access(int p) {
for(rei q = 0; p; p = fa[p]) {
splay(p);
ch[p][1] = q;
update(p);
q = p;
}
}
inline void mkrt(int p) {
access(p);
splay(p);
flip_tag(p);
}
inline void split(int x, int y) {
mkrt(x);
access(y);
splay(y);
}
inline void link(int x, int y) {
mkrt(x);
fa[x] = y;
}
inline void cut(int x, int y) {
split(x, y);
ch[y][0] = fa[x] = 0;
update(y);
}
signed main() {
int q, opt, x, y, u, v;
n = read(); q = read();
rep(i, 1, n) sum[i] = val[i] = mt[i] = siz[i] = 1;
rep(i, 2, n) {
x = read(); y = read();
link(x, y);
}
for(; q; -- q) {
opt = read();
x = read(); y = read();
if(opt == '-') {
u = read(); v = read();
cut(x, y);
link(u, v);
} else {
split(x, y);
if(opt == '+') add_tag(y, read());
else if(opt == '*') mul_tag(y, read());
else printf("%lld\n", sum[y] % P);
}
}
return 0;
}