#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 5;
const int INF = 1e17;
int a[maxn], ans[maxn << 2], lazy[maxn << 2];
int n, m, t;
inline void update(int k) { ans[k] = ans[k << 1] + ans[k << 1 | 1]; }
inline void push_down(int x, int l, int r) {
  if (lazy[x] == -1) return;
  int mid = (l + r) >> 1;
  lazy[x << 1] = lazy[x << 1 | 1] = lazy[x];
  ans[x << 1] = lazy[x] * (mid - l + 1);
  ans[x << 1 | 1] = lazy[x] * (r - mid);
  lazy[x] = -1;
}
void build(int rt, int l, int r) {
  lazy[rt] = -1;
  if (l == r) {
    ans[rt] = a[l];
    return;
  }
  int mid = (l + r) >> 1;
  build(rt << 1, l, mid);
  build(rt << 1 | 1, mid + 1, r);
  update(rt);
}
void modify(int rt, int l, int r, int ql, int qr, int w) {
  if (ql <= l && r <= qr) {
    ans[rt] = w * (r - l + 1);
    lazy[rt] = w;
    return;
  }
  push_down(rt, l, r);
  int mid = (r + l) >> 1;
  if (ql <= mid) modify(rt << 1, l, mid, ql, qr, w);
  if (qr > mid) modify(rt << 1 | 1, mid + 1, r, ql, qr, w);
  update(rt);
}
int query(int rt, int l, int r, int ql, int qr) {
  int res = 0;
  if (ql <= l && r <= qr) return ans[rt];
  push_down(rt, l, r);
  int mid = (r + l) >> 1;
  if (ql <= mid) res += query(rt << 1, l, mid, ql, qr);
  if (qr > mid) res += query(rt << 1 | 1, mid + 1, r, ql, qr);
  return res;
}
struct edge {
  int next, to;
} E[maxn + maxn];
int tot = 0, cnt = 0, head[maxn];
int d[maxn], fa[maxn], size[maxn], son[maxn];
int top[maxn], id1[maxn], rk[maxn], id2[maxn];
void addedge(int u, int v) {
  E[++tot].to = v;
  E[tot].next = head[u];
  head[u] = tot;
}
void dfs1(int x) {
  size[x] = 1;
  d[x] = d[fa[x]] + 1;
  for (int i = head[x]; i; i = E[i].next) {
    if (E[i].to != fa[x]) {
      fa[E[i].to] = x;
      dfs1(E[i].to);
      size[x] += size[E[i].to];
      if (size[E[i].to] > size[son[x]]) son[x] = E[i].to;
    }
  }
}
void dfs2(int x, int tp) {
  id1[x] = ++cnt;
  rk[cnt] = x;
  top[x] = tp;
  if (son[x]) dfs2(son[x], tp);
  for (int i = head[x]; i; i = E[i].next) {
    if (E[i].to != fa[x] && E[i].to != son[x]) dfs2(E[i].to, E[i].to);
  }
  id2[x] = cnt;
}
int lca(int x, int y) {
  while (top[x] != top[y]) {
    if (d[top[x]] < d[top[y]]) swap(x, y);
    x = fa[top[x]];
  }
  return d[x] < d[y] ? x : y;
}
int lca2(int x, int y) {
  int t;
  while (top[x] != top[y]) t = top[y], y = fa[top[y]];
  return x == y ? t : son[x];
}
void fillwater(int u) { modify(1, 1, n, id1[u], id1[u] + size[u] - 1, 1); }
void emptywater(int u) {
  for (; top[u] != top[1]; u = fa[top[u]]) {
    modify(1, 1, n, id1[top[u]], id1[u], 0);
  }
  modify(1, 1, n, id1[1], id1[u], 0);
}
int querywater(int u) { return query(1, 1, n, id1[u], id1[u]); }
int main() {
  cin >> n;
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    addedge(u, v);
    addedge(v, u);
  }
  dfs1(1);
  dfs2(1, 1);
  int q;
  cin >> q;
  for (int i = 1; i <= q; i++) {
    int opt, u;
    scanf("%d%d", &opt, &u);
    if (opt == 1) {
      fillwater(u);
    } else if (opt == 2) {
      emptywater(u);
    } else if (opt == 3) {
      int ans = querywater(u);
      printf("%d\n", ans);
    }
  }
}
