//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=200050;
int n,q,cnt,dfn[N],last[N],tree[N*16],lson[N*16],rson[N*16];
int first[N],next[N],v[N],w[N],tot,root[N],fa[N],deep[N],f[N];
struct Node{int xx,yy;char op[2];}node[N];
void dfs(int x){
dfn[x]=++cnt;
for(int i=first[x];~i;i=next[i])
if(v[i]!=fa[x])deep[v[i]]=deep[x]+1,fa[v[i]]=x,dfs(v[i]);
last[x]=cnt;
}
void add(int x,int y){v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void Add(int x,int y){add(x,y),add(y,x);}
void insert(int l,int r,int &pos,int num,int wei){
if(!pos)pos=++cnt;
if(l==r){tree[pos]=wei;return;}
int mid=(l+r)>>1;
if(mid<num)insert(mid+1,r,rson[pos],num,wei);
else insert(l,mid,lson[pos],num,wei);
tree[pos]=tree[lson[pos]]+tree[rson[pos]];
}
int query(int l,int r,int pos,int L,int R){
if(!pos)return 0;
if(l>=L&&r<=R)return tree[pos];
int mid=(l+r)>>1;
if(mid<L)return query(mid+1,r,rson[pos],L,R);
else if(mid>=R)return query(l,mid,lson[pos],L,R);
else return query(l,mid,lson[pos],L,R)+query(mid+1,r,rson[pos],L,R);
}
void merge(int pos1,int &pos2){
if(!pos2)pos2=++cnt;
tree[pos2]+=tree[pos1];
// printf("pos1=%d pos2=%d lson[pos1]=%d rson[pos1]=%d tree[pos]=%d\n",pos1,pos2,lson[pos1],rson[pos1],tree[pos2]);
if(lson[pos1])merge(lson[pos1],lson[pos2]);
if(rson[pos1])merge(rson[pos1],rson[pos2]);
}
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
void dfs2(int x){
if(lson[x])dfs2(lson[x]);
if(rson[x])dfs2(rson[x]);
}
int main(){
memset(first,-1,sizeof(first));
scanf("%d%d",&n,&q),getchar();
for(int i=1;i<=q;i++){
scanf("%s%d%d",node[i].op,&node[i].xx,&node[i].yy);
if(node[i].op[0]=='A')Add(node[i].xx,node[i].yy);
}
for(int i=1;i<=n;i++)if(!fa[i])dfs(i);
cnt=0;
for(int i=1;i<=n;i++)insert(1,n,root[i],dfn[i],1),f[i]=i;
for(int i=1;i<=q;i++){
if(node[i].op[0]=='A'){
int fx=find(node[i].xx),fy=find(node[i].yy);
if(fx!=fy)merge(root[fx],root[fy]),f[fx]=fy;
}
else{
if(deep[node[i].xx]>deep[node[i].yy])swap(node[i].xx,node[i].yy);
int fy=find(node[i].yy);
long long temp=query(1,n,root[fy],dfn[node[i].yy],last[node[i].yy]);
printf("%lld\n",(tree[root[fy]]-temp)*temp);
}
}
}
//By SiriusRen
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=100050;
int n,m,xx,yy,fa[N],ch[N][2],rev[N],size[N],Size[N],q[N],top;
char op[10];
bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}
void push_up(int x){size[x]=size[ch[x][0]]+size[ch[x][1]]+1+Size[x];}
void push_down(int x){if(rev[x])rev[ch[x][0]]^=1,rev[ch[x][1]]^=1,swap(ch[x][0],ch[x][1]),rev[x]=0;}
void rotate(int p){
int q=fa[p],y=fa[q],x=(ch[q][1]==p);
ch[q][x]=ch[p][!x],fa[ch[q][x]]=q;
ch[p][!x]=q,fa[p]=y;
if(!isroot(q)){
if(ch[y][1]==q)ch[y][1]=p;
if(ch[y][0]==q)ch[y][0]=p;
}fa[q]=p,push_up(q);
}
void splay(int x){
q[++top]=x;
for(int i=x;!isroot(i);i=fa[i])q[++top]=fa[i];
while(top)push_down(q[top]),top--;
for(int y=fa[x];!isroot(x);rotate(x),y=fa[x])if(!isroot(y)){
if((ch[fa[y]][0]==y)^(ch[y][0]==x))rotate(x);
else rotate(y);
}push_up(x);
}
void access(int x){for(int t=0;x;t=x,x=fa[x])splay(x),Size[x]+=size[ch[x][1]]-size[t],ch[x][1]=t,push_up(x);}
void makeroot(int x){access(x),splay(x),rev[x]^=1;}
void link(int x,int y){makeroot(x),makeroot(y),fa[x]=y,Size[y]+=size[x],push_up(y);}
void split(int x,int y){makeroot(x),access(y),splay(x);}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)size[i]=1;
while(m--){
scanf("%s%d%d",op,&xx,&yy);
if(op[0]=='A')link(xx,yy);
else split(xx,yy),printf("%lld\n",1ll*(Size[yy]+1)*(size[xx]-Size[yy]-1));
}
}