#include <cmath>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <map>
#include <fstream>
#include <iostream>

#define rep(i, l, r) for(int i = l; i <= r; i++)
#define down(i, l, r) for(int i = l; i >= r; i--)
#define MS 123456
#define MAX 1037471823
#define Q 51061

using namespace std;

struct node { node *ch[2], *h; bool rec; unsigned int sum, k, a, c, s, n;
inline bool d();
inline bool Root();
inline void Cal();
inline void Down();
} t[MS];

inline bool node::d() { return h->ch[1]==this; }

inline bool node::Root() { return (h==NULL) || (h->ch[1]!=this && h->ch[0]!=this); }

inline void node::Down() 
{
	if (!this) return;
	if (rec) 
	{
		if (ch[0]) ch[0]->rec^=1;
		if (ch[1]) ch[1]->rec^=1;
		swap(ch[0], ch[1]); rec=0;
	}
	k=(k*c+a)%Q; 
	if (ch[0]) ch[0]->c=(ch[0]->c*c)%Q, ch[0]->a=(ch[0]->a*c+a)%Q;
	if (ch[1]) ch[1]->c=(ch[1]->c*c)%Q, ch[1]->a=(ch[1]->a*c+a)%Q;
	a=0, c=1; ch[0]->Cal(); ch[1]->Cal(); Cal();
}

inline void node::Cal()
{
	if (!this) return; 
	s=1; if (ch[0]) s+=ch[0]->s; if (ch[1]) s+=ch[1]->s;
	sum=k; if (ch[0]) sum+=ch[0]->sum; if (ch[1]) sum+=ch[1]->sum; sum=((sum%Q*c)%Q+(s%Q*a)%Q)%Q;
}

inline void Rotate(node *x) 
{
	node *o=x->h; o->Down(); x->Down();
	bool d=x->d();
	if (!o->Root()) o->h->ch[o->d()]=x;
	x->h=o->h;
	if (x->ch[d^1]) x->ch[d^1]->h=o;
	o->ch[d]=x->ch[d^1];
	x->ch[d^1]=o;
	o->h=x;
	o->Cal(); x->Cal();
}

inline void Splay(node *x) 
{
	x->Down();
	while (!x->Root())
	{
		if (x->h->Root()) Rotate(x);
		else if (x->d()!=x->h->d()) Rotate(x), Rotate(x);
		else Rotate(x->h), Rotate(x);
	}
	x->Cal();
}

inline node* Acc(node *x) 
{
	node *o;
	for (o=NULL; x; o=x, x=x->h)
		{ Splay(x); x->ch[1]=o; x->Cal(); }
	return o;
}
inline void Evert(node *x) { Acc(x)->rec^=1; Splay(x); }
inline void Link(node *x, node *y) { Evert(x); x->h=y; Acc(x); }
inline void Cut(node *x, node *y) { Evert(x); Acc(y); Splay(y); y->ch[0]=x->h=NULL; y->Cal(); x->Cal(); }
inline void Add(node *x, node *y, int z) { Evert(x); Acc(y); Splay(y); y->a=(y->a+z)%Q; y->Cal(); }
inline void Mult(node *x, node *y, int z) { Evert(x); Acc(y); Splay(y);  y->c=(y->c*z)%Q; y->Cal(); }
inline void QSum(node *x, node *y) { Evert(x); Acc(y); Splay(y); printf("%d\n", y->sum); }

int n, m, x, y, z;
char q[10];

int main()
{
	scanf("%d%d", &n, &m);
	rep(i, 1, n) t[i].rec=false, t[i].h=t[i].ch[0]=t[i].ch[1]=NULL, t[i].sum=t[i].k=t[i].c=t[i].s=1, t[i].a=0, t[i].n=i;
	rep(i, 1, n-1) { scanf("%d%d", &x, &y); Link(&t[x], &t[y]); }
	rep(i, 1, m)
	{
		scanf("%s", q);
		if (q[0] == '+') { scanf("%d%d%d", &x, &y, &z); Add(&t[x], &t[y], z); }
		else if (q[0] == '-') { scanf("%d%d", &x, &y); Cut(&t[x], &t[y]); scanf("%d%d", &x, &y); Link(&t[x], &t[y]); }
		else if (q[0] == '*') { scanf("%d%d%d", &x, &y, &z); Mult(&t[x], &t[y], z); }
		else { scanf("%d%d", &x, &y); QSum(&t[x], &t[y]); }
	}
	return 0;
}