#include<iostream>
#include<random>
#include<cassert>
#include<set>
#define ull unsigned long long
using namespace std;
const int N = 1e5 + 20;
struct myPair {
int u;
ull hsh;
inline myPair(int _u, ull _hsh) : u(_u), hsh(_hsh) {}
inline bool operator==(const myPair &b) const {
return hsh == b.hsh;
}
inline bool operator<(const myPair &b) const {
return hsh < b.hsh;
}
};
struct myPair_Hash {
inline ull operator()(const myPair &p) const { return p.hsh; }
};
struct Edge2 {
int u, v;
};
struct Edge {
int v, next;
} pool[2][2 * N];
int ne[2], head[2][N], cs[2][N];
void clear_Edge(int n) {
ne[0] = ne[1] = 0;
for(int i = 1; i <= n; i++) head[0][i] = head[1][i] = cs[0][i] = cs[1][i] = 0;
}
void addEdge(int id, int u, int v) {
pool[id][++ne[id]] = {v, head[id][u]};
head[id][u] = ne[id];
++cs[id][u];
}
int T, k;
int n, m;
int rt0, rt1;
ull seed = (mt19937_64){(random_device){}()}();
ull hsh[2][N], sz[2][N];
ull shift(ull x) {
x ^= x << 2;
x ^= x >> 3;
x ^= x << 21;
x ^= seed;
return x;
}
void dfs(int u, int fa, int id) {
hsh[id][u] = 1;
sz[id][u] = 1;
for(int e = head[id][u]; e; e = pool[id][e].next) {
int v = pool[id][e].v;
dfs(v, u, id);
hsh[id][u] += shift(hsh[id][v]);
sz[id][u] += sz[id][v];
}
}
namespace match {
Edge pool[30];
int ne, head[7];
int link[7], vis[7];
void clear() {
ne = 0;
head[1] = head[2] = head[3] = head[4] = head[5] = 0;
link[1] = link[2] = link[3] = link[4] = link[5] = 0;
vis[1] = vis[2] = vis[3] = vis[4] = vis[5] = 0;
}
void addEdge(int u, int v) {
pool[++ne] = {v, head[u]};
head[u] = ne;
}
bool dfs(int u) {
for(int e = head[u]; e; e = pool[e].next) {
int v = pool[e].v;
if(vis[v]) continue;
vis[v] = 1;
if(!link[v] || dfs(link[v])) {
link[v] = u;
return true;
}
}
return false;
}
int calc() {
int res = 0;
for(int i = 1; i <= 5; i++) {
vis[1] = vis[2] = vis[3] = vis[4] = vis[5] = 0;
res += dfs(i);
}
return res;
}
}
bool solve(int x, int y) {
if(hsh[0][x] == hsh[1][y]) return true;
int delta = sz[0][x] - sz[1][y];
if(delta <= 0 || delta > k) return false;
if(sz[1][y] == 0) return true;
multiset<myPair> st1, st2;
for(int e = head[0][x]; e; e = pool[0][e].next) {
int v = pool[0][e].v;
st1.insert({v, hsh[0][v]});
}
for(int e = head[1][y]; e; e = pool[1][e].next) {
int v = pool[1][e].v;
if(st1.count({0, hsh[1][v]})) st1.erase(st1.find({0, hsh[1][v]}));
else st2.insert({v, hsh[1][v]});
}
if(st1.size() < st2.size()) return false;
if(st1.size() > delta) return false;
vector<Edge2> edg;
int i = 1, j;
for(auto it1 = st1.begin(); it1 != st1.end(); ++it1, i++) {
j = 1;
for(auto it2 = st2.begin(); it2 != st2.end(); ++it2, j++) {
if(solve(it1->u, it2->u)) {
edg.push_back({i, j});
}
}
}
match::clear();
for(Edge2 &e : edg) {
assert(1 <= e.u && e.u <= 5);
match::addEdge(e.u, e.v);
}
if(match::calc() >= st2.size()) return true;
return false;
}
int main() {
cin >> T >> T >> k;
while(T--) {
cin >> n;
clear_Edge(n);
for(int i = 1; i <= n; i++) {
int x;
cin >> x;
if(~x) addEdge(0, x, i);
else rt0 = i;
}
cin >> m;
for(int i = 1; i <= m; i++) {
int x;
cin >> x;
if(~x) addEdge(1, x, i);
else rt1 = i;
}
dfs(rt0, 0, 0);
dfs(rt1, 0, 1);
cout << (solve(rt0, rt1) ? "Yes\n" : "No\n");
}
return 0;
}