#include <bits/stdc++.h>
using namespace std;
int const maxn = 5e5 + 10, INF = 1e9;
int fa[maxn], top[maxn], id[maxn], rk[maxn], tson[maxn], nodetot, hson[maxn],
    head[maxn], n, m, val[maxn], tot, deep[maxn];
int sgt[maxn << 2], delta[maxn << 2];
struct edge {
  int v, nxt;
} e[maxn << 1];
struct edgevalue {
  int u, v, w;
} ev[maxn];
void build(int x, int y) {
  e[++tot].v = y;
  e[tot].nxt = head[x];
  head[x] = tot;
}
void init() {
  tot = 0;
  nodetot = 0;
  memset(head, 0, sizeof(int) * (n + 5));
  memset(hson, 0, sizeof(int) * (n + 5));
  memset(val, 0, sizeof(int) * (n + 5));
  memset(sgt, 0, sizeof(int) * (n * 4));
}
void TreeSplitDfs1(int x, int f, int d) {
  deep[x] = d;
  tson[x] = 1;
  fa[x] = f;
  for (int i = head[x]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == f) continue;
    TreeSplitDfs1(v, x, d + 1);
    tson[x] += tson[v];
    if (!hson[x] || tson[v] > tson[hson[x]]) {
      hson[x] = v;
    }
  }
}
void TreeSplitDfs2(int x, int f) {
  top[x] = f;
  id[x] = ++nodetot;
  rk[nodetot] = x;
  if (!hson[x]) return;
  TreeSplitDfs2(hson[x], f);
  for (int i = head[x]; i; i = e[i].nxt) {
    int v = e[i].v;
    if (v == fa[x] || v == hson[x]) continue;
    TreeSplitDfs2(v, v);
  }
}
void BuildSgTree(int l, int r, int x) {
  if (l == r) {
    sgt[x] = 0;
    delta[x] = -1;
    return;
  }
  delta[x] = -1;
  int mid = (l + r) >> 1;
  BuildSgTree(l, mid, x << 1);
  BuildSgTree(mid + 1, r, (x << 1) | 1);
}
void pushdown(int x, int l, int r, int mid) {
  if (delta[x] != -1) {
    sgt[x << 1] = delta[x];
    delta[x << 1] = delta[x];
    sgt[(x << 1) + 1] = delta[x];
    delta[(x << 1) + 1] = delta[x];
    delta[x] = -1;
  }
}
void IntervalChange(int l, int r, int x, int lrange, int rrange, int v) {
  int mid = (l + r) >> 1;
  pushdown(x, l, r, mid);
  if (lrange <= l && rrange >= r) {
    sgt[x] = v;
    delta[x] = v;
    return;
  }
  if (lrange <= mid) IntervalChange(l, mid, x << 1, lrange, rrange, v);
  if (rrange > mid) IntervalChange(mid + 1, r, (x << 1) | 1, lrange, rrange, v);
}
int thisans = 0;
void PointQuery(int pos, int l, int r, int x) {
  int mid = (l + r) >> 1;
  pushdown(x, l, r, mid);
  if (pos == l && pos == r) {
    thisans = sgt[x];
    return;
  }
  if (pos <= mid)
    PointQuery(pos, l, mid, x << 1);
  else
    PointQuery(pos, mid + 1, r, (x << 1) | 1);
}
int main() {
  scanf("%d", &n);
  init();
  int a, b;
  for (int i = 1; i < n; i++) {
    scanf("%d%d", &a, &b);
    build(a, b);
    build(b, a);
  }
  TreeSplitDfs1(1, -1, 0);
  TreeSplitDfs2(1, 1);
  BuildSgTree(1, n, 1);
  int qnum, qf, qn;
  scanf("%d", &qnum);
  while (qnum--) {
    scanf("%d%d", &qf, &qn);
    if (qf == 1) {
      IntervalChange(1, n, 1, id[qn], id[qn] + tson[qn] - 1, 1);
    } else if (qf == 2) {
      while (qn != -1) {
        IntervalChange(1, n, 1, id[top[qn]], id[qn], 0);
        qn = fa[top[qn]];
      }
    } else {
      PointQuery(id[qn], 1, n, 1);
      printf("%d\n", thisans);
    }
  }
  return 0;
}
