#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define fo(i,x,y) for (int i = (x); i <= (y); i++)
#define Redge(u) for (int k = head[u]; k != -1; k = edge[k].next)
using namespace std;
const int maxn = 300005,maxm = 600005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1;char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = out * 10 + c - 48; c = getchar();}
return out * flag;
}
int n,m;
int head[maxn],nedge = 0;
struct EDGE{
int to,next;
}edge[maxm];
inline void build(int a,int b){
edge[nedge] = (EDGE){b,head[a]};
head[a] = nedge++;
edge[nedge] = (EDGE){a,head[b]};
head[b] = nedge++;
}
void init(){
fill(head,head + maxn,-1);
n = read();
m = read();
for (int i = 1; i < n; i++) build(read(),read());
}
int Siz[maxn],rt = 1,rmax = INF;
void dfs(int u,int f){
Siz[u] = 1;
int gmax = 1,to;
Redge(u)
if ((to = edge[k].to) != f){
dfs(to,u);
Siz[u] += Siz[to];
if (Siz[to] > gmax) gmax = Siz[to];
}
if (n - Siz[u] > gmax) gmax = n - Siz[u];
if (gmax < rmax){
rt = u;
rmax = gmax;
}
}
int siz[maxn],top[maxn],fa[maxn],id[maxn],Hash[maxn],son[maxn],dep[maxn];
int cnt = 0;
void dfs1(int u,int f,int d){
siz[u] = 1; fa[u] = f; dep[u] = ++d;
int to;
Redge(u){
if ((to = edge[k].to) != f){
dfs1(to,u,d);
siz[u] += siz[to];
if (!son[u] || siz[to] > siz[son[u]]) son[u] = to;
}
}
}
void dfs2(int u,bool flag){
id[u] = ++cnt; Hash[cnt] = u;
top[u] = flag ? top[fa[u]] : u;
if (son[u]) dfs2(son[u],true);
int to;
Redge(u)
if ((to = edge[k].to) != fa[u] && to != son[u])
dfs2(to,false);
}
int L,R,sum[4 * maxn];
void change(int u,int l,int r,int v){
if (l >= L && r <= R) sum[u] = v;
else {
int mid = (l + r) >> 1;
if (mid >= L) change(u<<1,l,mid,v);
else change(u<<1|1,mid + 1,r,v);
sum[u] = sum[u << 1] + sum[u << 1 | 1];
}
}
int Query(int u,int l,int r){
if (l >= L && r <= R) return sum[u];
else {
int mid = l + r >> 1;
if (mid >= R) return Query(u<<1,l,mid);
else if (mid < L) return Query(u<<1|1,mid + 1,r);
else return Query(u<<1,l,mid) + Query(u<<1|1,mid + 1,r);
}
}
void cal1(){
int u = read(),v = read(),ans = 0;
while (top[u] != top[v]){
if (dep[top[u]] < dep[top[v]]) swap(u,v);
L = id[top[u]]; R = id[u];
ans += Query(1,1,n);
u = fa[top[u]];
}
if (dep[u] > dep[v]) swap(u,v);
L = id[u] + 1; R = id[v];
if (L <= R) ans += Query(1,1,n);
if (ans > 0) printf("No\n");
else printf("Yes\n");
}
int N = 0,U[maxn];
void cal2(int p){
if (p > 0){
int u = read(),v = read();
if (fa[v] == u) swap(u,v);
U[++N] = u;
L = R = id[u];
change(1,1,n,p);
}
else {
int x = read();
L = R = id[U[x]];
change(1,1,n,p);
}
}
void solve(){
char c;
while (m--){
c = getchar();
while (c != 'Q' && c != 'C' && c != 'U') c = getchar();
if (c == 'Q'){
cal1();
}else if (c == 'C'){
cal2(1);
}else {
cal2(0);
}
//L = 1; R = n; cout<<"1 to n : "<<Query(1,1,n)<<endl;
}
}
int main()
{
init();
dfs(1,0);//cout<<rt<<endl;
dfs1(rt,0,0);
dfs2(rt,0);//REP(i,n) cout<<id[i]<<endl;
solve();
return 0;
}