#include <algorithm>/*{{{*/ #include <cassert> #include <cctype> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <iostream> #include <map> #include <queue> #include <set> #include <vector> using namespace std; typedef long long lld; typedef long double lf; typedef unsigned long long uld; typedef pair<int, int> pii; #define fi first #define se second #define pb push_back #define mk make_pair #define FOR(i, a, b) for (int i = (a); i <= (b); ++i) #define ROF(i, a, b) for (int i = (a); i >= (b); --i) namespace RA { int r(int p) { return 1ll * rand() * rand() % p; } int r(int L, int R) { return r(R - L + 1) + L; } } // namespace RA namespace IO { char nc() { static char bf[100000], *p1 = bf, *p2 = bf; return p1 == p2 && (p2 = (p1 = bf) + fread(bf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } int rd() { int res = 0; char c = getchar(); while (!isdigit(c)) c = getchar(); while (isdigit(c)) res = res * 10 + c - '0', c = getchar(); return res; } } // namespace IO /******************heading******************/ const int SZ = 1e5 + 50, P = 51061; int n, q; int tot, ch[SZ][2], f[SZ], rv[SZ]; int val[SZ], s[SZ], sz[SZ], tadd[SZ], tmul[SZ]; void print() { puts("-------------------------------------"); FOR(u, 1, n) printf("u=%d,lc=%d,rc=%d,f=%d,sz=%d, s=%d,tmul=%d,tadd=%d\n", u, ch[u][0], ch[u][1], f[u], sz[u], s[u], tmul[u], tadd[u]); puts("-------------------------------------"); } int newnode(int v) { ++tot, ch[tot][0] = ch[tot][1] = f[tot] = rv[tot] = 0; val[tot] = s[tot] = v, tmul[tot] = 1, tadd[tot] = 0, sz[tot] = 1; return tot; } void pushup(int u) { s[u] = (s[ch[u][0]] + s[ch[u][1]] + val[u]) % P; sz[u] = sz[ch[u][0]] + sz[ch[u][1]] + 1; } void nodeadd(int u, int v) { s[u] = (s[u] + 1ll * sz[u] * v) % P, (val[u] += v) %= P, (tadd[u] += v) %= P; } void nodemul(int u, int v) { s[u] = 1ll * s[u] * v % P, val[u] = 1ll * val[u] * v % P, tmul[u] = 1ll * tmul[u] * v % P, tadd[u] = 1ll * tadd[u] * v % P; } void pushdown(int u) { if (rv[u]) swap(ch[u][0], ch[u][1]), rv[ch[u][0]] ^= 1, rv[ch[u][1]] ^= 1, rv[u] = 0; if (tmul[u] != 1) nodemul(ch[u][0], tmul[u]), nodemul(ch[u][1], tmul[u]), tmul[u] = 1; if (tadd[u]) nodeadd(ch[u][0], tadd[u]), nodeadd(ch[u][1], tadd[u]), tadd[u] = 0; } bool isroot(int u) { return ch[f[u]][0] != u && ch[f[u]][1] != u; } bool get(int u) { return ch[f[u]][1] == u; } void rotate(int u) { int y = f[u], z = f[y], k; pushdown(y), pushdown(u), k = get(u); if (!isroot(y)) ch[z][get(y)] = u; ch[y][k] = ch[u][!k], f[ch[u][!k]] = y; ch[u][!k] = y, f[y] = u, f[u] = z; pushup(y), pushup(u); } void splay(int u) { pushdown(u); for (int p; p = f[u], !isroot(u); rotate(u)) if (!isroot(p)) rotate(get(p) == get(u) ? p : u); } void access(int u) { for (int p = 0; u; p = u, u = f[u]) splay(u), ch[u][1] = p, pushup(u); } void makeroot(int u) { access(u); splay(u); rv[u] ^= 1; } void link(int u, int v) { makeroot(u), f[u] = v; } void cut(int u, int v) { makeroot(u), access(v), splay(v), ch[v][0] = f[u] = 0, pushup(v); } void add(int u, int v, int c) { makeroot(u), access(v), splay(v); nodeadd(v, c); } void mul(int u, int v, int c) { makeroot(u), access(v), splay(v); nodemul(v, c); } int sum(int u, int v) { makeroot(u), access(v), splay(v); return s[v]; } int main() { scanf("%d%d", &n, &q); FOR(i, 1, n) newnode(1); // index 1 to n FOR(i, 1, n - 1) { int u, v; scanf("%d%d", &u, &v); link(u, v); } FOR(i, 1, q) { char op[5]; int u, v, x, y, c; scanf("%s", op); if (op[0] == '+') { scanf("%d%d%d", &u, &v, &c); add(u, v, c); } else if (op[0] == '-') { scanf("%d%d%d%d", &u, &v, &x, &y); cut(u, v), link(x, y); } else if (op[0] == '*') { scanf("%d%d%d", &u, &v, &c); mul(u, v, c); } else { scanf("%d%d", &u, &v); printf("%d\n", sum(u, v)); } } return 0; }