#include using namespace std; #define ge getchar() #define Re read() inline int read() { int x = 0, ch; while(!isdigit(ch = ge)) ; while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = ge; return x; } const int MAXN = 100000; int n; int Q; int ct; int T[MAXN * 20]; int L[MAXN * 20]; int R[MAXN * 20]; int rt[MAXN + 1]; int dep[MAXN + 1]; int fa[MAXN + 1][20]; int bk[MAXN + 1]; int fd[MAXN + 1]; int tot; int fi[MAXN + 1]; int to[MAXN << 1]; int ne[MAXN << 1]; inline int LCA(int, int); inline int Dis(int, int); inline void dfs(int, int); inline void Link(int, int); inline void solve(int); inline int find(int); inline void Merge(int, int); inline void Merge(int&, int&, int, int); inline void Modify(int&, int, int, int); inline int Query(int, int, int, int); int main() { int Cases = Re; while(Cases--) { n = Re; for(int i = 1; i < n; i++) { int u = Re, v = Re; Link(u, v), Link(v, u); } fa[1][0] = 1; dep[1] = 1; dfs(1, 1); Q = Re; while(Q--) { int opt = Re; if(opt == 1) { int x = Re; if(bk[x]) continue; solve(x); } else { int u = Re, v = Re; int fu = find(u), fv = find(v); if(fu == fv) { if(u > v) swap(u, v); // cout << Query(rt[fu], 1, n, u + 1) << ' ' << Query(rt[fu], 1, n, v + 1) << endl; printf("%d\n", Query(rt[fu], 1, n, u + 1) - Query(rt[fu], 1, n, v + 1)); } else { int dis = 0, x = fu, y = fv; if(x != u) x = fa[x][0], dis++; if(y != v) y = fa[y][0], dis++; dis += Dis(x, y); dis += Query(rt[fu], 1, n, u + 1); dis += Query(rt[fv], 1, n, v + 1); printf("%d\n", dis); } } } tot = ct = 0; memset(T, 0, sizeof(T)); memset(L, 0, sizeof(L)); memset(R, 0, sizeof(R)); memset(rt, 0, sizeof(rt)); memset(fi, 0, sizeof(fi)); } return 0; } inline int find(int x) { return fd[x] == x ? x : fd[x] = find(fd[x]); } inline void Merge(int x, int y) { int fx = find(x), fy = find(y); if(fx == fy) return ; fd[fy] = fx; } inline void dfs(int x, int la) { Modify(rt[x], 1, n, x); fd[x] = x, bk[x] = 0; for(int i = 1; i < 19; i++) fa[x][i] = fa[fa[x][i - 1]][i - 1]; for(int i = fi[x]; i; i = ne[i]) { int u = to[i]; if(u == la) continue; dep[u] = dep[x] + 1; fa[u][0] = x; dfs(u, x); } } inline int LCA(int u, int v) { if(dep[u] < dep[v]) swap(u, v); int k = dep[u] - dep[v]; for(int i = 0; i < 19; i++) if(k & (1 << i)) u = fa[u][i]; if(u == v) return u; for(int i = 18; ~i; --i) if(fa[u][i] != fa[v][i]) u = fa[u][i], v = fa[v][i]; return fa[u][0]; } inline int Dis(int u, int v) { return dep[u] + dep[v] - 2 * dep[LCA(u, v)]; } inline void Link(int u, int v) { tot++; to[tot] = v; ne[tot] = fi[u]; fi[u] = tot; } inline void solve(int x) { if(bk[x]) return ; int F = fa[x][0]; bk[x] = 1; for(int i = fi[x]; i; i = ne[i]) { int u = to[i]; if(F == u) continue; solve(u); Merge(x, u); Merge(rt[x], rt[u], 1, n); } } inline void Modify(int&x, int l, int r, int p) { if(!x) x = ++ct; T[x]++; if(l == r) return ; int mid = (l + r) >> 1; if(p <= mid) Modify(L[x], l, mid, p); else Modify(R[x], mid + 1, r, p); } inline void Merge(int&x, int&y, int l, int r) { if(!(1LL * x * y)) { x = x | y; return ; } T[x] += T[y]; int mid = (l + r) >> 1; Merge(L[x], L[y], l, mid); Merge(R[x], R[y], mid + 1, r); } inline int Query(int x, int l, int r, int p) { if(p > r) return 0; if(l >= p || !T[x]) return T[x]; int mid = (l + r) >> 1, v = Query(R[x], mid + 1, r, p); if(mid >= p) v += Query(L[x], l, mid, p); return v; }