#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define pb push_back
#define fi first
#define se second
const int N=1e6+10;
const int mod=998244353;
void read(int &a)
{
a=0;int d=1;char ch;
while(ch=getchar(),ch>'9'||ch<'0')
if(ch=='-')
d=-1;
a=ch^48;
while(ch=getchar(),ch>='0'&&ch<='9')
a=(a<<3)+(a<<1)+(ch^48);
a*=d;
}
struct node{int x,w,p;};
struct note{int l,r,lazy;ll sum;}tree[N<<2];
vector <node> v[N];
int siz[N],top[N],dep[N],son[N],id[N],rk[N],f[N],val[N],rt=1,cnt,head[N];
void dfs1(int x)
{
siz[x]=1,dep[x]=dep[f[x]]+1;
for(re int t=0;t<v[x].size();t++)
{
node i=v[x][t];
if(i.x!=f[x])
{
val[i.x]=i.w;
head[i.p]=i.x;
f[i.x]=x,dfs1(i.x);
siz[x]+=siz[i.x];
if(siz[son[x]]<siz[i.x]) son[x]=i.x;
}
}
}
void dfs2(int x,int tp)
{
top[x]=tp,id[x]=++cnt,rk[cnt]=x;
if(son[x]) dfs2(son[x],tp);
for(re int t=0;t<v[x].size();t++) {node i=v[x][t];if(i.x!=son[x]&&i.x!=f[x]) dfs2(i.x,i.x);}
}
void build(int l,int r,int now)
{
tree[now].l=l,tree[now].r=r,tree[now].lazy=0;
if(l==r) {tree[now].sum=val[rk[l]];return;}
int m=l+r>>1;
build(l,m,now<<1),build(m+1,r,now<<1|1);
tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum);
}
void work(int now,int k)
{
tree[now].sum+=1ll*(tree[now].r-tree[now].l+1)*k;
tree[now].lazy+=k;
}
void pushdown(int now)
{
work(now<<1,tree[now].lazy);
work(now<<1|1,tree[now].lazy);
tree[now].lazy=0;
}
void modify(int l,int r,int now,int w)
{
if(l<=tree[now].l&&tree[now].r<=r) {work(now,w);return;}
if(tree[now].lazy) pushdown(now);
int m=tree[now].l+tree[now].r>>1;
if(m>=l) modify(l,r,now<<1,w);
if(m<r) modify(l,r,now<<1|1,w);
tree[now].sum=(tree[now<<1].sum+tree[now<<1|1].sum);
}
ll query(int l,int r,int now)
{
ll ans=0;
if(l<=tree[now].l&&tree[now].r<=r) {return tree[now].sum;}
if(tree[now].lazy) pushdown(now);
int m=tree[now].l+tree[now].r>>1;
if(m>=l) ans+=query(l,r,now<<1);
if(m<r) ans+=query(l,r,now<<1|1);
return ans;
}
void update(int x,int y,int w)
{
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
modify(id[top[x]],id[x],1,w);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
modify(id[x]+1,id[y],1,w);
}
ll query1(int x,int y)
{
ll ans=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=query(id[top[x]],id[x],1);
x=f[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
return ans+query(id[x]+1,id[y],1);
}
int main()
{
int n,m;read(n),read(m);
for(re int i=1,x,y,z;i<n;i++)
{
read(x),read(y);
v[x].pb(node{y,0,i});
v[y].pb(node{x,0,i});
}
dfs1(rt),dfs2(rt,rt);
build(1,n,1);
char op;
for(re int i=1,l,r;i<=m;i++)
{
scanf(" %c %d %d",&op,&l,&r);
if(op=='P') update(l,r,1);
else printf("%lld\n",query1(l,r));
}
return 0;
}