#include <bits/stdc++.h>
const double EPS = 1e-8;
using namespace std;
long long gcd(long long a, long long b) {
  if (b == 0) return a;
  return gcd(b, a % b);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
  std::fill((T *)array, (T *)(array + N), val);
}
class Graph {
 public:
  int vn;
  int sumcost = 0;
  vector<vector<pair<int, int>>> g;
  Graph(int n) {
    vn = n;
    g.resize(n);
  }
  virtual void con(int a, int b, int w) = 0;
  int getWeight(int f, int t) {
    auto itr = lower_bound((g[f]).begin(), (g[f]).end(), make_pair(t, INT_MIN));
    if (itr != g[f].end()) return itr->second;
    return INT_MIN;
  }
  int Costsum() { return sumcost; }
  void scan(int edcount, bool oindexed, bool w) {
    for (int i = (0); (edcount) > i; i++) {
      int a, b, c = 1;
      scanf("%d %d", &a, &b);
      if (w) scanf("%d", &c);
      con(a - oindexed, b - oindexed, c);
    }
  }
};
class BiDGraph : public Graph {
 public:
  BiDGraph(int n) : Graph(n) {}
  void con(int a, int b, int w = 1) {
    g[a].push_back({b, w});
    g[b].push_back({a, w});
    sumcost++;
  }
};
struct RSQ {
  int n;
  vector<int> dat;
  RSQ() {}
  RSQ(int n_) {
    n = 1;
    while (n < n_) n *= 2;
    dat.resize(2 * n - 1, 0);
  }
  void add(int k, int a) {
    k += n - 1;
    dat[k] += a;
    while (k > 0) {
      k = (k - 1) / 2;
      dat[k] = dat[2 * k + 1] + dat[2 * k + 2];
    }
  }
  int query(int a, int b) { return query(a, b, 0, 0, n); }
  int query(int a, int b, int k, int l, int r) {
    if (r <= a || b <= l) return 0;
    if (a <= l && r <= b) return dat[k];
    int vl = query(a, b, 2 * k + 1, l, (l + r) / 2);
    int vr = query(a, b, 2 * k + 2, (l + r) / 2, r);
    return vl + vr;
  }
};
class Heavy_Light_Decomposition {
 public:
  BiDGraph g, compg;
  vector<int> sz, depth, chain, par;
  int bn = 0;
  vector<int> bvn, inbn;
  vector<vector<int>> bv;
  Heavy_Light_Decomposition(BiDGraph graph, vector<int> root)
      : g(graph),
        compg(graph.vn),
        sz(graph.vn, 1),
        depth(graph.vn),
        chain(graph.vn),
        par(graph.vn),
        bvn(graph.vn, -1),
        inbn(graph.vn) {
    for (auto itr : root) getsz(itr, itr);
    bv.push_back(vector<int>());
    for (auto itr : root) {
      if (bv[bv.size() - 1].size()) bv.push_back(vector<int>()), bn++;
      HLD(itr, -1, itr, bn);
    }
  }
  int getsz(int cur, int p) {
    par[cur] = p;
    for (auto itr : g.g[cur])
      if (p != itr.first)
        depth[itr.first] = depth[cur] + 1, sz[cur] += getsz(itr.first, cur);
    return sz[cur];
  }
  void HLD(int cur, int p, int head, int num) {
    chain[cur] = head, bvn[cur] = num;
    inbn[cur] = bv[num].size(), bv[num].push_back(cur);
    pair<int, int> Maxc = {-1, -1};
    for (auto itr : g.g[cur])
      if (itr.first != p) Maxc = max(Maxc, {sz[itr.first], itr.first});
    for (auto itr : g.g[cur])
      if (itr.first != p) {
        int nb = num;
        if (itr.first != Maxc.second) {
          bv.push_back(vector<int>());
          nb = ++bn;
        }
        HLD(itr.first, cur, itr.first == Maxc.second ? head : itr.first, nb);
      }
  }
  int lca(int a, int b) {
    if (chain[a] == chain[b]) return depth[a] < depth[b] ? a : b;
    if (depth[chain[a]] > depth[chain[b]]) return lca(par[chain[a]], b);
    return lca(a, par[chain[b]]);
  }
  void for_each_edge(int a, int b, function<void(int, int)> func) {
    if (chain[a] == chain[b])
      return func(inbn[a] < inbn[b] ? a : b, inbn[a] < inbn[b] ? b : a);
    if (depth[chain[a]] < depth[chain[b]]) swap(a, b);
    for_each_edge(a, chain[a], func), for_each_edge(par[chain[a]], b, func);
  }
};
struct UnionFind {
  vector<int> data;
  UnionFind(int size) : data(size, -1) {}
  bool unionSet(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]); }
  bool isroot(int x) { return data[x] < 0; }
  int size(int x) { return -data[root(x)]; }
};
int main() {
  int n;
  cin >> n;
  BiDGraph g(n);
  vector<int> t(n);
  vector<int> root;
  UnionFind uf(n);
  for (int i = (0); (n) > i; i++) {
    int p;
    scanf("%d %d", &p, &t[i]);
    if (p == -1) root.push_back(i);
    if (p > 0) uf.unionSet(i, p - 1), g.con(i, p - 1);
  }
  Heavy_Light_Decomposition hld(g, root);
  vector<RSQ> seg;
  for (int i = (0); (hld.bv.size()) > i; i++) {
    seg.push_back(RSQ(hld.bv[i].size()));
    for (int j = (0); (hld.bv[i].size()) > j; j++)
      seg[i].add(j, t[hld.bv[i][j]]);
  }
  int q;
  cin >> q;
  for (int i = (0); (q) > i; i++) {
    int mode, p, c;
    scanf("%d %d %d", &mode, &p, &c);
    c--, p--;
    if (c == p || !uf.findSet(p, c)) {
      printf("NO\n");
      continue;
    }
    int lca = hld.lca(p, c);
    if (mode == 1) {
      bool f = 0;
      if (lca == p) {
        int sum = 0;
        hld.for_each_edge(p, c, [&](int u, int v) {
          sum += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);
          if (u == lca) {
            sum -= t[lca];
          } else if (v == lca) {
            sum -= t[lca];
          }
        });
        if (sum == 0) f = 1;
      }
      printf(f ? "YES\n" : "NO\n");
    } else {
      if (lca == c) {
        printf("NO\n");
        continue;
      }
      int sum = 0, sum2 = 0;
      hld.for_each_edge(p, lca, [&](int u, int v) {
        sum += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);
        if (u == lca) {
          sum -= t[lca];
        } else if (v == lca) {
          sum -= t[lca];
        }
      });
      hld.for_each_edge(c, lca, [&](int u, int v) {
        sum2 += seg[hld.bvn[u]].query(hld.inbn[u], hld.inbn[v] + 1);
        if (u == lca) {
          sum2 -= t[lca];
        } else if (v == lca) {
          sum2 -= t[lca];
        }
      });
      if (sum == 0 && sum2 == (hld.depth[c] - hld.depth[lca]))
        printf("YES\n");
      else
        printf("NO\n");
    }
  }
  return 0;
}
