#include <bits/stdc++.h>
#pragma GCC optimize(2)
using namespace std;
const int N = 1e6 + 10;
inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch <= '9' && ch >= '0') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
struct Tree {
  int l, r, v, lz;
} tree[N * 4];
int n, m, ct, w[N], head[N], nxt[N], to[N];
void addedge(int x, int y) {
  nxt[++ct] = head[x];
  head[x] = ct;
  to[ct] = y;
}
int siz[N], dep[N], son[N], fa[N];
void pre(int u, int f) {
  siz[u] = 1;
  dep[u] = dep[f] + 1;
  fa[u] = f;
  int mx = -1;
  for (int i = head[u]; i; i = nxt[i]) {
    int y = to[i];
    if (y == f) continue;
    pre(y, u);
    siz[u] += siz[y];
    if (siz[y] > mx) {
      son[u] = y;
      mx = siz[y];
    }
  }
}
int dfn[N], top[N], tim;
long long a[N];
void dfs(int u, int tp) {
  dfn[u] = ++tim;
  top[u] = tp;
  a[tim] = w[u];
  if (!son[u]) return;
  dfs(son[u], tp);
  for (int i = head[u]; i; i = nxt[i]) {
    int y = to[i];
    if (y == fa[u] || y == son[u]) continue;
    dfs(y, y);
  }
}
void build(int i, int l, int r) {
  tree[i].l = l;
  tree[i].r = r;
  tree[i].lz = -1;
  if (l >= r) {
    tree[i].lz = -1;
    tree[i].v = 0;
    return;
  }
  int mid = l + r >> 1;
  build(2 * i, l, mid);
  build(2 * i + 1, mid + 1, r);
}
void push_down(int i) {
  int lz = tree[i].lz;
  if (lz != -1) {
    tree[i].lz = -1;
    tree[2 * i].v = lz;
    tree[2 * i + 1].v = lz;
    tree[2 * i].lz = lz;
    tree[2 * i + 1].lz = lz;
  }
}
void change(int i, int l, int r, int v) {
  if (tree[i].l >= l && tree[i].r <= r) {
    tree[i].v = v;
    tree[i].lz = v;
    return;
  }
  push_down(i);
  int mid = tree[i].l + tree[i].r >> 1;
  if (r <= mid)
    change(2 * i, l, r, v);
  else if (l > mid)
    change(2 * i + 1, l, r, v);
  else {
    change(2 * i, l, mid, v);
    change(2 * i + 1, mid + 1, r, v);
  }
}
int query(int i, int p) {
  if (tree[i].l == p && tree[i].r == p) return tree[i].v;
  push_down(i);
  int mid = tree[i].l + tree[i].r >> 1;
  if (p <= mid)
    return query(2 * i, p);
  else
    return query(2 * i + 1, p);
}
void rchange(int x, int y) {
  while (top[x] != top[y]) {
    if (dep[top[x]] < dep[top[y]]) swap(x, y);
    change(1, dfn[top[x]], dfn[x], 0);
    x = fa[x];
  }
  if (dep[x] > dep[y]) swap(x, y);
  change(1, dfn[x], dfn[y], 0);
}
int main() {
  n = read();
  for (int i = 1; i <= n - 1; ++i) {
    int x, y;
    x = read();
    y = read();
    addedge(x, y);
    addedge(y, x);
  }
  m = read();
  pre(1, 1);
  dfs(1, 1);
  build(1, 1, tim);
  for (int i = 1; i <= m; ++i) {
    int op, p;
    op = read();
    p = read();
    if (op == 1) {
      change(1, dfn[p], dfn[p] + siz[p] - 1, 1);
    } else if (op == 2) {
      rchange(1, p);
    } else {
      if (query(1, dfn[p]))
        puts("1");
      else
        puts("0");
    }
  }
  return 0;
}
