#include <bits/stdc++.h>
#pragma optimize("SEX_ON_THE_BEACH")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("fast-math")
using ll = long long int;
using ull = long long int;
using dd = double;
using ldd = long double;
namespace someUsefull {
template <typename T1, typename T2>
inline void checkMin(T1& a, T2 b) {
  if (a > b) a = b;
}
template <typename T1, typename T2>
inline void checkMax(T1& a, T2 b) {
  if (a < b) a = b;
}
const int _popcount_size_ = 16;
char _bits_count_[1 << _popcount_size_];
inline void _build_bits_count_() {
  for (int i = 1, j = 0; i < (1 << _popcount_size_); ++i) {
    if (i & (1 << (j + 1))) ++j;
    _bits_count_[i] = _bits_count_[i ^ (1 << j)] + 1;
  }
}
template <typename T1 = int, typename T2 = int>
inline T1 popcnt(T2 x) {
  T1 ans = 0;
  while (x) {
    ans += _bits_count_[x & (1 << _popcount_size_) - 1];
    x >>= _popcount_size_;
  }
  return ans;
}
}  // namespace someUsefull
using namespace std;
using namespace someUsefull;
int _size = 1 << 20;
vector<int> tree(_size << 1);
vector<vector<int>> gr(_size);
vector<int> euler;
vector<int> pos(_size);
vector<int> tin(_size), tout(_size);
vector<int> pre(_size);
void dfs(int v, int p = -1) {
  pre[v] = p;
  tin[v] = euler.size();
  euler.push_back(v);
  for (int to : gr[v])
    if (to != p) dfs(to, v);
  tout[v] = euler.size();
}
void add(int v, int l, int r, int fl, int fr) {
  if (r <= l || fr <= l || r <= fl || tree[v]) return;
  if (fl <= l && r <= fr) return void(tree[v] = 1);
  add(v << 1, l, (r + l) >> 1, fl, fr);
  add(v << 1 | 1, (r + l) >> 1, r, fl, fr);
  tree[v] = tree[v << 1] & tree[v << 1 | 1];
}
void del(int v, int l, int r, int pos) {
  if (l + 1 == r) return void(tree[v] = 0);
  if (tree[v]) {
    tree[v << 1] = tree[v << 1 | 1] = 1;
    tree[v] = 0;
  }
  if (pos < ((r + l) >> 1))
    del(v << 1, l, (r + l) >> 1, pos);
  else
    del(v << 1 | 1, (r + l) >> 1, r, pos);
}
int get(int v, int l, int r, int fl, int fr) {
  if (r <= l || fr <= l || r <= fl || tree[v]) return 1;
  if (fl <= l && r <= fr) return tree[v];
  return get(v << 1, l, (r + l) >> 1, fl, fr) &
         get(v << 1 | 1, (r + l) >> 1, r, fl, fr);
}
void solve(int test) {
  int n;
  cin >> n;
  for (int i = 0; i < n - 1; ++i) {
    int a, b;
    cin >> a >> b;
    --a;
    --b;
    gr[a].push_back(b);
    gr[b].push_back(a);
  }
  dfs(0);
  for (int i = 0; i < euler.size(); ++i) pos[euler[i]] = i;
  set<int> curr;
  for (int i = 0; i < n; ++i) curr.insert(i);
  int q;
  cin >> q;
  for (int i = 0; i < q; ++i) {
    int t;
    int v;
    cin >> t >> v;
    --v;
    if (t == 1) {
      auto x = curr.lower_bound(tin[v]);
      int c = 0;
      while (x != curr.end() && *x < tout[v]) {
        c = 1;
        auto y = x;
        y++;
        curr.erase(x);
        x = y;
      }
      if (c && pre[v] != -1) {
        curr.insert(pos[pre[v]]);
      }
    } else if (t == 2) {
      curr.insert(pos[v]);
    } else {
      auto x = curr.lower_bound(tin[v]);
      if (x != curr.end() && *x < tout[v])
        cout << 0 << '\n';
      else
        cout << 1 << '\n';
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(false);
  cout.tie(0);
  cin.tie(0);
  _build_bits_count_();
  int t = 1;
  for (int i = 0; i < t; ++i) {
    solve(i + 1);
  }
  return 0;
}
