#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;
}