#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <random>
#include <queue>
#include <numeric>
#include <array>
#include <iomanip>
#include <stack>
#include <chrono>
#include <climits>
#include <bitset>
using namespace std;
using ll = long long;
using ld = long double;
using vi = vector<ll>;
using vii = vector<vi>;
using viii = vector<vii>;
using pi = pair<ll, ll>;
using vpi = vector<pi>;
using vb = vector<bool>;
using vs = vector<string>;
#define vec vector
#define cmax(x, ...) x = max({x, __VA_ARGS__})
#define cmin(x, ...) x = min({x, __VA_ARGS__})
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
const ll N = 5e5 + 5, MOD = 1e9 + 7, INF = (ll)1e18, K = 20;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
ll nxt[N], prv[N];
struct Seg {
vi seg;
Seg(ll n) {
seg.assign(4 * n, INF);
build(1, 1, n);
}
void build(ll t, ll tl, ll tr) {
if (tl == tr) {
seg[t] = prv[tl];
}
else {
ll tm = tl + (tr - tl) / 2;
build(t * 2, tl, tm);
build(t * 2 + 1, tm + 1, tr);
cmin(seg[t], seg[t * 2], seg[t * 2 + 1]);
}
}
ll get(ll t, ll tl, ll tr, ll l, ll r, ll v) {
if (tl > r || tr < l) return INF;
if (seg[t] >= v) return INF;
if (tl == tr) {
return tl;
}
ll tm = tl + (tr - tl) / 2;
ll res = get(t * 2, tl, tm, l, r, v);
if (res != INF) return res;
return get(t * 2 + 1, tm + 1, tr, l, r, v);
}
};
void solve() {
ll n; cin >> n;
vi c(n + 1); for (ll i = 1; i < n; i++) cin >> c[i];
vii a(n + 1);
for (ll i = 1; i <= n; i++) {
ll sz; cin >> sz;
for (ll j = 0; j < sz; j++) {
ll x; cin >> x;
a[x].push_back(i);
}
}
for (ll i = 1; i <= n; i++) {
auto it = upper_bound(all(a[c[i]]), i);
if (it == a[c[i]].end()) nxt[i] = n + 1;
else nxt[i] = *it;
if (it == a[c[i]].begin()) prv[i] = -1;
else --it, prv[i] = *it;
}
stack<ll> st;
Seg seg(n);
vi l(n + 1), r(n + 1);
for (ll i = 1; i <= n; i++) {
l[i] = i;
r[i] = min(n, seg.get(1, 1, n, i, n, l[i]));
while (!st.empty()) {
if (nxt[st.top()] > r[i]) break;
auto cur = st.top(); st.pop();
l[i] = l[cur];
r[i] = min(n, seg.get(1, 1, n, i, n, l[i]));
}
st.push(i);
}
ll q; cin >> q;
while (q--) {
ll x, y; cin >> x >> y;
if ((y >= x && r[x] >= y) || (y < x && l[x] <= y)) {
cout << "YES\n";
}
else {
cout << "NO\n";
}
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
long long tt = 1;
//cin >> tt;
while (tt--) {
solve();
cout << '\n';
}
return 0;
}
/*
Я думаю что это препроцессинг до какой вершины может добраться итый элемент
Это дп с сег деревом для максимума
Идем с n до 1 элемента и держим сег дерево максимума. Допустим в данный момент мы знаем
что можем добраться до диапазона [l, r]. Можно сделать запрос на отрезке и перейти в
следующий диапазон(увеличить правую границу).
Какие темы повторить:
1) мст
2) 2сат
3) точки артикуляции
4) ксор базис
5) эйлеровый цикл, путь
6) кмп
7) конвекс хулл
8) вафельное дерево
9) суфиксный массив
10) суффиксный автомат
11) ним
*/