真的不想拍
#include<cstdio>
#include<vector>
#include<algorithm>
#define INF (0x3f3f3f3f)
using namespace std;
const int MAXN = 1000005;
int n, Q;
struct edge {
int to, nex;
}e[MAXN]; int idx, head[MAXN];
inline void add(int u, int v) {
e[++ idx].to = v;
e[idx].nex = head[u];
head[u] = idx;
}
namespace Tree {
int timer, eu[MAXN];
int dep[MAXN], dfn[MAXN];
int lg[MAXN], f[MAXN][25];
inline void dfs(int u, int fath) {
eu[dfn[u] = ++ timer] = u;
if (u == 1) dep[u] = 1;
for (int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if (v == fath) continue;
dep[v] = dep[u] + 1;
dfs(v, u);
eu[++ timer] = u;
}
}
inline int _min(int u, int v) {
return (dep[u] < dep[v]) ? u : v;
}
inline void Init() {
dep[0] = INF;
for (int i = 2; i <= timer; ++ i)
lg[i] = lg[i >> 1] + 1;
for (int i = 1; i <= timer; ++ i)
f[i][0] = eu[i];
for (int j = 1; j <= lg[timer]; ++ j)
for (int i = 1; i <= timer; ++ i)
f[i][j] = _min(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
inline int dist(int u, int v) {
int l = min(dfn[u], dfn[v]);
int r = max(dfn[u], dfn[v]);
int len = lg[r - l + 1];
int lca = _min(f[l][len], f[r - (1 << len) + 1][len]);
return dep[u] + dep[v] - 2 * dep[lca];
}
inline void premain() {
scanf ("%d", &n);
for (int i = 1; i < n; ++ i) {
int u, v;
scanf ("%d%d", &u, &v);
add(u, v); add(v, u);
}
dfs(1, 0); Init();
}
}
class Segment_tree {
#define lc (u << 1)
#define rc (u << 1 | 1)
private :
int dst[MAXN << 2];
int p[MAXN << 2][2];
vector<int>nd;
inline void push_up(int u) {
p[u][0] = p[u][1] = 0;
nd.clear();
if (p[lc][0]) nd.push_back(p[lc][0]);
if (p[lc][1]) nd.push_back(p[lc][1]);
if (p[rc][0]) nd.push_back(p[rc][0]);
if (p[rc][1]) nd.push_back(p[rc][1]);
int len = nd.size(), mx = -1, dis;
for (int i = 1; i < len; ++ i)
for (int j = 0; j < i; ++ j)
if ((dis = Tree::dist(nd[i], nd[j])) > mx)
p[u][0] = nd[j], p[u][1] = nd[i], mx = dis;
dst[u] = mx;
if (!~mx) p[u][0] = nd[0];
}
public :
inline void Build(int u = 1, int l = 1, int r = n) {
if (l == r) {
dst[u] = 0;
p[u][0] = l, p[u][1] = 0;
return;
}
int mid = (l + r) >> 1;
Build(lc, l, mid);
Build(rc, mid + 1, r);
push_up(u);
}
inline void Modify(int x, int u = 1, int l = 1, int r = n) {
if (l == r) {
if (!dst[u]) dst[u] = -1, p[u][0] = p[u][1] = 0;
else dst[u] = 0, p[u][0] = l, p[u][1] = 0;
return;
}
int mid = (l + r) >> 1;
if (x <= mid) Modify(x, lc, l, mid);
else Modify(x, rc, mid + 1, r);
push_up(u);
}
inline int Query() {
return dst[1];
}
#undef lc
#undef rc
}st;
int cnt, t[MAXN];
inline void Solve() {
scanf ("%d", &Q);
char op[10];
int p;
cnt = n;
while (Q --) {
scanf ("%s", op);
if (op[0] == 'G')
printf ("%d\n", (cnt ^ 1) ? st.Query() : 0);
else {
scanf ("%d", &p);
cnt -= t[p];
cnt += (t[p] ^= 1);
st.Modify(p);
}
}
}
int main()
{
Tree::premain();
st.Build();
Solve();
return 0;
}