Mr_Ender @ 2022-07-14 21:58:01
#include<bits/stdc++.h>
using namespace std;
int n,m,u,v,fa[100005],d[100005],s[100005],son[100005],top[100005],w[100005],pos,tree[400005],lz[400005];
vector <int> edge[100005];
char op;
void dfs1(int f,int x){
fa[x]=f;
d[x]=d[f]+1;
s[x]=1;
for(int i=0;i<edge[x].size();i++){
if(edge[x][i]!=f){
dfs1(x,edge[x][i]);
s[x]+=s[edge[x][i]];
if(s[edge[x][i]]>s[son[x]]){
son[x]=edge[x][i];
}
}
}
return;
}
void dfs2(int x,int topv){
top[x]=topv;
pos++;
w[x]=pos;
if(son[x]!=0){
dfs2(son[x],topv);
}
for(int i=0;i<edge[x].size();i++){
if(edge[x][i]!=fa[x]&&edge[x][i]!=son[x]){
dfs2(edge[x][i],edge[x][i]);
}
}
}
void pushdown(int u,int l,int r){
int mid=(l+r)/2;
lz[u*2]+=lz[u];
lz[u*2+1]+=lz[u];
tree[u*2]+=(mid-l+1)*lz[u];
tree[u*2+1]+=(r-mid)*lz[u];
lz[u]=0;
return;
}
void pushup(int u){
tree[u]=tree[u*2]+tree[u*2+1];
return;
}
void update(int u,int l,int r,int a,int b){
if(l>b||r<a){
return;
}
if(a<=l&&r<=b){
lz[u]+=1;
tree[u]+=r-l+1;
return;
}
pushdown(u,l,r);
int mid=(l+r)/2;
update(u*2,l,mid,a,b);
update(u*2+1,mid+1,r,a,b);
pushup(u);
return;
}
void add(int u,int v){
while(top[u]!=top[v]){
if(d[top[u]]<d[top[v]]){
swap(u,v);
}
update(1,1,n,w[top[u]],w[u]);
u=fa[top[u]];
}
if(u==v){
return;
}
if(d[u]>d[v]){
swap(u,v);
}
update(1,1,n,w[son[u]],w[v]);
}
int query(int u,int l,int r,int tar){
if(l==r&&l==tar){
return tree[u];
}
if(l>tar||r<tar){
return 0;
}
int mid=(l+r)/2;
return query(u*2,l,mid,tar)+query(u*2+1,mid+1,r,tar);
}
int main(){
cin>>n>>m;
for(int i=1;i<n;i++){
cin>>u>>v;
edge[u].push_back(v);
edge[v].push_back(u);
}
dfs1(0,1);
dfs2(1,1);
for(int i=1;i<=m;i++){
cin>>op>>u>>v;
if(op=='P'){
add(u,v);
}
else{
if(d[u]>d[v]){
swap(u,v);
}
cout<<query(1,1,n,w[v])<<'\n';
}
}
return 0;
}