#include <bits/stdc++.h>
using namespace std;
template <typename T>
T gcd(T a, T b) {
  return !b ? a : gcd(b, a % b);
}
template <typename T>
T lcm(T a, T b) {
  return a * (b / gcd(a, b));
}
template <typename T>
T sqr(T a) {
  return a * a;
}
template <typename T>
T cube(T a) {
  return a * a * a;
}
template <typename T>
inline void smin(T &a, T b) {
  a = a < b ? a : b;
}
template <typename T>
inline void smax(T &a, T b) {
  a = a > b ? a : b;
}
template <typename T>
void fill(T a[], T n, T b) {
  for (int i = 0; i <= n; i++) a[i] = b;
}
int in() {
  int n;
  scanf("%d", &n);
  return n;
}
long long Lin() {
  long long n;
  scanf("%lld", &n);
  return n;
}
double Din() {
  double n;
  scanf("%lf", &n);
  return n;
}
const long long inf = (long long)1e17;
const long long mod = (long long)1e9 + 7;
const int N = 5e5 + 5;
vector<int> g[N];
int st[N], et[N], t;
void dfs(int u, int p = -1) {
  st[u] = ++t;
  for (auto v : g[u]) {
    if (p != v) dfs(v, u);
  }
  et[u] = t;
}
struct segment_tree {
  vector<int> tree, prop;
  segment_tree(int n) {
    tree = vector<int>(4 * n), prop = vector<int>(4 * n);
    for (int i = 1; i < 4 * n; i++) {
      tree[i] = 0, prop[i] = 0;
    }
  }
  void propagate(int pos) {
    tree[pos * 2] = prop[pos];
    tree[pos * 2 + 1] = prop[pos];
    prop[pos * 2] = prop[pos];
    prop[pos * 2 + 1] = prop[pos];
    prop[pos] = 0;
  }
  void update(int pos, int left, int right, int x, int y, int val) {
    if (left > y || right < x) return;
    if (left >= x && right <= y) {
      tree[pos] = val;
      prop[pos] = val;
      return;
    }
    if (prop[pos]) propagate(pos);
    int mid = (left + right) >> 1;
    update(pos * 2, left, mid, x, y, val);
    update(pos * 2 + 1, mid + 1, right, x, y, val);
    tree[pos] = max(tree[pos * 2], tree[pos * 2 + 1]);
  }
  int query(int pos, int left, int right, int x, int y) {
    if (left > y || right < x) return INT_MIN;
    if (left >= x && right <= y) return tree[pos];
    if (prop[pos]) propagate(pos);
    int mid = (left + right) >> 1;
    int m = query(pos * 2, left, mid, x, y);
    int n = query(pos * 2 + 1, mid + 1, right, x, y);
    return max(m, n);
  }
};
int solve() {
  int n = in();
  for (int i = 1; i < n; i++) {
    int u = in(), v = in();
    g[u].push_back(v);
    g[v].push_back(u);
  }
  dfs(1);
  segment_tree fl(t), emt(t);
  int q = in();
  for (int i = 1; i <= q; i++) {
    int ck = in(), u = in();
    if (ck == 1)
      fl.update(1, 1, n, st[u], et[u], i);
    else if (ck == 2)
      emt.update(1, 1, n, st[u], st[u], i);
    else {
      int x = fl.query(1, 1, n, st[u], st[u]);
      int y = emt.query(1, 1, n, st[u], et[u]);
      if (x > y)
        printf("1\n");
      else
        printf("0\n");
    }
  }
  return 0;
}
int main() {
  int test = 1, tc = 0;
  while (test--) {
    solve();
  }
  return 0;
}
