#include <bits/stdc++.h>   using namespace std;   const int N = 500005;   const int mod = 998244353;   const long long int inf = 10e17;   const long double pi = 3.14159265359;   mt19937_64 rang(       chrono::high_resolution_clock::now().time_since_epoch().count());   int rng(int lim) {     uniform_int_distribution<int> uid(0, lim - 1);     return uid(rang);   }   void fastIO(void);   void decimal(int);   int modmulti(int, int);   int modadd(int, int);   int modpower(int, int);   int gcd(int, int);   int modinv(int);   vector<int> parent, depth, heavy, head, pos, tin, tout;   int cur_pos;   int lazy1[4 * N], lazy2[8 * N];   int timer, l;   vector<vector<int>> up;   int dfs(int v, vector<vector<int>> const& g) {     int size = 1;     tin[v] = ++timer;     up[v][0] = parent[v];     for (int i = 1; i < l + 1; i++) {       up[v][i] = up[up[v][i - 1]][i - 1];     }     int max_c_size = 0;     for (int c : g[v]) {       if (c != parent[v]) {         parent[c] = v;         depth[c] = depth[v] + 1;         int c_size = dfs(c, g);         if (c_size > max_c_size) {           max_c_size = c_size;           heavy[v] = c;         }         size += c_size;       }     }     tout[v] = ++timer;     return size;   }   bool is_ancestor(int u, int v) {     return tin[u] <= tin[v] && tout[u] >= tout[v];   }   int lca(int u, int v) {     if (is_ancestor(u, v)) return u;     if (is_ancestor(v, u)) return v;     for (int i = l; i >= 0; --i) {       if (!is_ancestor(up[u][i], v)) u = up[u][i];     }     return up[u][0];   }   void decompose(int v, int h, vector<vector<int>> const& g) {     head[v] = h;     pos[v] = cur_pos++;     if (heavy[v] != -1) {       decompose(heavy[v], h, g);     }     for (int c : g[v]) {       if (c != parent[v] && c != heavy[v]) decompose(c, c, g);     }   }   void init(vector<vector<int>> const& g) {     int n = g.size();     parent = vector<int>(n);     depth = vector<int>(n);     heavy = vector<int>(n, -1);     head = vector<int>(n);     pos = vector<int>(n);     tin = vector<int>(n);     tout = vector<int>(n);     timer = 0;     l = ceil(log2(n));     up.assign(n, vector<int>(l + 1));     cur_pos = 0;     dfs(0, g);     decompose(0, 0, g);   }   void update1(int node, int l, int r, int st, int ed, int val) {     if (l == st && r == ed) {       lazy1[node] = val;       return;     }     int m = (l + r) / 2;     if (ed <= m) {       update1(2 * node + 1, l, m, st, ed, val);       return;     }     if (st > m) {       update1(2 * node + 2, m + 1, r, st, ed, val);       return;     }     update1(2 * node + 1, l, m, st, m, val);     update1(2 * node + 2, m + 1, r, m + 1, ed, val);     return;   }   void update2(int node, int l, int r, int st, int ed, int val) {     if (l == st && r == ed) {       lazy2[node] = val;       return;     }     int m = (l + r) / 2;     if (ed <= m) {       update2(2 * node + 1, l, m, st, ed, val);       return;     }     if (st > m) {       update2(2 * node + 2, m + 1, r, st, ed, val);       return;     }     update2(2 * node + 1, l, m, st, m, val);     update2(2 * node + 2, m + 1, r, m + 1, ed, val);     return;   }   void update(int b, int val, int n) {     int a = 0;     for (; head[a] != head[b]; b = parent[head[b]]) {       if (depth[head[a]] > depth[head[b]]) swap(a, b);       update1(0, 0, n - 1, pos[head[b]], pos[b], val);     }     update1(0, 0, n - 1, pos[a], pos[b], val);     return;   }   int query1(int node, int l, int r, int pos) {     if (l == r) {       return lazy1[node];     }     lazy1[2 * node + 1] = max(lazy1[node], lazy1[2 * node + 1]);     lazy1[2 * node + 2] = max(lazy1[node], lazy1[2 * node + 2]);     int m = (l + r) / 2;     if (pos <= m) return query1(2 * node + 1, l, m, pos);     return query1(2 * node + 2, m + 1, r, pos);   }   int query2(int node, int l, int r, int pos) {     if (l == r) {       return lazy2[node];     }     lazy2[2 * node + 1] = max(lazy2[node], lazy2[2 * node + 1]);     lazy2[2 * node + 2] = max(lazy2[node], lazy2[2 * node + 2]);     int m = (l + r) / 2;     if (pos <= m) return query2(2 * node + 1, l, m, pos);     return query2(2 * node + 2, m + 1, r, pos);   }   int main() {     fastIO();     int n;     cin >> n;     vector<vector<int>> g(n);     for (int i = 0; i < n - 1; i++) {       int u, v;       cin >> u >> v;       u--;       v--;       g[u].push_back(v);       g[v].push_back(u);     }     init(g);     int m;     cin >> m;     int cnt = 0;     for (int m1 = 1; m1 < m + 1; m1++) {       int a, b;       cin >> a >> b;       b--;       if (a == 1) {         update2(0, 1, 2 * n, tin[b], tout[b], m1);       } else if (a == 2) {         update(b, m1, n);       } else {         cnt++;         int q1, q2;         q1 = query1(0, 0, n - 1, pos[b]);         q2 = query2(0, 1, 2 * n, tin[b]);         if (q1 >= q2)           cout << 0 <<   n ;         else           cout << 1 <<   n ;       }     }   }   void fastIO(void) {     ios_base::sync_with_stdio(false);     cin.tie(0);     cout.tie(0);   }   void decimal(int n) {     cout << fixed;     cout << setprecision(n);   }   int modmulti(int a, int b) { return ((a % mod) * 1ll * (b % mod)) % mod; }   int modadd(int a, int b) {     a = a % mod;     a = (a + mod) % mod;     b = b % mod;     b = (b + mod) % mod;     return (a + b) % mod;   }   int modpower(int a, int n) {     if (n == 0) return 1;     if (n == 1) return a % mod;     int b = modpower(a, n / 2);     b = modmulti(b, b);     if (n % 2 == 0) return b;     return modmulti(a, b);   }   int gcd(int a, int b) {     if (b == 0) return a;     return gcd(b, a % b);   }   int modinv(int a) { return modpower(a, mod - 2); }