RT,70pts,吸了氧可以AC
//
// Created by kcx on 04/04/2023
//
#include <bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 5;
int n;
int num, h[maxN], nex[maxN << 1], to[maxN << 1];
int dep[maxN], f[maxN];
int dp[maxN], sz[maxN], dfa[maxN];
int global, top[maxN], son[maxN];
int vis[maxN], sta[maxN];
priority_queue<int> fIn[maxN], fDe[maxN], sIn[maxN], sDe[maxN]; // All "as"
// f: As a father, answers to sons
// s: As a son, answers to father
// Please don't name these queues in similar names, okay?
// I have been fallen into the pit since two hours ago!
// Oh! God damage! ***!
// Names which I named are much clearer!
inline void edge(int a, int b) {
to[++num] = b;
nex[num] = h[a];
h[a] = num;
}
void pre1(int u, int fa) {
dep[u] = dep[fa] + 1;
sz[u] = 1;
f[u] = fa;
for (int i = h[u]; i; i = nex[i]) {
int v = to[i];
if (v == fa) continue;
pre1(v, u);
sz[u] += sz[v];
if (sz[son[u]] < sz[v]) son[u] = v;
}
}
void pre2(int u, int sp) {
top[u] = sp;
if (son[u]) pre2(son[u], sp);
for (int i = h[u]; i; i = nex[i]) {
int v = to[i];
if (v == f[u] || v == son[u]) continue;
pre2(v, v);
}
}
inline int getLca(int a, int b) {
while (top[a] != top[b]) {
if (dep[top[a]] < dep[top[b]]) swap(a, b);
a = f[top[a]];
}
return dep[a] < dep[b] ? a : b;
}
inline int getDis(int u, int v) {
return dep[u] + dep[v] - (dep[getLca(u, v)] << 1);
}
int getRoot(int u, int fa, int sum) {
sz[u] = 1, dp[u] = 0;
int minn(0x3f3f3f3f), res;
for (int i = h[u]; i; i = nex[i]) {
int v = to[i];
if (v == fa || vis[v]) continue;
int tmp = getRoot(v, u, sum);
sz[u] += sz[v];
dp[u] = max(dp[u], sz[v]);
if (minn > dp[tmp]) minn = dp[tmp], res = tmp;
}
dp[u] = max(dp[u], sum - dp[u]);
if (minn > dp[u]) res = u;
return res;
}
void rebuild(int u, int fa) {
dfa[u] = fa;
vis[u] = 1;
for (int i(h[u]); i; i = nex[i]) {
int v(to[i]);
if (vis[v]) continue;
rebuild(getRoot(v, u, sz[v]), u);
}
}
inline void clearRedundant(priority_queue<int> &x, priority_queue<int> &y) {
while (!x.empty() && !y.empty() && x.top() == y.top()) x.pop(), y.pop();
}
inline int getLongest(priority_queue<int> &x, priority_queue<int> &y) {
clearRedundant(x, y);
if (x.empty()) return -1;
int one(x.top());
x.pop();
clearRedundant(x, y);
if (x.empty()) return x.emplace(one), -1;
int two(one + x.top());
x.emplace(one);
return two;
}
inline void change(int x) {
int u(x);
while (dfa[u]) {
int dis(getLongest(fIn[dfa[u]], fDe[dfa[u]]));
if (dis != -1) fDe[0].emplace(dis);
dis = getDis(x, dfa[u]);
if (!sIn[u].empty()) fDe[dfa[u]].emplace(sIn[u].top());
if (sta[x]) // 1 turn into 0
sDe[u].emplace(dis);
else // 0 turn into 1
sIn[u].emplace(dis);
clearRedundant(sIn[u], sDe[u]);
if (!sIn[u].empty()) fIn[dfa[u]].emplace(sIn[u].top());
dis = getLongest(fIn[dfa[u]], fDe[dfa[u]]);
if (dis != -1) fIn[0].emplace(dis);
u = dfa[u];
}
if (sta[x]) --global;
else ++global;
sta[x] ^= 1;
}
static char buf[1000000],*p1=buf,*p2=buf;
#define getchar() p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++
template <typename T>
void read(T &bow) {
T xdd = 0, fhh = 1;
char ch = char(getchar());
for(; ch < '0' || ch > '9'; ch = char(getchar()))
if(ch == '-')
fhh = -1;
for(; ch >= '0' && ch <= '9'; ch = char(getchar()))
xdd = (xdd << 1) + (xdd << 3) + (ch ^ 48);
bow = xdd * fhh;
}
template <typename T>
void write(T xdd) {
if (!xdd) return putchar('0'), void();
char F[114];
int lZj(0);
T tmp = xdd < 0 ? -xdd : xdd;
if (xdd < 0) putchar('-');
while (tmp) {
F[++lZj] = tmp % 10 ^ 48;
tmp /= 10;
}
while (lZj) putchar(F[lZj--]);
}
int main() {
#define LOCAL
#ifdef LOCAL
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif
read(n);
for (int i(1); i < n; ++i) {
int u, v;
read(u), read(v);
edge(u, v), edge(v, u);
}
pre1(1, 0), pre2(1, 1);
rebuild(getRoot(1, 0, n), 0);
for (int i(1); i <= n; ++i) change(i);
int m;
read(m);
while (m--) {
char op;
while (op = char(getchar()), (op != 'C' && op != 'G'));
if (op == 'G') {
if (global <= 1) write(global - 1), putchar(10);
else {
clearRedundant(fIn[0], fDe[0]);
write(fIn[0].top()), putchar(10);
}
} else {
int x;
read(x);
change(x);
}
}
return 0;
}