代码省略了读入
#define maxn 100005
class node
{
public:
int c[2],fa;
bool rev;
int im_siz,re_siz;
node(){c[0]=c[1]=fa=im_siz=0,re_siz=0,rev=false;}
};
node d[maxn];
#define fa(x) d[x].fa
#define left_son(x) d[d[x].c[0]]
#define right_son(x) d[d[x].c[1]]
inline bool nroot(int x){return d[fa(x)].c[0]==x||d[fa(x)].c[1]==x;}
inline void push_rev(int x){swap(d[x].c[0],d[x].c[1]),d[x].rev^=1;}
inline void pushdown(int x)
{
if(d[x].rev)
{
if(d[x].c[0]) push_rev(d[x].c[0]);
if(d[x].c[1]) push_rev(d[x].c[1]);
d[x].rev=0;
}
}
inline void push_all(int x)
{
if(nroot(x)) push_all(fa(x));
pushdown(x);
}
inline void update(int x)
{
d[x].re_siz=left_son(x).re_siz+right_son(x).re_siz+d[x].im_siz+1;
}
inline void rotate(int x)
{
int y=fa(x),z=fa(y),k=(d[y].c[1]==x),w=d[x].c[!k];
if(nroot(y)) d[z].c[d[z].c[1]==y]=x;
d[x].c[!k]=y,
d[y].c[ k]=w;
if(w) fa(w)=y;
fa(fa(y)=x)=z;
update(y);
// update(x);
return;
}
inline void splay(int x)
{
static int y,z;
push_all(x);
while(nroot(x))
{
y=d[x].fa,z=d[y].fa;
if(nroot(y)) rotate((d[y].c[0]==x)^(d[z].c[0]==y)?x:y);
rotate(x);
update(x);
}
}
inline void access(int x)
{
for(int y=0;x;x=fa(y=x))
splay(x),
d[x].im_siz+=right_son(x).re_siz-d[y].re_siz,
d[x].c[1]=y,
update(x);
}
inline void makeRoot(int x)
{
access(x),
splay(x),
push_rev(x);
}
inline int findRoot(int x)
{
access(x),splay(x);
while(d[x].c[0]) pushdown(x),x=d[x].c[0];
splay(x);
return x;
}
inline void link(int x,int y)
{
makeRoot(x);
if(findRoot(y)^x)
fa(x)=y,
d[y].im_siz+=d[x].re_siz,
update(y);
}
inline void cut(int x,int y)
{
makeRoot(x);
if(findRoot(y)==x&&!d[y].c[0]&&fa(y)==x)
d[x].c[1]=fa(y)=0,
update(x);
}
inline void split(int x,int y)
{
makeRoot(x),
access(y),
splay(y);
}
int n,m;
ll ans;
signed main()
{
read_(n),read_(m);
char op;
for(int x,y,i=1;i<=m;++i)
{
for(op=getchar();op<'A'||op>'Z';op=getchar());
read_(x),read_(y);
if(op=='A') link(x,y);
else
cut(x,y),
makeRoot(x),
makeRoot(y),
cout<<(ll)d[x].re_siz*(ll)d[y].re_siz<<'\n',
link(x,y);
}
return 0;
}