#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 5 *1e5 + 10;
char c;
int T, n, m, a, b, cnt, rudu[maxn], date[maxn], shuliang[maxn], yingshe[maxn];
int lazy[maxn<<2];
vector<int> tree[maxn];
void init() {
cnt = 0;
memset(rudu, 0, sizeof(rudu));
memset(lazy, -1, sizeof(lazy));
for (int i = 1; i <= n; i++) {
tree[i].clear();
}
}
int dfs(int u) {
date[++cnt] = u;
if (tree[u].empty()) return shuliang[u] = 0;
int temp = 0;
for (int i = 0; i < tree[u].size(); i++) {
int v = tree[u][i];
temp += dfs(v) + 1;
}
return shuliang[u] = temp;
}
void pushdown(int root) {
if (lazy[root] != -1) {
lazy[root<<1] = lazy[root<<1|1] = lazy[root];
lazy[root] = -1;
}
}
void update_interval(int L, int R, int root, int uL, int uR, int val) {
if (uL <= L && R <= uR) {
lazy[root] = val;
return;
}
int mid = (L + R)>>1;
pushdown(root);
if (uL <= mid) {
update_interval(L, mid, root<<1, uL, uR, val);
}
if (uR > mid) {
update_interval(mid + 1, R, root<<1|1, uL, uR, val);
}
}
int query(int L, int R, int root, int pos) {
if (L == R) {
return lazy[root];
}
int mid = (L + R)>>1;
pushdown(root);
if (pos <= mid) {
return query(L, mid, root<<1, pos);
}
else {
return query(mid + 1, R, root<<1|1, pos);
}
}
int main()
{
scanf("%d", &T);
for (int kase = 1; kase <= T; kase++) {
scanf("%d", &n);
init();
for (int i = 1; i <= n - 1; i++) {
scanf("%d %d", &a, &b);
tree[b].push_back(a);
rudu[a]++;
}
for (int i = 1; i <= n; i++) {
if (!rudu[i]) {
dfs(i);
break;
}
}
for (int i = 1; i <= n; i++) {
yingshe[date[i]] = i;
}
scanf("%d", &m);
printf("Case #%d:\n", kase);
while (m--) {
cin >> c;
if (c == 'T') {
scanf("%d %d", &a, &b);
update_interval(1, n, 1, yingshe[a], yingshe[a] + shuliang[a], b);
}
else {
scanf("%d", &a);
printf("%d\n", query(1, n, 1, yingshe[a]));
}
}
}
return 0;
}