/***************************************************
* 查询两点是否连通,相当于查询两点之间是否有断点
* 那么考虑树上差分,维护每个点到根节点的路径上,断点
* 的个数,直接按照DFS序,用树状数组维护即可
**************************************************/
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
const int maxn = 300300;
const int maxm = 300300;
int n, m, tot, coc, root;
vector <int> G[ maxn ];
struct BIT{
int s[ maxn << 1 ];
void add(int p,int v){
for(int i = p ; i <= n << 1 ; i += i & (-i) )
s[ i ] += v;
}
int query(int p){
int rtn = 0;
for(int i = p ; i ; i -= i & (-i) )
rtn += s[ i ];
return rtn;
}
}dis;
int dep[ maxn ], son[ maxn ], fa[ maxn ], sz[ maxn ], top[ maxn ], pin[ maxn ], pout[ maxn ];
int Q[ maxm ];
void dfs1(int k){
sz[ k ] = 1;
for(int i = 0; i < G[ k ].size(); ++i){
int kk = G[ k ][ i ];
if( kk == fa[ k ] ) continue;
fa[ kk ] = k;
dep[ kk ] = dep[ k ] + 1;
dfs1( kk );
if( sz[ son[ k ] ] < sz[ kk ] ) son[ k ] = kk;
sz[ k ] += sz[ kk ];
}
}
void dfs2(int k, int t){
top[ k ] = t;
pin[ k ] = ++coc;
if( !son[ k ] ) return ( void ) (pout[ k ] = ++coc);
dfs2( son[k] , t );
for(int i = 0; i < G[ k ].size(); ++i){
int kk = G[ k ][ i ];
if( kk == fa[ k ] || kk == son[ k ] )continue;
dfs2( kk , kk );
}
return ( void ) (pout[ k ] = ++coc);
}
int lca(int x, int y){
while( top[ x ] != top[ y ] ){
if( dep[ top[ x ] ] < dep[ top[ y ] ] ) swap(x, y);
x = fa[ top[ x ] ];
}return dep[ x ] < dep[ y ] ? x : y;
}
struct io {
char op[ 1 << 25 ] , *s;
io(){
//freopen("lct.in", "r", stdin);
//freopen("lct.out", "w", stdout);
fread( s = op , 1 , 1 << 25 , stdin );
}
int read(){
int u = 0;
while( *s < 48 || *s > 57 )s++;
while( *s > 47 && *s < 58 )u = ( u << 1 ) + ( u << 3 ) + *s++ - 48;
return u;
}
char gc(){
while( *s < 'A' || *s > 'Z' )s++;
return *s++ ;
}
}ip;
#define read ip.read
#define gcha ip.gc
int main(){
n = read(); m = read();
for(int i = 1; i < n; ++i){
int x = read() , y = read();
G[ x ].push_back( y );
G[ y ].push_back( x );
}
root = n / 2;
dfs1( root );
dfs2( root , root );
for(int i = 1; i <= n; ++i){
dis.add( pin[ i ], 1 );
dis.add( pout[ i ],-1 );
}
while( m-- ){
char s[5];
int p, q, l, D1, D2;
s[ 0 ] = gcha();
switch( s[ 0 ] ){
case 'Q': p = read(); q = read();
l = lca( p , q );
D1 = dep[ p ] + dep[ q ] - 2 * dep[ l ];
D2 = dis.query( pin[ p ] ) + dis.query( pin[ q ] ) - 2 * dis.query( pin[ l ] );
if(D1 == D2) printf("Yes\n"); else printf("No\n"); break;
case 'C': p = read(); q = read();
if(dep[ p ] < dep[ q ]) p = q;
Q[ ++tot ] = p;
dis.add( pin[ p ], -1 );
dis.add( pout[ p ], 1 );
break;
case 'U': p = read();
p = Q[ p ];
dis.add( pin[ p ], 1 );
dis.add( pout[ p ], -1 );
break;
}
}
return 0;
}