#include<cstdio>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<cstring>
#include<ctime>
#include<cstdlib>
#include<cctype>
#include<stack>
#include<map>
#include<climits>
#include<set>
using namespace std;
typedef long long ll;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+(ch-'0'),ch=getchar();
return s*w;
}
inline void output(int x)
{
if(x/10) output(x/10);
putchar(x%10+'0');
return;
}
const int INF=1e9;
inline int Min(int x,int y){return x<y?x:y;}
inline int Max(int x,int y){return x>y?x:y;}
inline void Swap(int&x,int&y){x^=y;y^=x;x^=y;}
const int MAXN(1e5+10);
int n,m,a[MAXN],b[MAXN];
struct E{int to,nxt;};
E edge[MAXN<<1];
int head[MAXN],tot;
inline void add_edge(int u,int v)
{
edge[++tot].nxt=head[u];
head[u]=tot;
edge[tot].to=v;
return;
}
int idx[MAXN],rk[MAXN],top[MAXN],par[MAXN],son[MAXN],siz[MAXN],dep[MAXN],cnt;
inline void dfs1(int u,int fa)
{
dep[u]=dep[fa]+1;
siz[u]=1;
par[u]=fa;
for(register int i=head[u];i;i=edge[i].nxt)
{
E e=edge[i];
if(e.to==fa) continue;
dfs1(e.to,u);
siz[u]+=siz[e.to];
if(siz[e.to]>siz[son[u]]) son[u]=e.to;
}
return;
}
inline void dfs2(int u,int topf)
{
idx[u]=++cnt;
rk[cnt]=u;
b[cnt]=a[u];
if(son[u]) dfs2(son[u],topf);
for(register int i=head[u];i;i=edge[i].nxt)
{
E e=edge[i];
if(e.to!=son[u]&&e.to!=par[u]) dfs2(e.to,e.to);
}
return;
}
struct Segment_Tree
{
int tree[MAXN];
inline int lc(int p){return p<<1;}
inline int rc(int p){return p<<1|1;}
inline void push_up(int u)
{
tree[u]=tree[lc(u)]+tree[rc(u)];
return;
}
inline void build(int u,int l,int r)
{
if(l==r)
{
tree[u]=b[l];
return;
}
int mid=(l+r)>>1;
build(lc(u),l,mid);
build(rc(u),mid+1,r);
push_up(u);
return;
}
inline void update(int u,int l,int r,int p,int k)
{
if(l==p&&r==p)
{
tree[u]=k;
return;
}
int mid=(l+r)>>1;
if(p<=mid) update(lc(u),l,mid,p,k);
else update(rc(u),mid+1,r,p,k);
push_up(u);
return;
}
inline int query(int u,int l,int r,int ln,int rn)
{
if(ln<=l&&r<=rn) return tree[u];
int res(0);
int mid=(l+r)>>1;
if(ln<=mid) res+=query(lc(u),l,mid,ln,rn);
if(rn>mid) res+=query(rc(u),mid+1,r,ln,rn);
return res;
}
inline int qpos(int l,int r)
{
if(l==r) return l;
int mid=(l+r)>>1;
if(query(1,1,n,l,mid)) return qpos(l,mid);
else return qpos(mid+1,r);
}
};
Segment_Tree bit;
inline void Update(int u)
{
bit.update(1,1,n,idx[u],1);
return;
}
inline int Query(int x,int y)
{
int fx=top[x],fy=top[y];
while(fx!=fy)
{
if(dep[fx]<dep[fy]) Swap(fx,fy),Swap(x,y);
if(!bit.query(1,1,n,idx[fx],idx[x])) x=par[fx],fx=top[x];
else return bit.qpos(idx[fx],idx[x]);
}
if(dep[x]>dep[y]) Swap(x,y);
return bit.qpos(idx[x],idx[y]);
}
int main()
{
n=read(),m=read();
for(register int i=1;i<n;i++)
{
int u=read(),v=read();
add_edge(u,v);
add_edge(v,u);
}
a[1]=1;
dfs1(1,0);
dfs2(1,1);
bit.build(1,1,n);
while(m--)
{
char opt[3];
scanf("%s",opt);
int u=read();
if(opt[0]=='C') Update(u);
else printf("%d\n",rk[Query(1,u)]);
}
return 0;
}