#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
template <class T>
using vv = vector<vector<T>>;
template <class T>
inline bool MX(T &l, const T &r) {
  return l < r ? l = r, 1 : 0;
}
template <class T>
inline bool MN(T &l, const T &r) {
  return l > r ? l = r, 1 : 0;
}
const ll MOD = 1e9 + 7;
template <class T>
class RMQ {
  vv<T> vals;

 public:
  inline T get(int l, int r) {
    if (l == r) return vals[0][l];
    const int d = 31 - __builtin_clz(l ^ r);
    return min(vals[d][l], vals[d][r]);
  }
  RMQ(){};
  RMQ(vector<T> &v, T e = -MOD) { init(v, e); }
  void init(vector<T> &v, T e) {
    int n = v.size();
    int d = 1, N = 2;
    while (N < n) N *= 2, ++d;
    vals.resize(d, vector<T>(N, e));
    for (int(i) = 0; (i) < (int)(n); ++(i)) vals[0][i] = v[i];
    for (int(i) = (int)(1); (i) < (int)(d); ++(i))
      for (int(j) = 0; (j) < (int)(N); ++(j)) {
        const int b = (j >> i | 1) << i;
        vals[i][j] = j >> i & 1 ? get(b, j) : get(j, b - 1);
      }
  }
};
class Lca {
 public:
  vector<int> dep, cld;
  vector<pii> et;
  vector<int> l, r;
  vector<ll> wdep;
  vector<int> par;
  int weighted;
  vv<int> wei;
  RMQ<pii> rmq;
  void dfs(const vv<int> &g, int root) {
    int n = g.size();
    vector<int> vst(n);
    stack<int> st;
    st.push(root);
    while (!st.empty()) {
      int v = st.top();
      st.pop();
      if (vst[v] == 1) {
        vst[v] = 2;
        r[v] = et.size() - 1;
        for (int(i) = 0; (i) < (int)(g[v].size()); ++(i))
          if (g[v][i] != par[v]) cld[v] += cld[g[v][i]] + 1;
        if (par[v] >= 0) et.emplace_back(dep[par[v]], par[v]);
      } else if (vst[v] == 0) {
        st.push(v);
        vst[v] = 1;
        l[v] = et.size();
        et.emplace_back(dep[v], v);
        for (int(i) = 0; (i) < (int)(g[v].size()); ++(i))
          if (!vst[g[v][i]]) {
            dep[g[v][i]] = dep[v] + 1;
            wdep[g[v][i]] = wdep[v] + (weighted ? wei[v][i] : 1);
            par[g[v][i]] = v;
            st.push(g[v][i]);
          }
      }
    }
  }
  Lca(const vv<int> &g, int root) : weighted(0) {
    int n = g.size();
    par.resize(n);
    dep.resize(n);
    wdep.resize(n);
    cld.resize(n);
    l.resize(n);
    r.resize(n);
    dfs(g, root);
    rmq.init(et, pii(MOD, 0));
  }
  Lca(const vv<pii> &h) : weighted(1) {
    int n = h.size();
    vv<int> g(n);
    wei.resize(n);
    for (int(i) = 0; (i) < (int)(n); ++(i))
      for (pii x : h[i]) {
        g[i].push_back(x.first);
        wei[i].push_back(x.second);
      }
    par.resize(n);
    dep.resize(n);
    wdep.resize(n);
    cld.resize(n);
    l.resize(n);
    r.resize(n);
    dfs(g, 0);
    rmq.init(et, pii(MOD, 0));
  }
  int LCA(int v, int w) {
    v = l[v];
    w = l[w];
    if (v > w) swap(v, w);
    return rmq.get(v, w).second;
  }
  ll dist(int v, int w) { return wdep[v] + wdep[w] - 2 * wdep[LCA(v, w)]; }
  vector<int> pathp(int v, int p) {
    vector<int> re;
    ;
    for (int i = v; i != p; i = par[i]) re.push_back(i);
    re.push_back(p);
    return re;
  }
  vector<int> path(int v, int w) {
    int p = LCA(v, w);
    vector<int> a = pathp(v, p);
    vector<int> b = pathp(w, p);
    b.pop_back();
    reverse((b).begin(), (b).end());
    a.insert(a.end(), (b).begin(), (b).end());
    return a;
  }
};
struct UF {
  vector<int> data;
  UF(int size) : data(size, -1) {}
  bool unite(int x, int y) {
    x = root(x);
    y = root(y);
    if (x != y) {
      if (-data[y] > -data[x]) swap(x, y);
      data[x] += data[y];
      data[y] = x;
    }
    return x != y;
  }
  bool findSet(int x, int y) { return root(x) == root(y); }
  int root(int x) { return data[x] < 0 ? x : data[x] = root(data[x]); }
  int size(int x) { return -data[root(x)]; }
  bool operator()(int x, int y) { return findSet(x, y); }
  int operator[](int x) { return root(x); }
  bool unti(int x, int y) { return unite(x, y); }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout << fixed << setprecision(0);
  int n;
  cin >> n;
  vector<int> par(n);
  vector<int> cas(n);
  for (int(i) = 0; (i) < (int)(n); ++(i)) {
    cin >> par[i] >> cas[i];
    --par[i];
  }
  vv<int> g(n + 1);
  for (int(i) = 0; (i) < (int)(n); ++(i)) {
    int v = i;
    int p = par[i];
    if (p < 0) p = n;
    g[v].push_back(p);
    g[p].push_back(v);
  }
  UF ufc(n + 1), ufp(n + 1);
  for (int(i) = 0; (i) < (int)(n); ++(i))
    if (par[i] >= 0) {
      if (cas[i] == 1) ufp.unite(i, par[i]);
      if (cas[i] == 0) ufc.unite(i, par[i]);
    }
  Lca h(g, n);
  auto solve = [&](int t, int u, int v) -> bool {
    if (u == v) return 0;
    if (t == 1) {
      ;
      if (h.LCA(u, v) != u) return 0;
      ;
      return ufc.findSet(u, v);
    } else {
      int lca = h.LCA(u, v);
      ;
      ;
      return v != lca && ufc.findSet(lca, u) && ufp.findSet(lca, v);
    }
  };
  int q;
  cin >> q;
  while (q--) {
    int t, u, v;
    cin >> t >> u >> v;
    --u;
    --v;
    cout << (solve(t, u, v) ? "YES" : "NO") << "\n";
  }
  return 0;
}
