#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<vector>
#include<ctime>
#include<queue>
#include<map>
#define ull unsigned long long
using namespace std;
int n,m,a,b,cnt;
int fa[100005],siz[100005],son[100005],dep[100005];
char op;
int head[100005],id[100005],di[100005],top[100005];
struct node{
int to,net;
}bian[200005];
struct str{
int lazy,l,r,num;
}tr[400005];
void add(int x,int y){
cnt++;
bian[cnt].to=y;
bian[cnt].net=head[x];
head[x]=cnt;
}
void Dfs(int x){
siz[x]++;
for(int i=head[x];i;i=bian[i].net){
int v=bian[i].to;
if(v==fa[x]) continue;
dep[v]=dep[x]+1;
fa[v]=x;
Dfs(v);
siz[x]+=siz[v];
if(siz[v]>siz[son[x]]) son[x]=v;
}
}
void dfs(int x,int f){
cnt++;
id[x]=cnt;
di[cnt]=x;
top[x]=f;
if(son[x]) dfs(son[x],f);
for(int i=head[x];i;i=bian[i].net){
if(bian[i].to==son[x]||bian[i].to==fa[x]) continue;
dfs(bian[i].to,bian[i].to);
}
}
void build(int now,int l,int r){
tr[now].l=l;tr[now].r=r;
tr[now].lazy=0;
tr[now].num=0;
if(l==r) return;
int mid=(l+r)>>1;
build(now<<1,l,mid);
build(now<<1|1,mid+1,r);
}
void lazy(int now){
if(!tr[now].lazy) return;
int l=now<<1,r=now<<1|1;
tr[l].lazy+=tr[now].lazy;
tr[r].lazy+=tr[now].lazy;
tr[l].num+=tr[now].lazy*(tr[l].r-tr[l].l+1);
tr[r].num+=tr[now].lazy*(tr[r].r-tr[r].l+1);
tr[now].lazy=0;
}
int find(int x,int y,int now){
if(x<=tr[now].l&&tr[now].r<=y) return tr[now].num;
else{
lazy(now);
int mid=(tr[now].l+tr[now].r)>>1;
int ans=0;
if(x<=mid) ans+=find(x,y,now<<1);
if(y>mid) ans+=find(x,y,now<<1|1);
return ans;
}
}
int find1(int x,int y){
int ans=0;
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
ans+=find(id[top[x]],id[x],1);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
if(x==y) return ans;
// cout<<x<<" "<<y<<endl;
ans+=find(id[x],id[y],1);
ans-=find(id[x],id[x],1);
return ans;
}
void update(int x,int y,int now,int z){
if(x<=tr[now].l&&tr[now].r<=y){
tr[now].lazy+=z;
tr[now].num+=(tr[now].r-tr[now].l+1)*z;
return;
}
int mid=(tr[now].l+tr[now].r)>>1;
if(x<=mid) update(x,y,now<<1,z);
if(y>mid) update(x,y,now<<1|1,z);
tr[now].num=tr[now<<1].num+tr[now<<1|1].num;
}
void update1(int x,int y,int now){
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(id[top[x]],id[x],1,1);
x=fa[top[x]];
}
if(dep[x]>dep[y]) swap(x,y);
update(id[x],id[y],1,1);
// int h=find1(1,3);
update(id[x],id[x],1,-1);
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
cin>>n>>m;
for(int i=1;i<n;i++){
cin>>a>>b;
add(a,b);
add(b,a);
}
Dfs(1);
cnt=0;
dfs(1,1);
build(1,1,n);
while(m--){
cin>>op>>a>>b;
if(op=='P'){
update1(a,b,1);
}else{
cout<<find1(a,b)<<endl;
}
}
// fclose(stdin);
// fclose(stdout);
return 0;
}
/*
*/
这个过不了样例,但有24分,不过......
把113行的int h=find1(1,3)加上就能过样例且有31分(十分神奇,main函数在117行)