#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
#define ll long long
#define ull unsigned long long
#define lll __int128_t
#define ulll __uint128_t
#define ld long double
#define lld __float128
#define fi first
#define se second
#define mp make_pair
#define fast ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
template<typename T>
using V = vector<T>;
template<typename T>
using VV = V<V<T>>;
template<typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T>
using ordered_multiset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
template<typename T, typename U>
bool chmax(T &x, U v) {return (v > x)? x=v,1 : 0;}
template<typename T, typename U>
bool chmin(T &x, U v) {return (v < x)? x=v,1 : 0;}
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
mt19937_64 rnd64(chrono::steady_clock::now().time_since_epoch().count());
// #pragma GCC optimize("Ofast")
// #pragma GCC target("avx,avx2,fma")
// #define DEBUG
#ifdef DEBUG
#define _main "\e[36m"
#define _reset "\e[39m\n"
template<typename T>
inline void __print(T x) {cerr << x;}
template<typename T, typename U>
inline void __print(pair<T,U> x)
{
cerr << "("; __print(x.fi); cerr << ", "; __print(x.se); cerr << ")";
}
inline void _print() {}
template<typename T, typename... U>
inline void _print(T x, U... y)
{
__print(x);
if(sizeof...(y)) cerr << ", ";
_print(y...);
}
template<typename T>
inline void _print_arr(T x) {__print(x);}
template<typename T, typename... U>
inline void _print_arr(T x, int size, U... len)
{
cerr << "[";
bool has = sizeof...(len);
for(int i = 0; i < size; i++)
{
if(i) cerr << "," << (has? "\n" : " ");
_print_arr(x[i], len...);
}
cerr << "]";
}
#define _source source_location::current()
#define debug_pref(a) cerr << _main << _source.file_name() << ":" << _source.line() << ":" << _source.column() << " [" << a << "]";
#define debug(a...) {debug_pref(#a); cerr << " = ["; _print(a); cerr << "]" << _reset;}
#define debug_arr(a, sz...) {debug_pref(#a); cerr << " = "; _print_arr(a, sz); cerr << _reset;}
#endif
#ifndef DEBUG
#define debug(a...)
#define debug_arr(a, sz...)
#endif
/*
precalc order of appearence for each edge
lets look at C query
root tree at node c and look at all valid nodes, where we reach. a valid node will have all edges increasing on a path from c
for each node we store max edge
put all of them into ordered set to find number of nodes where max <= t
now how do we transition to children of c?
first go into child with maximum edge
recalculate set for subtree. check if path from v to p is valid to add p
now return to p
calculate values for subtree of v
now we go into v with second largest edge. this way we keep whatever we found for subtree
we do that and bla bla bla each nodes gets added O(logN) times in O(logN) complexity
for Q queries, do together with C, just keep another set of present nodes and that's it
*/
const int MAXN = 120005;
struct q_query
{
int t;
int v;
int r;
bool ans;
q_query(int v, int r, int t): v(v), r(r), t(t), ans(0) {}
q_query() {}
};
struct c_query
{
int t;
int v;
int ans;
c_query(int v, int t): v(v), t(t), ans(0) {}
c_query() {}
};
namespace graph
{
vector<pair<int, int> > g[MAXN];
int sz[MAXN];
bool used[MAXN];
int ans[MAXN];
q_query q1s[MAXN];
c_query q2s[MAXN];
vector<int> q1[MAXN];
vector<int> q2[MAXN];
bool q_tp[MAXN];
ordered_set<int> vals[MAXN];
map<int, int> nodes[MAXN];
vector<int> pars[MAXN];
void calc_sz(int v, int p)
{
sz[v] = 1;
for(auto [e, c] : g[v])
{
if(used[c] || c == p)
continue;
calc_sz(c, v);
sz[v] += sz[c];
}
}
int find_centr(int v, int p, int cur_s)
{
for(auto [e, c] : g[v])
{
if(used[c] || c == p)
continue;
if(sz[c]*2 > cur_s)
return find_centr(c, v, cur_s);
}
return v;
}
void add_to_set(int v, int p, int pp, int val)
{
debug("add", pp, v, val);
nodes[pp][v] = val;
vals[pp].insert(val);
for(auto [e, c] : g[v])
{
if(e < val)
continue;
if(used[c] || c == p)
continue;
add_to_set(c, v, pp, e);
}
}
void add_pars(int v, int p, int pp, int val)
{
pars[v].push_back(pp);
for(auto [e, c] : g[v])
{
if(used[c] || c == p)
continue;
if(e > val)
continue;
add_pars(c, v, pp, e);
}
}
void solve(int v, int p)
{
debug("solve()", v, p);
calc_sz(v, -1);
int cur_sz = sz[v];
int c = find_centr(v, -1, cur_sz);
debug("centr", c);
used[c] = 1;
add_pars(c, -1, c, 1e9);
nodes[c][c] = -1;
vals[c].insert(-1);
debug("add", c, c, -1);
for(auto [e, u] : g[c])
{
if(used[u])
continue;
solve(u, c);
debug("back from child", c, u);
add_to_set(u, -1, c, e);
}
debug("answering queries", c);
debug("set: ", c);
for(auto [v, val] : nodes[c])
{
debug(v, val);
}
for(int pp : pars[c])
{
for(int q : q1[c])
{
int v = q1s[q].v;
if(nodes[pp].count(v) == 0) {
continue;
}
int val = nodes[pp][v];
q1s[q].ans |= val < q1s[q].t;
}
for(int q : q2[c])
{
int t = q2s[q].t;
auto it = vals[pp].lower_bound(t);
int res = 0;
if(it == vals[pp].end())
res = vals[pp].size();
else
res = vals[pp].order_of_key(*it);
q2s[q].ans += res;
}
}
used[c] = 0;
}
void add_edge(int a, int b, int t)
{
g[a].push_back(mp(t, b));
g[b].push_back(mp(t, a));
}
void add_q_query(q_query &q, int i)
{
q1s[i] = q;
q1[q.r].push_back(i);
q_tp[i] = 0;
}
void add_c_query(c_query &q, int i)
{
q2s[i] = q;
q2[q.v].push_back(i);
q_tp[i] = 1;
}
void solve(int n)
{
for(int i = 0; i < n; i++)
{
sort(g[i].rbegin(), g[i].rend());
}
solve(0, -1);
}
void print_ans(int q)
{
for(int i = 0; i < q; i++)
{
if(q_tp[i])
{
cout << q2s[i].ans << '\n';
}
else
{
cout << (q1s[i].ans ? "yes" : "no") << '\n';
}
}
}
}
int main()
{
fast;
int n, q; cin >> n >> q;
vector<pair<int, int> > edg;
int qs = 0;
for(int i = 0; i < n+q-1; i++)
{
char c; cin >> c;
if(c == 'S')
{
int a, b; cin >> a >> b; a--; b--;
edg.push_back(mp(a, b));
}
else if(c == 'Q')
{
int r, v; cin >> v >> r; r--; v--;
q_query qr(v, r, edg.size());
graph::add_q_query(qr, qs++);
}
else
{
int v; cin >> v; v--;
c_query qr(v, edg.size());
graph::add_c_query(qr, qs++);
}
}
for(int i = 0; i < n-1; i++)
{
int a = edg[i].fi, b = edg[i].se;
graph::add_edge(a, b, i);
}
graph::solve(n);
graph::print_ans(q);
}
/*
6 9
S 1 2
S 1 3
S 3 4
Q 5 1
S 4 5
S 1 6
Q 5 1
Q 1 5
C 1
C 2
C 3
C 4
C 5
C 6
*/