#include <bits/stdc++.h>
using namespace std;
const int M = 1000000007;
const int MM = 998244353;
const long double PI = acos(-1);
long long power(long long b, long long e, long long m) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b % m, e / 2, m) % m;
  return power(b * b % m, e / 2, m);
}
long long power(long long b, long long e) {
  if (e == 0) return 1;
  if (e & 1) return b * power(b * b, e / 2);
  return power(b * b, e / 2);
}
template <typename T, typename U>
static inline void amin(T &x, U y) {
  if (y < x) x = y;
}
template <typename T, typename U>
static inline void amax(T &x, U y) {
  if (x < y) x = y;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << '(' << p.first << "," << p.second << ')';
}
const int N = 100005;
struct node {
  long long sum;
} fake = {0};
struct SEGTREE {
  long long a[N];
  SEGTREE() { memset(a, 0, sizeof(a)); }
  node tree[4 * N];
  long long lazy[4 * N];
  inline node combine(node a, node b) {
    node ret;
    ret.sum = a.sum + b.sum;
    return ret;
  }
  inline node make_node(long long val) {
    node ret;
    ret.sum = val;
    return ret;
  }
  inline void pushdown(long long v, long long st, long long en) {
    tree[v].sum += (en - st + 1) * lazy[v];
    if (st != en) {
      lazy[v << 1] += lazy[v];
      lazy[v << 1 | 1] += lazy[v];
    }
    lazy[v] = 0;
    return;
  }
  void buildTree(long long v, long long st, long long en) {
    if (st == en) {
      tree[v] = make_node(a[st]);
      return;
    }
    long long mid = (st + en) >> 1;
    buildTree(v << 1, st, mid);
    buildTree(v << 1 | 1, mid + 1, en);
    tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
  }
  void update(long long v, long long st, long long en, long long in,
              long long val) {
    long long mid = (st + en) >> 1;
    if (st == en) {
      tree[v] = make_node(val);
      a[st] = val;
      return;
    }
    if (in <= mid)
      update(v << 1, st, mid, in, val);
    else
      update(v << 1 | 1, mid + 1, en, in, val);
    tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
  }
  void rupdate(long long v, long long st, long long en, long long l,
               long long r, long long val) {
    if (lazy[v] != 0) {
      pushdown(v, st, en);
    }
    if (en < l || st > r) return;
    if (st >= l && en <= r) {
      lazy[v] = val;
      pushdown(v, st, en);
      return;
    }
    long long mid = (st + en) >> 1;
    rupdate(v << 1, st, mid, l, r, val);
    rupdate(v << 1 | 1, mid + 1, en, l, r, val);
    tree[v] = combine(tree[v << 1], tree[v << 1 | 1]);
  }
  node query(long long v, long long st, long long en, long long l,
             long long r) {
    if (en < l || st > r) return fake;
    if (lazy[v] != 0) {
      pushdown(v, st, en);
    }
    if (st >= l && en <= r) return tree[v];
    long long mid = (st + en) >> 1;
    return combine(query(v << 1, st, mid, l, r),
                   query(v << 1 | 1, mid + 1, en, l, r));
  }
} seg;
const int LOGN = 20;
vector<pair<int, int>> v[N];
int n;
vector<int> roots;
int cmp[N], cno = 1;
int sub[N], dep[N], par[N][LOGN];
void dfs_size(int s = 1, int p = -1) {
  sub[s] = 1;
  cmp[s] = cno;
  for (auto j : v[s]) {
    if (j.first != p) {
      dep[j.first] = dep[s] + 1;
      par[j.first][0] = s;
      dfs_size(j.first, s);
      sub[s] += sub[j.first];
    }
  }
}
void sparseMatrix(long long n) {
  for (long long i = 1; i < LOGN; ++i)
    for (long long j = 1; j <= n; ++j) par[j][i] = par[par[j][i - 1]][i - 1];
}
long long lca(long long u, long long v) {
  if (dep[u] > dep[v]) swap(u, v);
  long long df = dep[v] - dep[u];
  for (long long i = 0; i < LOGN; ++i)
    if (df & (1 << i)) v = par[v][i];
  if (u == v) return u;
  for (long long i = LOGN - 1; i >= 0; i--) {
    if (par[u][i] != par[v][i]) {
      u = par[u][i];
      v = par[v][i];
    }
  }
  return par[u][0];
}
int head[N], pos[N], in[N], out[N], cur = 0;
void hld(int s, int p, int h, int w) {
  head[s] = h;
  int hv = -1, mx = -1;
  pos[s] = cur++;
  seg.a[pos[s]] = w;
  in[s] = pos[s];
  int pass = -1;
  for (auto j : v[s])
    if (j.first != p)
      if (sub[j.first] > mx) mx = sub[j.first], hv = j.first, pass = j.second;
  if (hv != -1) hld(hv, s, h, pass);
  for (auto j : v[s])
    if (j.first != p && j.first != hv) hld(j.first, s, j.first, j.second);
  out[s] = cur - 1;
}
int query(int a, int b) {
  int ans = 0;
  for (; head[a] != head[b]; b = par[head[b]][0]) {
    if (dep[head[a]] > dep[head[b]]) swap(a, b);
    ans += seg.query(1, 0, n - 1, pos[head[b]], pos[b]).sum;
  }
  if (dep[a] > dep[b]) swap(a, b);
  ans += seg.query(1, 0, n - 1, pos[a] + 1, pos[b]).sum;
  return ans;
}
int _runtimeTerror_() {
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    int pp, tt;
    cin >> pp >> tt;
    if (pp == -1)
      roots.push_back(i);
    else {
      tt ^= 1;
      v[pp].push_back({i, tt});
      v[i].push_back({pp, tt});
    }
  }
  for (auto k : roots) {
    dfs_size(k, 0);
    hld(k, 0, k, 0);
    ++cno;
  }
  sparseMatrix(n);
  seg.buildTree(1, 0, n - 1);
  assert(cur == n);
  int q;
  cin >> q;
  while (q--) {
    int tt, x, y;
    cin >> tt >> x >> y;
    if (cmp[x] != cmp[y] || x == y) {
      cout << "NO\n";
      continue;
    }
    int l = lca(x, y);
    if (tt == 1) {
      if (l != x) {
        cout << "NO\n";
        continue;
      }
      int xx = query(y, x);
      if (xx == dep[y] - dep[x])
        cout << "YES\n";
      else
        cout << "NO\n";
    } else if (tt == 2) {
      int xx = query(y, l);
      int yy = query(x, l);
      if (l != y && xx == 0 && yy == dep[x] - dep[l])
        cout << "YES\n";
      else
        cout << "NO\n";
    }
  }
  return 0;
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int TESTS = 1;
  while (TESTS--) _runtimeTerror_();
  return 0;
}
