#include <bits/stdc++.h>
using namespace std;
struct tree {
  int le, ri, la;
  bool p;
} a[4000000];
vector<int> ve[500010];
int b[500010], c[500010], d, e, f, g, h, i, j = 0, pre[500010];
void dfs(int q, int w) {
  b[q] = ++e;
  if (ve[q].size())
    for (int m = 0; m <= ve[q].size() - 1; m++)
      if (ve[q][m] != w) pre[ve[q][m]] = q, dfs(ve[q][m], q);
  c[q] = e;
}
void build(int q, int w, int e) {
  a[q].le = w;
  a[q].ri = e;
  a[q].la = 0;
  a[q].p = 1;
  if (w == e) return;
  build(q * 2, w, (w + e) / 2);
  build(q * 2 + 1, (w + e) / 2 + 1, e);
}
void update(int q, int w, int e) {
  if (a[q].le > e || a[q].ri < w || a[q].la) return;
  if (a[q].le >= w && a[q].ri <= e) {
    if (a[q].le != a[q].ri) a[q].la = 1;
    a[q].p = 0;
    return;
  }
  update(q * 2, w, e);
  update(q * 2 + 1, w, e);
  a[q].p = a[q * 2].p || a[q * 2 + 1].p;
}
void update1(int q, int w) {
  if (a[q].ri < w || a[q].le > w) return;
  a[q].p = 1;
  if (a[q].ri == a[q].le) return;
  if (a[q].la) {
    if (a[q * 2].ri != a[q * 2].le) a[q * 2].la = 1;
    if (a[q * 2 + 1].ri != a[q * 2 + 1].le) a[q * 2 + 1].la = 1;
    a[q].la = 0;
    a[q * 2].p = 0;
    a[q * 2 + 1].p = 0;
  }
  update1(q * 2, w);
  update1(q * 2 + 1, w);
}
bool query(int q, int w, int e) {
  if (a[q].le > e || a[q].ri < w || a[q].p == 0) return 0;
  if (a[q].le >= w && a[q].ri <= e) return 1;
  return query(q * 2, w, e) || query(q * 2 + 1, w, e);
}
int main() {
  cin >> d;
  for (int m = 1; m <= d - 1; m++) {
    scanf("%d%d", &e, &f);
    ve[f].push_back(e);
    ve[e].push_back(f);
  }
  e = 0;
  dfs(1, 0);
  build(1, 1, d);
  cin >> e;
  for (int m = 1; m <= e; m++) {
    scanf("%d%d", &f, &g);
    if (f == 1) {
      if (g > 1 && query(1, b[g], c[g])) update1(1, b[pre[g]]);
      update(1, b[g], c[g]);
    } else if (f == 2)
      update1(1, b[g]);
    else if (query(1, b[g], c[g]))
      printf("0\n");
    else
      printf("1\n");
  }
  return 0;
}
