#include <bits/stdc++.h>   using namespace std;   int sum[501000 << 2], sum2[501000 << 2];   void pushUp(int rt) { sum[rt] = max(sum[rt * 2], sum[rt * 2 + 1]); }   void updata(int l, int r, int rt, int q, int val) {     if (l == q && r == q) {       sum[rt] = val;       return;     }     int m = (l + r) / 2;     if (q <= m) updata(l, m, rt * 2, q, val);     if (q > m) updata(m + 1, r, rt * 2 + 1, q, val);     pushUp(rt);   }   int query(int l, int r, int rt, int ql, int qr) {     if (l > qr || r < ql) return 0;     if (l >= ql && r <= qr) return sum[rt];     int m = (l + r) / 2;     return max(query(l, m, rt * 2, ql, qr), query(m + 1, r, rt * 2 + 1, ql, qr));   }   void build(int l, int r, int rt) {     if (l == r) {       sum[rt] = 0;       return;     }     int m = (l + r) / 2;     build(l, m, rt * 2);     build(m + 1, r, rt * 2 + 1);     pushUp(rt);   }   void pushUp2(int rt) { sum2[rt] = min(sum2[rt * 2], sum2[rt * 2 + 1]); }   void updata2(int l, int r, int rt, int q, int val) {     if (l == q && r == q) {       sum2[rt] = val;       return;     }     int m = (l + r) / 2;     if (q <= m) updata2(l, m, rt * 2, q, val);     if (q > m) updata2(m + 1, r, rt * 2 + 1, q, val);     pushUp2(rt);   }   int query2(int l, int r, int rt, int ql, int qr) {     if (l > qr || r < ql) return 0;     if (l >= ql && r <= qr) return sum2[rt];     int m = (l + r) / 2;     return min(query2(l, m, rt * 2, ql, qr),                query2(m + 1, r, rt * 2 + 1, ql, qr));   }   void build2(int l, int r, int rt) {     if (l == r) {       sum2[rt] = 0;       return;     }     int m = (l + r) / 2;     build2(l, m, rt * 2);     build2(m + 1, r, rt * 2 + 1);     pushUp2(rt);   }   struct edge {     int to;     int next;   } e[501000 << 1];   int box[501000], cnt, tot;   int siz[501000], top[501000], son[501000], dep[501000], fa[501000], w[501000];   int we[501000];   int ww = 0;   void init() {     tot = 0;     son[0] = dep[0] = 0;     memset(box, -1, sizeof(box));     cnt = 0;   }   void add(int from, int to) {     e[cnt].to = to;     e[cnt].next = box[from];     box[from] = cnt++;   }   void dfs(int now, int pre) {     siz[now] = 1;     fa[now] = pre;     son[now] = 0;     dep[now] = dep[pre] + 1;     int t, v;     for (t = box[now]; t + 1; t = e[t].next) {       v = e[t].to;       if (v != pre) {         dfs(v, now);         siz[now] += siz[v];         if (siz[son[now]] < siz[v]) {           son[now] = v;         }       }     }   }   void dfs2(int now, int tp) {     w[now] = ++ww;     top[now] = tp;     if (son[now]) dfs2(son[now], top[now]);     int t, v;     for (t = box[now]; t + 1; t = e[t].next) {       v = e[t].to;       if (v != fa[now] && v != son[now]) dfs2(v, v);     }     we[now] = ww;   }   int n, m;   int solve(int a, int b) {     int ma = 0;     while (top[a] != top[b]) {       if (dep[top[a]] < dep[top[b]]) swap(a, b);       ma = max(ma, query(1, n, 1, w[top[a]], w[a]));       a = fa[top[a]];     }     if (dep[a] > dep[b]) swap(a, b);     ma = max(ma, query(1, n, 1, w[a], w[b]));     return ma;   }   int main() {     scanf( %d , &n);     init();     for (int i = 0; i < n - 1; i++) {       int x, y;       scanf( %d%d , &x, &y);       add(x, y);       add(y, x);     }     build(1, n, 1);     build2(1, n, 1);     dfs(1, 0);     dfs2(1, 1);     scanf( %d , &m);     for (int i = 1; i <= m; i++) {       int q, x;       scanf( %d%d , &q, &x);       if (q == 1) {         updata(1, n, 1, w[x], i);       } else if (q == 2) {         updata2(1, n, 1, w[x], -1 * i);       } else {         int zs = query2(1, n, 1, w[x], we[x]);         int zx = solve(1, x);         if (zx + zs > 0) {           printf( 1 n );         } else           printf( 0 n );       }     }   }