#include <bits/stdc++.h>
#define int long long
#define ll long long
#define ull unsigned long long
#define min std::min
#define max std::max
#define swap std::swap
namespace IO
{
const int N = 1e6 + 5;
char obuf[N], * p3 = obuf; char ibuf[N], * p1 = ibuf, * p2 = ibuf;
inline void flush() { fwrite(obuf, p3 - obuf, 1, stdout); p3 = obuf; }
inline void putch(char x) { (p3 - obuf < N) ? (*p3++ = x) : (flush(), *p3++ = x); }
inline char getch() { return p1 == p2 && (p2 = (p1 = ibuf) + fread(ibuf, 1, N, stdin), p1 == p2) ? EOF : *p1++; }
inline bool READ(char& p) { p = getch(); while (p == ' ' || p == '\n' || p == -1) { if (p == -1) return true; p = getch(); } return false; }
inline bool READ(char* p) { char ch = getch(); while (ch == ' ' || ch == '\n' || ch == -1) { if (ch == -1) return true; ch = getch(); } while (ch != ' ' && ch != '\n' && ch != -1) { *p++ = ch; ch = getch(); } *p++ = '\0'; return ch == -1; }
inline bool READ(std::string str) { str = ""; char ch = getch(); while (ch == ' ' || ch == '\n' || ch == -1) { if (ch == -1) return true; ch = getch(); } while (ch != ' ' && ch != '\n' && ch != -1) { str += ch; ch = getch(); } return ch == -1; }
inline bool READ(signed& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; if (ch == '-') { if (READ(x)) { x = -x; return true; } x = -x; return false; } ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; } inline bool READ(unsigned& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; }
inline bool READ(short& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; if (ch == '-') { if (READ(x)) { x = -x; return true; } x = -x; return false; } ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; } inline bool READ(unsigned short& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; }
inline bool READ(long long& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; if (ch == '-') { if (READ(x)) { x = -x; return true; } x = -x; return false; } ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; } inline bool READ(unsigned long long& x) { register char ch = getch(); while (ch < '0' || ch > '9') { if (ch == -1) return true; ch = getch(); } x = 0; while (ch <= '9' && ch >= '0') { x = (x << 3) + (x << 1) + (ch ^ 48); ch = getch(); } if (ch == -1) return true; return false; }
inline bool read() { return false; }
template < typename T, typename ... T2 > inline bool read(T& x, T2& ... oth) { if (READ(x)) return true; return read(oth...); }
inline int Read() { register int x = 0; read(x); return x; }
inline void WRITE(char ch) { putch(ch); }
inline void WRITE(char* ch) { register int len = strlen(ch); for (register int i = 0; i < len; i++) putch(ch[i]); }
inline void WRITE(std::string ch) { register int siz = ch.size(); for (register int i = 0; i < siz; i++) putch(ch[i]); }
inline void WRITE(signed x) { if (!x) { putch('0'); return ; } register int len = 0; register signed k1 = x; register char c[50] = {}; if (k1 < 0) k1 = -k1, putch('-'); while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void WRITE(unsigned x) { if (!x) { putch('0'); return ; } register int len = 0; register unsigned k1 = x; register char c[50] = {}; while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void WRITE(short x) { if (!x) { putch('0'); return ; } register int len = 0; register short k1 = x; register char c[50] = {}; if (k1 < 0) k1 = -k1, putch('-'); while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void WRITE(unsigned short x) { if (!x) { putch('0'); return ; } register int len = 0; register unsigned short k1 = x; register char c[50] = {}; while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void WRITE(long long x) { if (!x) { putch('0'); return ; } register int len = 0; register long long k1 = x; register char c[50] = {}; if (k1 < 0) k1 = -k1, putch('-'); while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void WRITE(unsigned long long x) { if (!x) { putch('0'); return ; } register int len = 0; register unsigned long long k1 = x; register char c[50] = {}; while (k1) c[len++] = k1 % 10 ^ 48, k1 /= 10; while (len--) putch(c[len]); }
inline void write() { }
template < typename T, typename ... T2 > inline void write(T x, T2 ... oth) { WRITE(x); write(oth...); }
template < typename T, typename ... T2 > inline void writef(T x, T2 ... oth) { WRITE(x); write(oth...); flush(); }
} using IO::read; using IO::write; using IO::writef; using IO::flush; using IO::putch; using IO::getch; using IO::Read;
using namespace std;
const int N = 1e5 + 5;
const int mod = 51061;
int n, m;
int x, y, k;
int fa[N], son[N][2];
bool tag[N];
int sum[N], value[N], add[N], mult[N], siz[N];
char op[10];
inline void add_tag(int x, int k)
{
(sum[x] += siz[x] * k) %= mod;
(add[x] += k) %= mod;
(value[x] += k) %= mod;
}
inline void mult_tag(int x, int k)
{
(sum[x] *= k) %= mod;
(value[x] *= k) %= mod;
(mult[x] *= k) %= mod;
(add[x] *= k) %= mod;
}
inline void reverse(int x) { tag[x] ^= true, son[x][0] ^= son[x][1] ^= son[x][0] ^= son[x][1]; }
inline void maintain(int x) { sum[x] = (sum[son[x][0]] + sum[son[x][1]] + value[x]) % mod, siz[x] = siz[son[x][0]] + siz[son[x][1]] + 1; }
inline void pushdown(int x)
{
if (tag[x]) reverse(son[x][0]), reverse(son[x][1]), tag[x] = false;
if (mult[x] > 1) mult_tag(son[x][0], mult[x]), mult_tag(son[x][1], mult[x]), mult[x] = 1;
if (add[x]) add_tag(son[x][0], add[x]), add_tag(son[x][1], add[x]), add[x] = 0;
}
inline bool isroot(int x) { return (son[fa[x]][0] != x) && (son[fa[x]][1] != x); }
inline bool get(int x) { return x == son[fa[x]][1]; }
inline void uppushdown(int x) { if (!isroot(x)) uppushdown(fa[x]); pushdown(x); }
inline void rotate(int x)
{
int p = fa[x], q = fa[p]; bool chk = get(x);
if (!isroot(p)) son[q][get(p)] = x; fa[x] = q;
son[p][chk] = son[x][chk ^ 1], fa[son[x][chk ^ 1]] = p;
son[x][chk ^ 1] = p, fa[p] = x;
maintain(p), maintain(x);
}
inline void splay(int x)
{
uppushdown(x);
for (int f = fa[x]; f = fa[x], !isroot(x); rotate(x)) if (!isroot(f)) rotate(get(f) == get(x) ? f : x);
}
inline int access(int x)
{
int s = 0;
for (; x; s = x, x = fa[x])
{
splay(x);
son[x][1] = s;
maintain(x);
}
return s;
}
inline void makeroot(int x)
{
access(x), splay(x), reverse(x);
}
inline void split(int x, int y)
{
makeroot(x), access(y), splay(y);
}
inline void link(int x, int y)
{
makeroot(x), fa[x] = y;
}
inline void cut(int x, int y)
{
split(x, y), son[y][0] = fa[x] = 0, maintain(y);
}
inline void ___()
{
read(n, m);
for (int i = 1; i <= n; i++) sum[i] = value[i] = siz[i] = mult[i] = 1;
for (int i = 1; i < n; i++)
{
read(x, y);
link(x, y);
}
for (int i = 1; i <= m; i++)
{
read(op);
if (op[0] == '-') read(x, y), cut(x, y), read(x, y), link(x, y);
if (op[0] == '+') read(x, y, k), split(x, y), add_tag(y, k);
if (op[0] == '*') read(x, y, k), split(x, y), mult_tag(y, k);
if (op[0] == '/') read(x, y), split(x, y), write(sum[y], '\n');
}
}
signed main()
{
register int _ = 1;
while (_--) ___();
flush();
return ~(0 ^_^ 0);
}
Submissions