The Committee for Research on Binary Viruses discovered a method of replication for a large family of viruses whose genetic codes are sequences of zeros and ones. Each virus originates from a single gene; for simplicity genes are denoted by integers from $$$0$$$ to $$$G - 1$$$. At each moment in time a virus is a sequence of genes. When mutation occurs, one of the genes from the sequence is replaced by a certain sequence of genes, according to the mutation table. The virus stops mutating when it consists only of genes $$$0$$$ and $$$1$$$.For instance, for the following mutation table: $$$$$$ 2 \to \langle 0\ 1 \rangle \\ 3 \to \langle 2\ 0\ 0\rangle\\ 3 \to \langle 1\ 3\rangle\\ 4 \to \langle 0\ 3\ 1\ 2\rangle\\ 5 \to \langle 2\ 1\rangle\\ 5 \to \langle 5\rangle $$$$$$ a virus that initially consisted of a single gene $$$4$$$, could have mutated as follows: $$$$$$ \langle 4 \rangle \to \langle \underline{0\ 3\ 1\ 2} \rangle \to \langle 0\ \underline{2\ 0\ 0}\ 1\ 2 \rangle \to \langle 0\ \underline{0\ 1}\ 0\ 0\ 1\ 2 \rangle \to \langle 0\ 0\ 1\ 0\ 0\ 1\ \underline{0\ 1} \rangle $$$$$$ or in another way: $$$$$$ \langle 4 \rangle \to \langle \underline{0\ 3\ 1\ 2} \rangle \to \langle 0\ \underline{1\ 3}\ 1\ 2 \rangle \to \langle 0\ 1\ 3\ 1\ \underline{0\ 1} \rangle \to \langle 0\ 1\ \underline{2\ 0\ 0}\ 1\ 0\ 1 \rangle \to \langle 0\ 1\ \underline{0\ 1}\ 0\ 0\ 1\ 0\ 1 \rangle $$$$$$Viruses are detected by antibodies that identify the presence of specific continuous fragments of zeros and ones in the viruses' codes. For example, an antibody reacting to a fragment $$$\langle 0\ 0\ 1\ 0\ 0 \rangle$$$ will detect a virus $$$\langle 0\ 0\ 1\ 0\ 0\ 1\ 0\ 1 \rangle$$$, but it will not detect a virus $$$\langle 0\ 1\ 0\ 1\ 0\ 0\ 1\ 0\ 1 \rangle$$$.For each gene from $$$2$$$ to $$$G-1$$$, the scientists are wondering whether a given set of antibodies is enough to detect all viruses that can emerge through mutations from this gene. If not, they want to know the length of the shortest virus that cannot be detected.It may happen that sometimes scientists don't have any antibodies. Then of course no virus can be detected, so the scientists are only interested in the length of the shortest possible virus that can emerge from the gene mutations.

The first line of the input will contain three integers $$$G$$$, $$$N$$$ and $$$M$$$ ($$$G > 2$$$, $$$N \geq G - 2$$$, $$$M \geq 0$$$) specifying the number of genes, the number of rows in the mutation table, and the number of antibodies. The following $$$N$$$ lines contain descriptions of rows of the mutation table; each line begins with two integers $$$a$$$ and $$$k$$$ ($$$2 \leq a < G$$$, $$$k \geq 1$$$), followed by a sequence of $$$k$$$ integers $$$b_1, b_2, \ldots, b_k$$$ ($$$0 \leq b_i < G$$$), that encode the row $$$$$$ a \to \langle b_1\ b_2\ \ldots\ b_k \rangle $$$$$$ The sum of all values $$$k$$$ does not exceed $$$100$$$. Every integer from $$$2$$$ to $$$G - 1$$$ appears in the table as $$$a$$$ at least once. The next $$$M$$$ lines contain descriptions of the antibodies; each such line begins with an integer $$$\ell$$$ ($$$\ell \geq 1$$$), followed by a sequence of $$$\ell$$$ integers $$$c_1, c_2, \ldots, c_\ell$$$ ($$$0 \leq c_i \leq 1$$$), describing the antibody. The sum of all values $$$\ell$$$ does not exceed $$$50$$$.

Your program needs to output exactly $$$G - 2$$$ lines, containing the answers for the subsequent genes from $$$2$$$ to $$$G - 1$$$. If all viruses that can mutate from this single gene can be detected by the given set of antibodies, you need to print the word "YES". You also need to print this if there are no viruses that could originate from this gene (it can happen when the sequences never stop mutating). Otherwise you need to print the word "NO", followed by an integer denoting the minimal length of the undetectable virus. You can assume that for all the prepared input data this value will be smaller than $$$2^{63}$$$.

#include <bits/stdc++.h>
using namespace std;

class AhoCorasick {
 public:
  int sz;
  vector<int> sl; // suffix link
  vector<int> bad; // bad prefixes
  vector<array<int, 2>> d; // transition
  vector<array<int, 2>> c; // trie

  AhoCorasick() : sz(1), sl(1, 0), bad(1, 0), d(1, {0, 0}), c(1, {0, 0}) {}

  int NewNode() {
    sl.emplace_back(0);
    bad.emplace_back(0);
    d.push_back({0, 0});
    c.push_back({0, 0});
    return sz++;
  }

  void InsertString(vector<int> s) {
    int u = 0;
    for (auto i : s) {
      if (!c[u][i]) {
        int nw = NewNode();
        c[u][i] = nw;
      }
      u = c[u][i];
    }
    bad[u] = 1;
  }

  void Build() {
    for (queue<int> q({0}); !q.empty(); q.pop()) {
      int u = q.front();
      bad[u] |= bad[sl[u]];
      for (int i = 0; i < 2; i++) {
        int v = c[u][i];
        if (v != 0) {
          sl[v] = d[sl[u]][i];
          d[u][i] = v;
          bad[v] |= bad[u];
          q.emplace(v);
        } else {
          d[u][i] = d[sl[u]][i];
        }
      }
    }
  }

  bool IsBadPrefix(int x) {
    return bad[x];
  }
};

int main() {
  ios::sync_with_stdio(0);
  cin.tie(0), cout.tie(0);

  int G, N, M;
  cin >> G >> N >> M;

  vector<vector<vector<int>>> adj(G);
  for (int rep = 0; rep < N; rep++) {
    int u, k;
    cin >> u >> k;
    vector<int> v;
    while (k--) {
      v.emplace_back();
      cin >> v.back();
    }
    while ((int) v.size() > 2) {
      int v2 = v.back(); v.pop_back();
      int v1 = v.back(); v.pop_back();
      int new_node = (int) adj.size();
      adj.emplace_back();
      adj[new_node].emplace_back();
      adj[new_node].back().emplace_back(v1);
      adj[new_node].back().emplace_back(v2);
      v.emplace_back(new_node);
    }
    adj[u].emplace_back();
    for (auto vi : v) {
      adj[u].back().emplace_back(vi);
    }
  }

  vector<vector<pair<int, int>>> radj(adj.size());
  for (int u = 0; u < (int) adj.size(); u++) {
    for (int vid = 0; vid < (int) adj[u].size(); vid++) {
      for (auto v : adj[u][vid]) {
        radj[v].emplace_back(u, vid);
      }
    }
  }

  AhoCorasick ac;
  for (int rep = 0; rep < M; rep++) {
    int l;
    cin >> l;
    vector<int> s;
    while (l--) {
      s.emplace_back();
      cin >> s.back();
    }
    ac.InsertString(s);
  }
  ac.Build();

  const unsigned long long INF = 1ull << 63;
  vector<vector<vector<unsigned long long>>> dist(adj.size(),
      vector<vector<unsigned long long>>(ac.sz, vector<unsigned long long>(ac.sz, INF)));

  struct State {
    int u, st, et;
    unsigned long long d;
    State() {}
    State(int u, int st, int et, unsigned long long d) : u(u), st(st), et(et), d(d) {}
    const bool operator < (const State &o) const { return d > o.d; }
  };

  priority_queue<State> pq;
  auto Relax = [&](int x, int y, int z, unsigned long long w) {
    if (!ac.IsBadPrefix(y) && !ac.IsBadPrefix(z) && dist[x][y][z] > w) {
      dist[x][y][z] = w;
      pq.emplace(x, y, z, w);
    }
  };

  // Base Case
  for (int st = 0; st < ac.sz; st++) {
    Relax(0, st, ac.d[st][0], 1);
    Relax(1, st, ac.d[st][1], 1);
  }

  // Dijkstra
  while (!pq.empty()) {
    State s = pq.top();
    pq.pop();
    if (dist[s.u][s.st][s.et] != s.d || dist[s.u][s.st][s.et] == INF) {
      continue;
    }
    for (auto r : radj[s.u]) {
      int par = r.first;
      int id = r.second;
      if ((int) adj[par][id].size() == 1) {
        Relax(par, s.st, s.et, dist[s.u][s.st][s.et]);
      }
      if ((int) adj[par][id].size() == 2 && adj[par][id][0] == s.u) {
        int v = adj[par][id][1];
        for (int i = 0; i < ac.sz; i++) {
          Relax(par, s.st, i, dist[s.u][s.st][s.et] + dist[v][s.et][i]);
        }
      }
      if ((int) adj[par][id].size() == 2 && adj[par][id][1] == s.u) {
        int v = adj[par][id][0];
        for (int i = 0; i < ac.sz; i++) {
          Relax(par, i, s.et, dist[v][i][s.st] + dist[s.u][s.st][s.et]);
        }
      }
    }
  }

  for (int i = 2; i < G; i++) {
    unsigned long long ans = INF;
    for (int j = 0; j < ac.sz; j++) {
      if (!ac.IsBadPrefix(j) && ans > dist[i][0][j]) {
        ans = dist[i][0][j];
      }
    }
    if (ans == INF) {
      cout << "YES\n";
    } else {
      cout << "NO " << ans << "\n";
    }
  }
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const uint64_t INF = 1ull << 63;

bool mnm(uint64_t &x, uint64_t y) {
   if (x > y) {
      x = y;
      return true;
   }
   return false;
}

vector<array<int, 2>> ch;
vector<array<int, 2>> go;
vector<int> link;
vector<bool> terminal;
int newNode() {
   int v = ch.size();
   ch.emplace_back();
   go.emplace_back();
   link.emplace_back();
   terminal.emplace_back();
   return v;
}
void add(vector<int> str) {
   int v = 0;
   for (int c : str) {
      if (ch[v][c] == 0) {
         int nv = newNode();
         ch[v][c] = nv;
      }
      v = ch[v][c];
   }
   terminal[v] = true;
}

void build() {
   queue<int> bfs;
   link[0] = 0;
   bfs.emplace(0);
   while (!bfs.empty()) {
      int v = bfs.front(); bfs.pop();
      if (terminal[link[v]]) terminal[v] = true;
      for (int c = 0; c < 2; ++c) {
         go[v][c] = go[link[v]][c];
         if (ch[v][c]) {
            link[ch[v][c]] = go[v][c];
            go[v][c] = ch[v][c];
            bfs.emplace(ch[v][c]);
         }
      }
   }
}

int main() {
   ios_base::sync_with_stdio(false); cin.tie(nullptr);
   int G, N, M; cin >> G >> N >> M;
   vector<vector<int>> singles(G);
   vector<vector<tuple<int, int, int>>> doubles(G);
   for (int i = 0; i < N; ++i) {
      int a, K; cin >> a >> K;
      if (K == 1) {
         int b; cin >> b;
         singles[b].emplace_back(a);
      } else {
         for (int i = 0; i < K - 2; ++i) {
            int na = singles.size();
            singles.emplace_back();
            doubles.emplace_back();
            // a = b, na;
            int b; cin >> b;
            doubles[b].emplace_back(a, na, 0);
            doubles[na].emplace_back(a, b, 1);
            a = na;
         }
         int b1, b2; cin >> b1 >> b2;
         doubles[b1].emplace_back(a, b2, 0);
         doubles[b2].emplace_back(a, b1, 1);
      }
   }
   newNode();
   for (int i = 0; i < M; ++i) {
      int L; cin >> L;
      vector<int> str(L);
      for (int &c : str) cin >> c;
      add(str);
   }
   build();
   int H = singles.size();
   int V = ch.size();
   vector<vector<vector<uint64_t>>> dp(H);
   for (auto &z : dp) z = vector<vector<uint64_t>>(V, vector<uint64_t>(V, INF));
   using T = tuple<uint64_t, int, int, int>;
   priority_queue<T, vector<T>, greater<T>> q;
   for (int c = 0; c < 2; ++c) {
      for (int v = 0; v < V; ++v) {
         if (!terminal[v] && !terminal[go[v][c]]) {
            dp[c][v][go[v][c]] = 1;
            q.emplace(1, c, v, go[v][c]);
         }
      }
   }
   while (!q.empty()) {
      uint64_t d, x, y, z; tie(d, x, y, z) = q.top(); q.pop();
      if (dp[x][y][z] != d) continue;
      for (int nx : singles[x]) {
         if (mnm(dp[nx][y][z], dp[x][y][z])) {
            q.emplace(dp[nx][y][z], nx, y, z);
         }
      }
      for (auto db : doubles[x]) {
         int px, nx, dir;
         tie(px, nx, dir) = db;
         if (dir == 0) {
            for (int nz = 0; nz < V; ++nz) if (!terminal[nz]) {
               if (mnm(dp[px][y][nz], dp[x][y][z] + dp[nx][z][nz])) {
                  q.emplace(dp[px][y][nz], px, y, nz);
               }
            }
         } else {
            for (int ny = 0; ny < V; ++ny) if (!terminal[ny]) {
               if (mnm(dp[px][ny][z], dp[nx][ny][y] + dp[x][y][z])) {
                  q.emplace(dp[px][ny][z], px, ny, z);
               }
            }
         }
      }
   }
   for (int g = 2; g < G; ++g) {
      uint64_t ans = INF;
      for (int v = 0; v < V; ++v) if (!terminal[v]) ans = min(ans, dp[g][0][v]);
      if (ans == INF) {
         cout << "YES\n";
      } else {
         cout << "NO " << ans << '\n';
      }
   }
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
#include <chrono>
#include <random>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
std::mt19937 rnd((int)std::chrono::steady_clock::now().time_since_epoch().count());
typedef long long ll;
ll gcd(ll a, ll b) { return b == 0 ? a : gcd(b, a % b); }

const int MAXMUTRHSSUM = 100;
const int MAXMUT = MAXMUTRHSSUM;
const int MAXGENE = MAXMUT + 2;
const int MAXPATRHSSUM = 50;
const int MAXPAT = MAXPATRHSSUM;
const int MAXTOK = 2 + MAXMUTRHSSUM;
const int MAXTRIE = 1 + MAXPATRHSSUM;
const int MAXSINGLE = MAXMUTRHSSUM;
const int MAXPAIR = MAXMUTRHSSUM - 1;
const int ALPH = 2;

int ngene, nmut, npat;
vector<int> mut[MAXMUT]; int mutlhs[MAXMUT];
vector<int> muts[MAXGENE];
vector<int> pat[MAXPAT];
ll ans[MAXGENE];

int ntok, nsingle, npair, ntrie;
int singlelhs[MAXSINGLE], singlerhs[MAXSINGLE];
int pairlhs[MAXPAIR]; pair<int, int> pairrhs[MAXPAIR];
vector<int> singleusage[MAXTOK];
vector<pair<int, int>> pairusage[MAXTOK];
ll dp[MAXTOK][MAXTRIE][MAXTRIE]; // dp[x][s][t] = the length of the shortest string generated by token x that goes from trienode s to trienode t
priority_queue<pair<ll, pair<int, pair<int, int>>>> pq;

struct TrieNode {
	int nxt[ALPH];
	int safenxt[ALPH];
	int suff;
	bool detected;
};

TrieNode trie[MAXTRIE]; int trieroot;
int maketrie() { assert(ntrie < MAXTRIE); int ret = ntrie++; REP(i, ALPH) trie[ret].nxt[i] = trie[ret].safenxt[i] = -1; trie[ret].detected = false; trie[ret].suff = -1; return ret; }

void buildtrie() {
	ntrie = 0;
	trieroot = maketrie();
	REP(i, npat) {
		int at = trieroot;
		REPSZ(j, pat[i]) {
			int x = pat[i][j]; assert(0 <= x && x < ALPH);
			int to = trie[at].nxt[x]; if (to == -1) { to = maketrie(); trie[at].nxt[x] = to; }
			at = to;
		}
		trie[at].detected = true;
	}
	queue<int> q;
	q.push(trieroot);
	while (!q.empty()) {
		int at = q.front(); q.pop();
		REP(k, ALPH) {
			int suff;
			if (at == trieroot) {
				suff = at;
			} else {
				suff = trie[at].suff; while (suff != trieroot && trie[suff].nxt[k] == -1) suff = trie[suff].suff;
				if (trie[suff].nxt[k] != -1) suff = trie[suff].nxt[k];
			}
			int to = trie[at].nxt[k];
			trie[at].safenxt[k] = to == -1 ? suff : to;
			if (to != -1) {
				trie[to].suff = suff;
				if (trie[suff].detected) trie[to].detected = true;
				q.push(to);
			}
		}
	}
	//REP(at, ntrie) { printf("%d: detected=%s suff=%d", at, trie[at].detected ? "YES" : "NO", trie[at].suff); REP(k, ALPH) if (trie[at].nxt[k] != -1) printf(" %c=%d", '0' + k, trie[at].nxt[k]); puts(""); }
}

void upd(int x, int s, int t, ll cost) { if (cost >= dp[x][s][t]) return; dp[x][s][t] = cost; pq.push(MP(-cost, MP(x, MP(s, t)))); }

void solve() {
	ntok = ngene, nsingle = 0, npair = 0;
	REP(i, nmut) {
		if (SZ(mut[i]) == 1) { int idx = nsingle++; singlelhs[idx] = mutlhs[i]; singlerhs[idx] = mut[i][0]; continue; }
		int at = 0, last = mutlhs[i];
		while (at + 2 < SZ(mut[i])) { int next = ntok++, idx = npair++; pairlhs[idx] = last, pairrhs[idx] = MP(mut[i][at], next); ++at, last = next; }
		{ int idx = npair++; pairlhs[idx] = last; pairrhs[idx] = MP(mut[i][at], mut[i][at + 1]); }
	}
	REP(i, nsingle) singleusage[singlerhs[i]].PB(i);
	REP(i, npair) pairusage[pairrhs[i].first].PB(MP(i, 0)), pairusage[pairrhs[i].second].PB(MP(i, 1));
	//REP(i, nsingle) printf("%d: %d\n", singlelhs[i], singlerhs[i]);
	//REP(i, npair) printf("%d: %d %d\n", pairlhs[i], pairrhs[i].first, pairrhs[i].second);

	buildtrie();

	REP(x, ntok) REP(s, ntrie) REP(t, ntrie) dp[x][s][t] = LLONG_MAX;
	REP(x, 2) REP(s, ntrie) if (!trie[s].detected) { int t = trie[s].safenxt[x]; if (!trie[t].detected) upd(x, s, t, 1); }

	while (!pq.empty()) {
		ll cost = -pq.top().first; int x = pq.top().second.first, s = pq.top().second.second.first, t = pq.top().second.second.second; pq.pop();
		if (cost > dp[x][s][t]) continue;
		//printf("processing %d: %d->%d = %lld\n", x, s, t, cost);
		REPSZ(i, singleusage[x]) {
			int idx = singleusage[x][i];
			int a = singlelhs[idx], b = singlerhs[idx]; assert(b == x);
			upd(a, s, t, cost);
		}
		REPSZ(i, pairusage[x]) {
			int idx = pairusage[x][i].first, side = pairusage[x][i].second;
			int a = pairlhs[idx], b = pairrhs[idx].first, c = pairrhs[idx].second;
			if (side == 0) { assert(b == x); REP(tt, ntrie) if (dp[c][t][tt] != LLONG_MAX) upd(a, s, tt, cost + dp[c][t][tt]); }
			if (side == 1) { assert(c == x); REP(ss, ntrie) if (dp[b][ss][s] != LLONG_MAX) upd(a, ss, t, cost + dp[b][ss][s]); }
		}
	}

	FOR(x, 2, ngene) ans[x] = LLONG_MAX;
	FOR(x, 2, ngene) REP(t, ntrie) if (!trie[t].detected) ans[x] = min(ans[x], dp[x][trieroot][t]);
}

void run() {
	scanf("%d%d%d", &ngene, &nmut, &npat);
	REP(i, nmut) { int a, cnt; scanf("%d%d", &a, &cnt); vector<int> cur(cnt); REP(j, cnt) scanf("%d", &cur[j]); mutlhs[i] = a, mut[i] = cur; muts[a].PB(i); }
	REP(i, npat) { int cnt; scanf("%d", &cnt); vector<int> cur(cnt); REP(j, cnt) scanf("%d", &cur[j]); pat[i] = cur; }
	solve();
	FOR(i, 2, ngene) if (ans[i] == LLONG_MAX) printf("YES\n"); else printf("NO %lld\n", ans[i]);
}

int main() {
	run();
	return 0;
}

//CLOCKS_PER_SEC
using namespace std;
#include<bits/stdc++.h>
#define sqr(x) 1ll*(x)*(x)
//#define sort stable_sort
#define ll long long
#define mk make_pair
#define pb push_back
#define in insert
#define mtr(x,y,z) mk(mk(x,y),z)
#define fi first
#define se second
#define lch(x) ((x)<<1)
#define rch(x) (((x)<<1)|1)
#define all(x) (x).begin(),(x).end()
#define titose CLOCKS_PER_SEC
#define fpi(x) freopen(x,"r",stdin);
#define fpo(x) freopen(x,"w",stdout);
#define fprio fpi("in.txt");fpo("out.txt");
#define fast ios_base::sync_with_stdio(false);
inline void read(int &x){int v=0,f=1;char c=getchar();while (!isdigit(c)&&c!='-') c=getchar();if (c=='-') f=-1; else v=(c&15);while (isdigit(c=getchar())) v=(v<<1)+(v<<3)+(c&15);x=v*f;}
inline void read(ll &x){ll v=0ll,f=1ll;char c=getchar();while (!isdigit(c)&&c!='-') c=getchar();if (c=='-') f=-1; else v=(c&15);while (isdigit(c=getchar())) v=(v<<1)+(v<<3)+(c&15);x=v*f;}
inline void readc(char &x){char c;while (((c=getchar())==' ')||c=='\n');x=c;}
#define pii pair<int,int>
#define pll pair<ll,ll>
#define vi vector<int>
#define vl vector<ll>
#define si set<int>
#define sl set<ll>
#define mii map<int,int>
#define mll map<ll,ll>
#define msi map<string,int>
#define msl map<string,ll>
#define piii pair<int,pii >
#define piipi pair<pii,int>
#define plll pair<ll,pll >
#define pllpl pair<pll,ll>
#define pqi priority_queue<int>
#define pql priority_queue<ll>
#define npqi priority_queue<int,vector<int>,greater<int> >
#define npql priority_queue<ll,vector<ll>,greater<ll> >
#define forup(i,a,b) for ((i)=(a);(i)<=(b);(i)++)
#define fordo(i,a,b) for ((i)=(a);(i)>=(b);(i)--)
#define rep(i,x) forup ((i),1,(x))
#define repd(i,x) fordo ((i),(x),1)
#define rep0(i,x) forup ((i),0,((int)(x))-1)
#define rep0d(i,x) fordo ((i),((int)(x))-1,0)
#define itr iterator
#define fe(itcalc,c) for(__typeof((c).begin()) itcalc=(c).begin();itcalc!=(c).end();itcalc++)
#define NO {cout<<"NO";return 0;}
#define YES {cout<<"YES";return 0;}
#define y0 y000000000000000000000000000
#define y1 y111111111111111111111111111
#define j0 j000000000000000000000000000
#define j1 j111111111111111111111111111
#define cl0(a) memset((a),(0),(sizeof((a))))
#define clz(a) memset((a),(0x16),(sizeof((a))))
#define clf(a) memset((a),(-(0x16)),(sizeof((a))))
#define inf 0x3bbbbbbb
#define lnf 0x3bbbbbbbbbbbbbbbll
//#define sqrt divi
#define p2(i) (1ll<<(i))
#define readi read
#define readll read
/*************************************************/
int n,m,g,cg,cn,i,j,k,l,ch[105][2],fa[105],ban[105],cnt=1,fr[105];
vector<int> e[105],ef[105];int lc[105],rc[105];
ll dp[105][105][105];
priority_queue<pair<long long,pair<int,pair<int,int> > >,vector<pair<long long,pair<int,pair<int,int> > > >,greater<pair<long long,pair<int,pair<int,int> > > > >pq;
void upd(int x,int y,int z,long long c)
{
	if(c<dp[x][y][z]){
		dp[x][y][z]=c;
		pq.push(make_pair(c,make_pair(x,make_pair(y,z))));
	}
}
int main()
{
	read(g);read(n);read(m);cg=g;cn=n;
	rep(i,n){
		lc[i]=rc[i]=-1;
		int x,y,t;
		read(x);read(y);
		e[x].pb(t=i);
		read(lc[t]);y--;
		while(y--){
			if(y==0){
				read(rc[t]);
			}
			else{
				rc[t]=cg++;
				e[cg-1].push_back(++cn);
				t=cn;read(lc[t]);rc[t]=-1;
			}
		}
	}
	rep0(i,cg){
		fe(it,e[i]) fr[*it]=i;
	}
	rep(i,cn){
		ef[lc[i]].pb(i);
		if(rc[i]!=-1&&rc[i]!=lc[i]) ef[rc[i]].pb(i);
	}
	rep(i,m){
		int x=1,l;
		read(l);
		while(l--){
			int t;read(t);
			if(!ch[x][t]) ch[x][t]=++cnt;
			x=ch[x][t];
		}ban[x]=1;
	}
	queue<int> q;
	rep0(i,2)if(ch[1][i]){q.push(ch[1][i]);fa[ch[1][i]]=1;} else ch[1][i]=1;
	while(!q.empty()){
		int x=q.front();q.pop();
		ban[x]|=ban[fa[x]];
		rep0(i,2)if(ch[x][i]){
			q.push(ch[x][i]);
			fa[ch[x][i]]=ch[fa[x]][i];
		}else ch[x][i]=ch[fa[x]][i];
	}
	clz(dp);
	rep(i,cnt){
		if(!ban[i]){
			if(!ban[ch[i][0]]){
				upd(0,i,ch[i][0],1);
			}
			if(!ban[ch[i][1]]){
				upd(1,i,ch[i][1],1);
			}
		}
	}
	while(!pq.empty()){
		long long v=pq.top().fi;
		int x=pq.top().se.fi,a=pq.top().se.se.fi,b=pq.top().se.se.se;pq.pop();
		if(dp[x][a][b]!=v) continue;
		fe(it,ef[x]){
			if(lc[*it]==x){
				if(rc[*it]==-1){
					upd(fr[*it],a,b,v);
					continue;
				}
				rep(i,cnt){
					upd(fr[*it],a,i,v+dp[rc[*it]][b][i]);
				}
			}
			if(rc[*it]==x){
				rep(i,cnt){
					upd(fr[*it],i,b,v+dp[lc[*it]][i][a]);
				}
			}
		}
	}
	forup(i,2,g-1){
		ll ans=dp[104][104][104];
		rep(j,cnt)if(!ban[j])ans=min(ans,dp[i][1][j]);
		if(ans>=dp[104][104][104]){
			puts("YES");
		}
		else{
			printf("NO %lld\n",ans);
		}
	}
	return 0;
}

#include <cstdio>
#include <cstring>
#include <queue>
#include <functional>

template<typename T> bool ckmax(T& a, const T& b) {return b>a?a=b,1:0;}
template<typename T> bool ckmin(T& a, const T& b) {return b<a?a=b,1:0;}

using ull = unsigned long long;
using ll = long long;

const ull INF = 0xffffffffffffffff;

const int MG = 120;
const int ML = 55;

int G, N, M, X, L, c[ML][2], g[ML][2], l[ML], q[ML];
bool bad[ML], vis[MG*2][ML][ML];
std::vector<std::vector<int> > jmp[MG*2];
ull dp[MG*2][ML][ML];
struct Tran
{
	public:
		int g, i;//g = gene to transition to, i>>1 = "pair" gene, i&1 = 0 your index in the 2-vector. If i == -1: then its a single transition
};
std::vector<Tran> tr[MG*2];
struct State
{
	public:
		int g, s, e;
		ull w;
		bool operator > (const State& o) const {return w > o.w;}
};
std::priority_queue<State, std::vector<State>, std::greater<State> > pq;

void build_aho()
{
	l[0]=-1;
	q[0]=0;
	memset(g[0], 0, sizeof*g);
	for(int i=0,Q=1,n;i<Q;++i)
	{
		n=q[i];
		if(~l[n])
		{
			memcpy(g[n], g[l[n]], sizeof*g);
			bad[n]|=bad[l[n]];
		}
		for(int x=0;x<=1;++x)
			if(~c[n][x])
			{
				g[n][x]=c[n][x];
				l[c[n][x]]=~l[n]?g[l[n]][x]:0;
				q[Q++]=c[n][x];
			}
	}
}

int main()
{
	memset(dp, 0xff, sizeof dp);
	scanf("%d%d%d", &G, &N, &M);
	X=G;
	for(int i=0;i<N;++i)
	{
		int a,k,u;
		scanf("%d%d", &a, &k);
		if(k==1)
		{
			scanf("%d",&u);
			jmp[a].push_back({u});
			tr[u].push_back({a,-1});
		}
		else
		{
			for(int j=0;j+2<k;++j)
			{
				scanf("%d", &u);
				jmp[a].push_back({u, X});
				tr[u].push_back({a, X<<1});
				tr[X].push_back({a, u<<1|1});
				a=X++;
			}
			int v;
			scanf("%d%d", &u, &v);
			jmp[a].push_back({u,v});
			tr[u].push_back({a, v<<1});
			tr[v].push_back({a, u<<1|1});
		}
	}
	memset(c, -1, sizeof c);
	for(int i=0,l;i<M;++i)
	{
		scanf("%d", &l);
		int n=0;
		for(int j=0,x;j<l;++j)
		{
			scanf("%d", &x);
			if(~c[n][x]) n=c[n][x]; else n=c[n][x]=++L;
		}
		bad[n]=1;
	}
	build_aho();
	for(int i=0;i<=L;++i)
		if(!bad[i])
			for(int v=0,x;v<2;++v)
				if(!bad[x=g[i][v]])
					dp[v][i][x]=1, pq.push({v, i, x, dp[v][i][x]});
	for(State n;!pq.empty();)
	{
		n=pq.top(); pq.pop();
		if(vis[n.g][n.s][n.e]) continue;
		vis[n.g][n.s][n.e]=1;
		for(auto t:tr[n.g])
			if(~t.i)
				if(t.i&1)
				{
					int y=t.i>>1, g=t.g;
					for(int i=0;i<=L;++i)
						if(~dp[y][i][n.s] && ckmin(dp[g][i][n.e], dp[y][i][n.s]+dp[n.g][n.s][n.e]))
							pq.push({g, i, n.e, dp[g][i][n.e]});
				}
				else
				{
					int y=t.i>>1, g=t.g;
					for(int i=0;i<=L;++i)
						if(~dp[y][n.e][i] && ckmin(dp[g][n.s][i], dp[n.g][n.s][n.e]+dp[y][n.e][i]))
							pq.push({g, n.s, i, dp[g][n.s][i]});
				}
			else if(ckmin(dp[t.g][n.s][n.e], dp[n.g][n.s][n.e]))
				pq.push({t.g, n.s, n.e, dp[t.g][n.s][n.e]});
	}
	for(int i=2;i<G;++i)
	{
		ull f=INF;
		for(int j=0;j<=L;++j)
			if(!bad[j])
				ckmin(f, dp[i][0][j]);
		if(!~f)
			printf("YES\n");
		else
			printf("NO %llu\n", f);
	}
	return 0;
}

#include <cstdio>
#include <cassert>
#include <vector>
#include <set>
#include <tuple>
#include <map>
#include <queue>
using namespace std;

#define REP(i,a,b) for (int i = (a); i < (b); i++)

typedef long long ll;
typedef unsigned long long ull;

const ull INF = 1ull<<63;

ull add(ull a, ull b) {
	if (a == INF)
		return INF;
	return min(a+b, INF);
}

int G, N, M;
vector<int> rule_genes;
vector<vector<int> > rules;

vector<vector<bool> > words;

int P;
map<vector<bool>,int> ma;
vector<array<int,2> > adj;

int visit(vector<bool> bla) {
	while(true) {
		bool found = false;
		for (const vector<bool>& word : words) {
			if (bla.size() <= word.size()) {
				bool ok = true;
				REP(i,0,(int)bla.size())
					if (bla[i] != word[i])
						ok = false;
				if (ok)
					found = true;
			}
		}
		if (found || bla.empty())
			break;
		assert(!bla.empty());
		bla.erase(bla.begin());
	}
	bool detected = false;
	for (const vector<bool>& word : words) {
		if (bla.size() >= word.size()) {
			bool ok = true;
			REP(i,0,(int)word.size())
				if (bla[bla.size()-i-1] != word[word.size()-i-1])
					ok = false;
			if (ok)
				detected = true;
		}
	}
	if (detected) {
		return 0;
	} else {
		if (ma.count(bla))
			return ma[bla];
		int p = ma[bla] = P;
		adj.emplace_back();
		P++;
// 		printf("%d: ", p);
// 		for (bool b : bla)
// 			printf("%d", b);
// 		printf("\n");
		REP(c,0,2) {
			bla.push_back(c);
			assert((int)adj.size() > p);
			int h = visit(bla);
			adj[p][c] = h;
			bla.pop_back();
		}
// 		printf("%d -> %d %d\n", p, adj[p][0], adj[p][1]);
		return p;
	}
}

vector<vector<vector<ull> > > dp1; // dp1[g][a][b] = shortest path through gene g, going from state a to state b.
vector<vector<vector<vector<ull> > > > dp2; // dp2[n][i][a][b] = shortest path from beginning of rule n to after the first i constituents of rule n, going from state a to state b.

struct st {
	ull d;
	int n, i, a, b;
	friend bool operator<(const st& x, const st& y) {
		return x.d > y.d;
	}
};

int main() {
	P = 1;
	adj.emplace_back(array<int,2>{0,0});
	scanf("%d%d%d", &G, &N, &M);
	rule_genes.resize(N);
	rules.resize(N);
	REP(n,0,N) {
		int g, L;
		scanf("%d%d", &g, &L);
		rule_genes[n] = g;
		rules[n].resize(L);
		REP(i,0,L)
			scanf("%d", &rules[n][i]);
	}
	REP(m,0,M) {
		int L;
		scanf("%d", &L);
		vector<bool> word;
		REP(i,0,L) {
			int c;
			scanf("%d", &c);
			word.push_back(c);
		}
		words.push_back(word);
	}
	visit({});
	dp1.assign(G, vector<vector<ull> >(P, vector<ull>(P, INF)));
	dp2.resize(N);
	REP(n,0,N)
		dp2[n].assign(rules[n].size()+1, vector<vector<ull> >(P, vector<ull>(P, INF)));
	priority_queue<st> qu;
	REP(g,0,2) REP(a,0,P) {
		int b = adj[a][g];
		dp1[g][a][b] = 1;
		qu.push(st{1,g,-1,a,b});
	}
	REP(n,0,N) REP(a,0,P) {
		dp2[n][0][a][a] = 0;
		qu.push(st{0,n,0,a,a});
	}
	while(!qu.empty()) {
		st s = qu.top();
		ull d = s.d;
		qu.pop();
		if (s.i == -1) {
			int g = s.n, b = s.a, c = s.b;
			if (dp1[g][b][c] != d)
				continue;
// 			fprintf(stderr, "dp1[%d][%d][%d] = %llu\n", g, b, c, d);
			REP(n,0,N) REP(i,0,(int)rules[n].size()) {
				if (rules[n][i] == g) {
					REP(a,0,P) {
						ull ds = add(dp2[n][i][a][b], d);
						if (dp2[n][i+1][a][c] > ds) {
							dp2[n][i+1][a][c] = ds;
							qu.push(st{ds,n,i+1,a,c});
						}
					}
				}
			}
		} else {
			int n = s.n, i = s.i, a = s.a, b = s.b;
			if (dp2[n][i][a][b] != d)
				continue;
// 			fprintf(stderr, "dp2[%d][%d][%d][%d] = %llu\n", n, i, a, b, d);
			int L = rules[n].size();
			if (i == L) {
				int g = rule_genes[n];
				if (dp1[g][a][b] > d) {
					dp1[g][a][b] = d;
					qu.push(st{d,g,-1,a,b});
				}
			} else {
				int gs = rules[n][i];
				REP(c,0,P) {
					ull ds = add(d, dp1[gs][b][c]);
					if (dp2[n][i+1][a][c] > ds) {
						dp2[n][i+1][a][c] = ds;
						qu.push(st{ds,n,i+1,a,c});
					}
				}
			}
		}
	}
	REP(g,2,G) {
		ull res = INF;
		REP(b,1,P)
			res = min(res, dp1[g][1][b]);
		if (res == INF)
			printf("YES\n");
		else
			printf("NO %llu\n", res);
	}
	return 0;
}

/*
after dusk passed,
there is a starry sky.
*/
#include <bits/stdc++.h>
#define inf 9223372036854775809
#define m_k make_pair
#define int unsigned long long
using namespace std;
const int N=110,L=55;
int g,n,m,dp[N*2][L][L],k[N],sh[N][N],id[N][N];
int cnt,c[L],tot,kind[N*N],vi[N*2][L][L];
pair <int,int> tr[N*N];
vector <int> to[N];
struct st
{
	int i,j,k,num;
};
bool operator <(st a,st b){return a.num>b.num;}
priority_queue <st> q;
inline int read()
{
	int f=1,x=0;char s=getchar();
	while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
	while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
	return x*f;
}
namespace Aho
{
	struct node
	{
		int son[2],fail,ok;
	}sh[L*2];
	inline void insert(int l)
	{
		int x=1;
		for (int i=1;i<=l;i++)
		{
			int p=sh[x].son[c[i]];
			if (!p) p=++cnt;
			sh[x].son[c[i]]=p;
			x=p;
		}
		sh[x].ok=1;
	}
	inline void build_fail()
	{
		queue <int> q;q.push(1);
		while (!q.empty())
		{
			int x=q.front();q.pop();
			sh[x].ok|=sh[sh[x].fail].ok;
			for (int i=0;i<2;i++)
			{
				if (!sh[x].son[i])
				{
					if (x==1) sh[x].son[i]=1;
					else sh[x].son[i]=sh[sh[x].fail].son[i];
				}
				else
				{
					if (x==1) sh[sh[x].son[i]].fail=1;
					else sh[sh[x].son[i]].fail=sh[sh[x].fail].son[i];
					q.push(sh[x].son[i]);
				}
			}
		}
	}
	inline void init()
	{
		for (int i=0;i<=tot;i++)for(int j=1;j<=cnt;j++)for(int k=1;k<=cnt;k++) dp[i][j][k]=inf;
		for (int i=1;i<=cnt;i++)
		{
			if (sh[i].ok) continue;
			int j=sh[i].son[0];
			if (!sh[j].ok) dp[0][i][j]=1,q.push((st){0,i,j,1});
			j=sh[i].son[1];
			if (!sh[j].ok) dp[1][i][j]=1,q.push((st){1,i,j,1});
		}
	}
}
signed main()
{
	// freopen("1.in","r",stdin);
	g=read();n=read();m=read();
	tot=g-1;
	for (int i=1;i<=n;i++)
	{
		sh[i][0]=read();k[i]=read();
		for (int j=1;j<=k[i];j++)
		{
			sh[i][j]=read(),id[i][j]=++tot;
			to[sh[i][j]].push_back(tot);
			tr[tot]=m_k(i,j);
			if (j==1) kind[tot]|=1;
			if (j==k[i]) kind[tot]|=2;
		}
	}
	cnt=1;
	for (int i=1;i<=m;i++)
	{
		int l=read();
		for (int j=1;j<=l;j++) c[j]=read();
		Aho::insert(l);
	}
	Aho::build_fail();
	Aho::init();
	while (!q.empty())
	{
		st x=q.top();q.pop();
		int i=x.i,j=x.j,k=x.k;
		if (vi[i][j][k]) continue;
		vi[i][j][k]=1;
		if (i<g)
		{
			for (int id=0;id<(int)to[i].size();id++)
			{
				int u=to[i][id];
				if (kind[u]&1)
				{
					if (dp[i][j][k]<dp[u][j][k])
					{
						dp[u][j][k]=dp[i][j][k];
						q.push((st){u,j,k,dp[u][j][k]});
					}
					continue;
				}
				for (int p=1;p<=cnt;p++)
				{
					if (dp[u-1][p][j]+dp[i][j][k]<dp[u][p][k])
					{
						dp[u][p][k]=dp[u-1][p][j]+dp[i][j][k];
						q.push((st){u,p,k,dp[u][p][k]});
					}
				}
			}
		}
		else
		if ((kind[i]>>1)&1)
		{
			int u=sh[tr[i].first][0];
			if (dp[i][j][k]<dp[u][j][k])
			{
				dp[u][j][k]=dp[i][j][k];
				q.push((st){u,j,k,dp[u][j][k]});
			}
		}
		else
		{
			int num=sh[tr[i].first][tr[i].second+1];
			for (int p=1;p<=cnt;p++)
			{
				if (dp[i][j][k]+dp[num][k][p]<dp[i+1][j][p])
				{
					dp[i+1][j][p]=dp[i][j][k]+dp[num][k][p];
					q.push((st){i+1,j,p,dp[i+1][j][p]});
				}
			}
		}
	}
	for (int i=2;i<g;i++)
	{
		unsigned long long ans=inf;
		for (int j=1;j<=cnt;j++)
		{
			for (int k=1;k<=cnt;k++) ans=min(ans,dp[i][j][k]);
		}
		if (ans==inf) printf("YES\n");
		else printf("NO %lld\n",ans);
	}
}

/*input
3 2 1
2 1 0
2 2 2 1
1 0
*/

#include <iostream>
#include <vector>
#include <algorithm>
#include <array>
#include <queue>
#include <tuple>

// .......

using namespace std;

const uint64_t INF = 1ull << 63;

struct AhoCorasick
{
	int n;
	vector<array<int, 2>> go, child;
	vector<int> par, link, terminal;

	AhoCorasick(): n(1), child(n + 1, {0, 0}), par(n + 1, 0), terminal(n + 1, 0) {};

	void addString(vector<int> str)
	{
		int u = 1;
		for (int c : str) {
			if (!child[u][c]) {
				child[u][c] = ++n;
				child.push_back({0, 0});
				par.push_back(u);
				terminal.push_back(false);
			}
			u = child[u][c];
		}
		terminal[u] = true;
	}

	void build()
	{
		go.resize(n + 1);
		link.resize(n + 1);

		queue<int> qu;
		qu.push(1);
		link[1] = 1;
		while (!qu.empty()) {
			int u = qu.front();
			qu.pop();

			if (terminal[link[u]] || terminal[par[u]]) terminal[u] = true;

			go[u][0] = (child[u][0] ? child[u][0] : (u == 1 ? 1 : go[link[u]][0]));
			go[u][1] = (child[u][1] ? child[u][1] : (u == 1 ? 1 : go[link[u]][1]));

			for (int c = 0; c < 2; ++c) if (child[u][c]) {
				int v = child[u][c];
				link[v] = (u == 1 ? 1 : go[link[u]][c]);
				qu.push(v);
			}
		}
	}
};

int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	int G, N, M;
	cin >> G >> N >> M;

	vector<tuple<int, int, int>> muts; // mutations ...
	vector<vector<int>> conOf(G);
	vector<uint64_t> ans(G, INF);

	for (int i = 0; i < N; ++i) {
		int a, cnt, x, y, z;
		cin >> a >> cnt >> x;

		if (cnt == 1) {
			conOf[x].push_back((int) muts.size());
			muts.emplace_back(x, -1, a);
			continue;
		}

		for (int j = 1; j < cnt; ++j) {
			cin >> y;

			if (j == cnt - 1) z = a;
			else {
				z = (int) conOf.size();
				conOf.emplace_back();
			}

			conOf[x].push_back((int) muts.size());
			conOf[y].push_back((int) muts.size());
			muts.emplace_back(x, y, z);
			x = z;
		}
	}

	AhoCorasick ac;
	for (int i = 0; i < M; ++i) {
		int cnt;
		cin >> cnt;
		vector<int> str(cnt);
		for (int &x : str) cin >> x;
		ac.addString(str);
	}

	ac.build();
	int S = ac.n, H = (int) conOf.size();
	vector<vector<vector<uint64_t>>> dp(H, vector<vector<uint64_t>>(S + 1, vector<uint64_t>(S + 1, INF)));

	using pq_type = tuple<uint64_t, int, int, int>;
	priority_queue<pq_type, vector<pq_type>, greater<pq_type>> pq;
	for (int u = 1; u <= S; ++u) if (!ac.terminal[u]) {
		for (int k = 0; k < 2; ++k) {
			int v = ac.go[u][k];
			if (!ac.terminal[v]) {
				dp[k][u][v] = 1;
				pq.emplace(1, k, u, v);
			}
		}
	}

	int ansLeft = G - 2;
	while (!pq.empty() && ansLeft > 0) {
		uint64_t dist;
		int u, x, y;
		tie(dist, u, x, y) = pq.top();
		pq.pop();
		if (dist > dp[u][x][y]) continue;
		if (1 < u && u < G && ans[u] > dist) --ansLeft, ans[u] = dist;

		for (int i : conOf[u]) {
			int w = get<2>(muts[i]);
			int v = u ^ get<0>(muts[i]) ^ get<1>(muts[i]);
			if (v == -1) {
				if (dp[w][x][y] > dist) {
					pq.emplace(dp[w][x][y] = dist, w, x, y);
				}
				continue;
			}

			if (u == get<0>(muts[i])) {
				for (int z = 1; z <= S; ++z) {
					if (dp[u][x][y] + dp[v][y][z] < dp[w][x][z]) {
						pq.emplace(dp[w][x][z] = dp[u][x][y] + dp[v][y][z], w, x, z);
					}
				}
			}

			if (u == get<1>(muts[i])) {
				for (int z = 1; z <= S; ++z) {
					if (dp[v][z][x] + dp[u][x][y] < dp[w][z][y]) {
						pq.emplace(dp[w][z][y] = dp[v][z][x] + dp[u][x][y], w, z, y);
					}
				}
			}
		}
	}

	for (int i = 2; i < G; ++i) {
		if (ans[i] == INF) {
			cout << "YES\n";
		} else {
			cout << "NO " << ans[i] << '\n';
		}
	}
}

/*

Author: Asriel Dreemurr

Created on: 2020-9-2 18:31

*/

#include <bits/stdc++.h>
const int maxn = 205;
typedef unsigned long long ull;
const ull inf = 1ull << 63;
ull dp[205][205][205];
int ch[maxn][2],mark[maxn],a[maxn],k[maxn],b[maxn][maxn],link[maxn],g,n,m,tl,x,s[maxn];

struct data {
	ull v; int x,s,t;
};
std::priority_queue<data>q;

bool operator < (data a, data b) { return a.v > b.v; }
data dat(ull v1,int x1,int s1,int t1) { data d; d.v=v1; d.x=x1; d.s=s1; d.t=t1; return d; }

void insert(int len) {
	int rt = 0;
	for (int i = 1; i <= len; ++ i) {
		if (!ch[rt][s[i]]) ch[rt][s[i]] = ++tl;
		rt = ch[rt][s[i]];
	} mark[rt] = 1;
}

void build() {
	std::queue <int> q;
	std::memset(link,-1,sizeof(link));
	link[0] = 0;
	for (int i = 0; i < 2; ++ i) if (ch[0][i]) { q.push(ch[0][i]); link[ch[0][i]] = 0; }
	while (!q.empty()) {
		int u = q.front(); q.pop();
		mark[u] |= mark[link[u]];
		for (int i = 0; i < 2; ++ i) {
			if (ch[u][i]) { mark[ch[u][i]] |= mark[u]; link[ch[u][i]] = ch[link[u]][i]; q.push(ch[u][i]); }
			else ch[u][i] = ch[link[u]][i];
		}
	}
}

void update(int x,int s,int t,ull v) {

	if ( v >= dp[x][s][t] ) return;
//	printf("update %d %d %d -> %lld\n",x,s,t,v);
	dp[x][s][t] = v;
	q.push(dat(v,x,s,t));
}

int main() {
	scanf("%d%d%d",&g,&n,&m); g--; int gi = g;
	for (int i = 1; i <= n; ++ i) {
		scanf("%d%d",&a[i],&k[i]);
		for (int j = 1; j <= k[i]; ++ j) scanf("%d",&b[i][j]);
	}
	for (int i = 1; i <= n; ++ i) {
		if (k[i] > 2) {
			++n; k[n] = k[i] - 1; a[n] = ++g;
			for (int j = 2; j <= k[i]; ++ j) b[n][j-1] = b[i][j];
			k[i] = 2; b[i][2] = g;
		}// printf("%d:",a[i]);
	//	for (int j = 1; j <= k[i]; ++ j) printf("%d ",b[i][j]); puts("");
	} //return 0;
	for (int i = 1; i <= m; ++ i) {
		scanf("%d",&x);
		for (int j = 1; j <= x; ++ j) scanf("%d",&s[j]);
		insert(x);
	} build();
	for (int i = 0; i <= g; ++ i)
	for (int j = 0; j <= tl; ++ j)
	for (int k = 0; k <= tl; ++ k)
		dp[i][j][k] = inf;

	for (int i = 0; i < 2; ++ i) {
		for (int j = 0; j <= tl; ++ j)
		if (!mark[j] && !mark[ch[j][i]]) {
			dp[i][j][ch[j][i]] = 1;
			q.push(dat(1,i,j,ch[j][i]));
		}
	} while (!q.empty()) {
		data d = q.top(); q.pop();
		ull v = d.v;
		int s = d.s, t = d.t, x = d.x;
		//printf("%lld %d %d %d\n",v,x,s,t);
		if (v != dp[x][s][t]) continue;
		for (int j = 1; j <= n; ++ j) {
			if (k[j] == 1 && b[j][1] == x) update(a[j],s,t,v);
			if (k[j] == 2) {
				if (b[j][1] == x)
					for (int T = 0; T <= tl; ++ T) update(a[j],s,T,v + dp[b[j][2]][t][T]);
				if (b[j][2] == x)
					for (int S = 0; S <= tl; ++ S) update(a[j],S,t,v + dp[b[j][1]][S][s]);
			}
		}
	} for (int i = 2; i <= gi; ++ i) {
		ull ans = inf;
		for (int j = 0; j <= tl; ++ j) ans = std::min ( ans, dp[i][0][j] );
		if (ans == inf) puts("YES");
		else printf("NO %lld\n",ans);
	}
	return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
priority_queue<pair<pair<LLI,int>,pii> > H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
            if (leaf[u]) nxt[u][i] = u;
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        for (j = 0; j < 2; j++) dist[j][i][nxt[i][j]] = 1,H.push(mp(mp(-1,j),mp(i,nxt[i][j])));
    }
    while (!H.empty()) {
        ULLI d = -H.top().first.first;
        int u = H.top().first.second;
        int a = H.top().second.first;
        int b = H.top().second.second;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.push(mp(mp(-dist[v][a][b],v),mp(a,b)));
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (dist[w][j][a]+dist[u][a][b] < dist[v][j][b]) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.push(mp(mp(-dist[v][j][b],v),mp(j,b)));
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (dist[u][a][b]+dist[w][b][j] < dist[v][a][j]) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.push(mp(mp(-dist[v][a][j],v),mp(a,j)));
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
struct state {
    ULLI d; int u,a,b;
    state(ULLI dd,int uu,int aa,int bb) {
        d = dd,u = uu,a = aa,b = bb;
    }
};
class comp {
    public:
        bool operator()(state a,state b) {
            return a.d > b.d;
        }
};
priority_queue<state,vector<state>,comp> H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        if (leaf[i]) continue;
        for (j = 0; j < 2; j++) {
            if (!leaf[nxt[i][j]]) dist[j][i][nxt[i][j]] = 1,H.emplace(1,j,i,nxt[i][j]);
        }
    }
    while (!H.empty()) {
        ULLI d = H.top().d;
        int u = H.top().u,a = H.top().a,b = H.top().b;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.emplace(dist[v][a][b],v,a,b);
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[w][j][a]+dist[u][a][b] < dist[v][j][b])) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.emplace(dist[v][j][b],v,j,b);
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[u][a][b]+dist[w][b][j] < dist[v][a][j])) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.emplace(dist[v][a][j],v,a,j);
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
priority_queue<pair<pair<LLI,int>,pii> > H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        if (leaf[i]) continue;
        for (j = 0; j < 2; j++) {
            if (!leaf[nxt[i][j]]) dist[j][i][nxt[i][j]] = 1,H.push(mp(mp(-1,j),mp(i,nxt[i][j])));
        }
    }
    while (!H.empty()) {
        ULLI d = -H.top().first.first;
        int u = H.top().first.second;
        int a = H.top().second.first;
        int b = H.top().second.second;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.push(mp(mp(-dist[v][a][b],v),mp(a,b)));
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (dist[w][j][a]+dist[u][a][b] < dist[v][j][b]) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.push(mp(mp(-dist[v][j][b],v),mp(j,b)));
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (dist[u][a][b]+dist[w][b][j] < dist[v][a][j]) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.push(mp(mp(-dist[v][a][j],v),mp(a,j)));
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------
#pragma GCC optimize("Ofast")

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
priority_queue<pair<pair<LLI,int>,pii> > H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        if (leaf[i]) continue;
        for (j = 0; j < 2; j++) {
            if (!leaf[nxt[i][j]]) dist[j][i][nxt[i][j]] = 1,H.push(mp(mp(-1,j),mp(i,nxt[i][j])));
        }
    }
    while (!H.empty()) {
        ULLI d = -H.top().first.first;
        int u = H.top().first.second;
        int a = H.top().second.first;
        int b = H.top().second.second;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.push(mp(mp(-dist[v][a][b],v),mp(a,b)));
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[w][j][a]+dist[u][a][b] < dist[v][j][b])) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.push(mp(mp(-dist[v][j][b],v),mp(j,b)));
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[u][a][b]+dist[w][b][j] < dist[v][a][j])) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.push(mp(mp(-dist[v][a][j],v),mp(a,j)));
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
struct state { ULLI d; int u,a,b; };
class comp {
    public:
        bool operator()(state a,state b) {
            return a.d > b.d;
        }
};
priority_queue<state,vector<state>,comp> H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        if (leaf[i]) continue;
        for (j = 0; j < 2; j++) {
            if (!leaf[nxt[i][j]]) dist[j][i][nxt[i][j]] = 1,H.push((state){1,j,i,nxt[i][j]});
        }
    }
    while (!H.empty()) {
        ULLI d = H.top().d;
        int u = H.top().u,a = H.top().a,b = H.top().b;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.push((state){dist[v][a][b],v,a,b});
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[w][j][a]+dist[u][a][b] < dist[v][j][b])) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.push((state){dist[v][j][b],v,j,b});
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[u][a][b]+dist[w][b][j] < dist[v][a][j])) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.push((state){dist[v][a][j],v,a,j});
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int b[100];
vector<pair<pii,int> > adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
priority_queue<pair<pair<LLI,int>,pii> > H;
ULLI dist[102][51][51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,l,c;
    scanf("%d %d %d",&G,&N,&M);
    int G2 = G;
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        for (j = 0; j < k; j++) scanf("%d",&b[j]);
        if (k == 1) adjList[b[0]].pb(mp(mp(a,-1),-1));
        else {
            for (j = 1; j < k; j++) {
                if (j == k-1) {
                    adjList[b[j-1]].pb(mp(mp(a,b[j]),1));
                    adjList[b[j]].pb(mp(mp(a,b[j-1]),0));
                }
                else {
                    adjList[b[j-1]].pb(mp(mp(a,G2),1));
                    adjList[G2].pb(mp(mp(a,b[j-1]),0));
                    a = G2++;
                }
            }
        }
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num;
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;

    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) nxt[0][i] = trie[0][i],fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else nxt[0][i] = trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                nxt[u][i] = trie[u][i],Q.push(trie[u][i]);
            }
            else nxt[u][i] = nxt[fail[u]][i];
        }
    }

    for (i = 0; i < G2; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,1ULL << 63);
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    for (i = 0; i < num; i++) {
        if (leaf[i]) continue;
        for (j = 0; j < 2; j++) {
            if (!leaf[nxt[i][j]]) dist[j][i][nxt[i][j]] = 1,H.push(mp(mp(-1,j),mp(i,nxt[i][j])));
        }
    }
    while (!H.empty()) {
        ULLI d = -H.top().first.first;
        int u = H.top().first.second;
        int a = H.top().second.first;
        int b = H.top().second.second;
        H.pop();

        if (d > dist[u][a][b]) continue;
        for (i = 0; i < adjList[u].size(); i++) {
            int v = adjList[u][i].first.first,w = adjList[u][i].first.second;
            if (adjList[u][i].second == -1) {
                if (dist[u][a][b] < dist[v][a][b]) {
                    dist[v][a][b] = dist[u][a][b];
                    H.push(mp(mp(-dist[v][a][b],v),mp(a,b)));
                }
            }
            else if (adjList[u][i].second == 0) {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[w][j][a]+dist[u][a][b] < dist[v][j][b])) {
                        dist[v][j][b] = dist[w][j][a]+dist[u][a][b];
                        H.push(mp(mp(-dist[v][j][b],v),mp(j,b)));
                    }
                }
            }
            else {
                for (j = 0; j < num; j++) {
                    if (!leaf[j] && (dist[u][a][b]+dist[w][b][j] < dist[v][a][j])) {
                        dist[v][a][j] = dist[u][a][b]+dist[w][b][j];
                        H.push(mp(mp(-dist[v][a][j],v),mp(a,j)));
                    }
                }
            }
        }
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1ULL << 63;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == (1ULL << 63)) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define mp make_pair
#define pb push_back
typedef long long int LLI;
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef vector<pii> vpii;
typedef unsigned long long int ULLI;
#pragma GCC optimize("Ofast")

vector<vi> poss[102];
vpii adjList[102];
int trie[51][2],leaf[51],fail[51],nxt[51][2],num = 0;
queue<int> Q;
deque<pii> Q2;
ULLI dist[102][51][51],temp[51][51],temp2[51][51];
int inQueue[102][102],bad[102],done[102],done2[102][102];
string ss[51];
int main() {
    int i,j;
    int G,N,M;
    int a,k,b,l,c;
    scanf("%d %d %d",&G,&N,&M);
    memset(trie,-1,sizeof(trie));
    for (i = 0; i < N; i++) {
        scanf("%d %d",&a,&k);
        poss[a].pb(vi());
        for (j = 0; j < k; j++) scanf("%d",&b),poss[a].back().pb(b),adjList[b].pb(mp(a,poss[a].size()-1));
    }
    for (i = 0; i < M; i++) {
        scanf("%d",&l);
        int u = 0;
        for (j = 0; j < l; j++) {
            scanf("%d",&c);
            if (trie[u][c] == -1) trie[u][c] = ++num,ss[trie[u][c]] = ss[u]+((char) (c+'0'));
            u = trie[u][c];
        }
        leaf[u] = 1;
    }
    num++;
/*
    for (i = 0; i < 2; i++) {
        if (trie[0][i] != -1) fail[trie[0][i]] = 0,Q.push(trie[0][i]);
        else trie[0][i] = 0;
    }
    while (!Q.empty()) {
        int u = Q.front();
        Q.pop();

        for (i = 0; i < 2; i++) {
            if (trie[u][i] != -1) {
                int v = fail[u];
                while (trie[v][i] == -1) v = fail[v];
                v = trie[v][i];
                fail[trie[u][i]] = v,leaf[trie[u][i]] |= leaf[v];
                Q.push(trie[u][i]);
            }
        }
    }
*/
    for (i = 0; i < G; i++) {
        for (j = 0; j < num; j++) fill(dist[i][j],dist[i][j]+num,(ULLI) 1e19);
    }
/*
    for (i = 0; i < num; i++) {
        for (j = 0; j < 2; j++) {
            if (leaf[i]) nxt[i][j] = i;
            else if (trie[i][j] != -1) nxt[i][j] = trie[i][j];
            else nxt[i][j] = nxt[fail[i]][j];
            cout<<nxt[i][j]<<" ";
        }
        cout<<endl;
    }*/
    for (i = 0; i < num; i++) {
        for (j = 0; j < 2; j++) {
            nxt[i][j] = 0;
            string s = ss[i]+((char) (j+'0'));
            for (k = 0; k < num; k++) {
                if ((ss[k].size() <= s.size()) && (s.substr(s.size()-ss[k].size(),ss[k].size()) == ss[k])) {
                    if (ss[k].size() > ss[nxt[i][j]].size()) nxt[i][j] = k;
                }
            }
        }
    }
    for (i = 0; i < num; i++) {
        for (j = 0; j < num; j++) {
            if (ss[j].size() > ss[i].size()) continue;
            if (leaf[j] && (ss[i].substr(ss[i].size()-ss[j].size(),ss[j].size()) == ss[j])) leaf[i] = 1;
        }
        if (leaf[i]) nxt[i][0] = nxt[i][1] = i;
    }
    for (i = 0; i < num; i++) {
        for (j = 0; j < 2; j++) dist[j][i][nxt[i][j]] = 1;
    }
    int m;
    for (i = 2; i < G; i++) {
        bad[i] = 1;
        for (j = 0; j < poss[i].size(); j++) {
            for (k = 0; k < poss[i][j].size(); k++) {
                if (poss[i][j][k] > 1) break;
            }
            if (k == poss[i][j].size()) Q2.pb(mp(i,j)),inQueue[i][j] = 1;
        }
        sort(adjList[i].begin(),adjList[i].end());
        adjList[i].resize(unique(adjList[i].begin(),adjList[i].end())-adjList[i].begin());
    }
    while (!Q2.empty()) {
        int u = Q2.front().first;
        int i = Q2.front().second;
        Q2.pop_front(),inQueue[u][i] = 0;
        if (done2[u][i]) continue;

        int f = 0;
        for (j = 0; j < poss[u][i].size(); j++) {
            if (bad[poss[u][i][j]]) break;
        }
        if (j == poss[u][i].size()) {
            int c = 0;
            for (j = 0; j < poss[u][i].size(); j++) {
                if (done[poss[u][i][j]] == poss[poss[u][i][j]].size()) c++;
                if (j == 0) memcpy(temp,dist[poss[u][i][j]],sizeof(temp));
                else {
                    for (k = 0; k < num; k++) {
                        for (l = 0; l < num; l++) temp2[k][l] = 1e19;
                        for (m = 0; m < num; m++) {
                            if (temp[k][m] == 1e19) continue;
                            for (l = 0; l < num; l++) {
                                if (dist[poss[u][i][j]][m][l] < 1e19)
                                    temp2[k][l] = min(temp2[k][l],temp[k][m]+dist[poss[u][i][j]][m][l]);
                            }
                        }
                    }
                    memcpy(temp,temp2,sizeof(temp));
                }
            }
            if (c == poss[u][i].size()) done2[u][i] = 1,done[u]++;
            for (j = 0; j < num; j++) {
                for (k = 0; k < num; k++) {
                    if (temp[j][k] < dist[u][j][k]) {
                        dist[u][j][k] = temp[j][k];
                        f = 1;
                    }
                }
            }
        }
        if (f) {
            bad[u] = 0;
            for (i = 0; i < adjList[u].size(); i++) {
                pii v = adjList[u][i];
                if (!inQueue[v.first][v.second]) {
                    if ((v.first == u) && (done[u] == poss[u].size()-1)) Q2.push_front(v);
                    else Q2.pb(v);
                    inQueue[v.first][v.second] = 1;
                }
            }
        }
        else done[u] = adjList[u].size();
    }
    for (i = 2; i < G; i++) {
        ULLI d = 1e19;
        for (j = 0; j < num; j++) {
            if (!leaf[j]) d = min(d,dist[i][0][j]);
        }
        if (d == 1e19) printf("YES\n");
        else printf("NO %llu\n",d);
    }

    return 0;
}

#pragma GCC optimize ("O3")
// #pragma GCC target ("avx")
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}

// ret[i] := #words that is a suffix of t[0:i+1];
const int ALPHA_BASE = 0;
const int ALPHA_SIZE = 2;

struct Node {
    LL sum;
    int mask, head, fail;
    Node() {
	sum = 0;
	mask = 0;
	head = 0;
	fail = 0;
    }
    int child(char c) const {
	int t = c-ALPHA_BASE;
	if (~mask>>t&1) return -1;
	return head + __builtin_popcount(mask & ((1<<t)-1));
    }
};

vector<Node> nodes;

int get_next(int x, char c) {
    while (x >= 0 && ~nodes[x].mask>>(c-ALPHA_BASE)&1) x = nodes[x].fail;
    if (x < 0) return 0;
    else return nodes[x].child(c);
}

template<class ITER> void build(ITER begin, ITER end) {
    int n = end - begin;
    VI idx(n);
    REP (i, n) idx[i] = i;
    sort(idx.begin(), idx.end(), [&](int i, int j){ return begin[i] < begin[j]; });
    nodes.clear();
    nodes.push_back(Node());
    VI depth, left, right;
    depth.push_back(0); left.push_back(0); right.push_back(n);
    for (int i=0; i<(int)nodes.size(); i++) {
	nodes[i].head = nodes.size();
	int j = left[i];
	while (j < right[i] && (int)begin[idx[j]].size() <= depth[i]) {
	    // nodes[i] is end of string begin[idx[j]];
	    // e.g. nodes[i].sum += value[idx[j]]);
	    nodes[i].sum += 1;
	    j++;
	}
	while (j<right[i]) {
	    const char c = begin[idx[j]][depth[i]];
	    int k = j;
	    while (k < right[i] && c == begin[idx[k]][depth[i]]) k++;
	    nodes.push_back(Node());
	    depth.push_back(depth[i]+1); left.push_back(j); right.push_back(k);
	    nodes[i].mask |= 1<<(c-ALPHA_BASE);
	    j = k;
	}
    }

    nodes[0].fail = -1;
    for (int i=1; i<(int)nodes.size(); i++) {
	int k = nodes[i].head;
	for (int j=0; j<ALPHA_SIZE; j++) if (nodes[i].mask>>j&1) {
	    int f = nodes[i].fail;
	    nodes[k].fail = get_next(f, j+ALPHA_BASE);
	    nodes[k].sum += nodes[nodes[k].fail].sum;
	    k++;
	}
    }
}

//VI run(const string &t) {
//    VI v(t.size());
//    int x = 0;
//    REP (i, t.size()) {
//      x = get_next(x, t[i]);
//	v[i] += nodes[x].sum;
//    }
//    return v;
//}

// 3 <= G <= 102;
// 1 <= N <= 100;
// 0 <= M <= 50;

int G, N, M;
struct Mutation {
    int from;
    VI to;

    Mutation() {}

    bool operator<(const Mutation &o) const {
	return from < o.from;
    }
};
vector<Mutation> table;

vector<VI> anti;

__int128 INF;
__int128 dp[111];

namespace SUBTASK1 {
void solve() {
    memset(dp, 0x3f, sizeof dp);
    INF = dp[0];
    dp[0] = dp[1] = 1;

    while (1) {
	bool update = false;
	EACH (e, table) {
	    VI &to = e->to;
	    __int128 sum = 0;
	    EACH (f, to) {
		if (dp[*f] == INF) {
		    sum = INF;
		    break;
		}

		sum += dp[*f];
	    }

	    if (sum < dp[e->from]) {
		update = true;
		dp[e->from] = sum;
	    }
	}

	if (!update) break;
    }
}
}; // SUBTASK1;

namespace SUBTASK2 {

int nxt[55][111]; // [node index][gene] = next node index;
bool dead_edge[55][111];

void solve() {
    build(anti.begin(), anti.end());
    vector<pair<__int128, int> > B;
    for (int i=2; i<G; i++) if (dp[i] != INF) B.emplace_back(dp[i], i);
    sort(B.begin(), B.end());

    memset(nxt, -1, sizeof nxt);
    REP (x, nodes.size()) {
	nxt[x][0] = get_next(x, 0);
	nxt[x][1] = get_next(x, 1);
    }

    REP (t, 2) {
	VI one(1, t);
	if (count(anti.begin(), anti.end(), one)) {
	    dp[t] = INF;

	    REP (x, nodes.size()) {
		dead_edge[x][t] = true;
	    }
	}
    }

    REP (i, B.size()) {
	int g = B[i].second;

	VI &to = table[g-2].to;

	REP (x, nodes.size()) {
	    int cur = x;
	    bool dead = false;
	    REP (j, to.size()) {
		if (dead_edge[cur][to[j]]) dead = true;
		cur = nxt[cur][to[j]];
		if (nodes[cur].sum) dead = true;
	    }

	    if (dead) dead_edge[x][g] = true;
	    nxt[x][g] = cur;
	}

	if (dead_edge[0][g]) {
	    dp[g] = INF;
	}
    }
}

}; // SUBTASK2;

namespace SUBTASK5 {

__int128 cost[55][111][55];
__int128 buf[55][55];
int update_table[111];

void solve() {
    build(anti.begin(), anti.end());
    memset(cost, 0x3f, sizeof cost);

    REP (t, 2) {
	VI one(1, t);
	if (count(anti.begin(), anti.end(), one)) {
	    dp[t] = INF;
	} else {
	    REP (x, nodes.size()) {
		int y = get_next(x, t);
		if (nodes[y].sum == 0) cost[x][t][y] = 1;
	    }
	}
    }

    for (int cnt=1; ; cnt++) {
	bool update = false;

	REP (i, table.size()) {
	    int from = table[i].from;
	    VI &to = table[i].to;

	    bool need_update = false;
	    REP (j, to.size()) if (update_table[to[j]] == cnt - 1) need_update = true;
	    if (!need_update) continue;

	    REP (x, nodes.size()) {
		memset(buf, 0x3f, sizeof buf);
		buf[0][x] = 0;

		REP (j, to.size()) REP (y, nodes.size()) if (buf[j][y] < INF && nodes[y].sum == 0) {
		    REP (z, nodes.size()) {
			__int128 tmp = buf[j][y] + cost[y][to[j]][z];
			amin(buf[j+1][z], tmp);
		    }
		}

		REP (y, nodes.size()) if (cost[x][from][y] > buf[to.size()][y]) {
		    update_table[from] = cnt;
		    update = true;
		    cost[x][from][y] = buf[to.size()][y];
		}
	    }
	}

	if (!update) break;
    }

    static __int128 ans[111];
    REP (g, G) ans[g] = INF;

    for (int g=2; g<G; g++) if (dp[g] != INF) {
	REP (y, nodes.size()) amin(ans[g], cost[0][g][y]);
    }

    REP (g, G) dp[g] = ans[g];

//    vector<pair<__int128, int> > B;
//    for (int i=2; i<G; i++) if (dp[i] != INF) B.emplace_back(dp[i], i);
//    sort(B.begin(), B.end());
//
//    REP (i, B.size()) {
//	int g = B[i].second;
//
//	VI &to = table[g-2].to;
//
//	REP (x, nodes.size()) {
//	    int cur = x;
//	    bool dead = false;
//	    REP (j, to.size()) {
//		if (dead_edge[cur][to[j]]) dead = true;
//		cur = nxt[cur][to[j]];
//		if (nodes[cur].sum) dead = true;
//	    }
//
//	    if (dead) dead_edge[x][g] = true;
//	    nxt[x][g] = cur;
//	}
//
//	if (dead_edge[0][g]) {
//	    dp[g] = INF;
//	}
//    }
}

}; // SUBTASK2;

void MAIN() {
    scanf("%d%d%d", &G, &N, &M);
    table.reserve(N);

    REP (i, N) {
	int a, len;
	scanf("%d%d", &a, &len);
	table.emplace_back();
	table.back().from = a;
	table.back().to.reserve(len);

	REP (j, len) {
	    int x;
	    scanf("%d", &x);
	    table.back().to.push_back(x);
	}
    }

    sort(table.begin(), table.end());

    anti.reserve(M);
    REP (i, M) {
	int len;
	scanf("%d", &len);
	anti.emplace_back();
	anti.back().reserve(len);
	REP (j, len) {
	    int x;
	    scanf("%d", &x);
	    anti.back().push_back(x);
	}
    }

    SUBTASK1::solve();
    //if (N == G-2) SUBTASK2::solve();
    SUBTASK5::solve();

    for (int i=2; i<G; i++) {
	if (dp[i] == INF) puts("YES");
	else printf("NO %llu\n", (unsigned long long)dp[i]);
    }
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}

#include <bits/stdc++.h>
#define all(x) x.begin(), x.end()
#define x first
#define y second
using namespace std;
using ull = unsigned long long;

const int N   = 104;
const int S   = 52;
const ull INF = -1;

template<class T>
void umin(T &a, T b) {
    a = min(a, b);
}

int tr[S][2]; // trie
int go[S][2]; // automaton
int ls[S];    // last char
int pr[S];    // parent
int pi[S];    // sufflink
bool z[S];    // terminal
int len = 0;  // last vertex

void add(vector<int> s) {
    int v = 0;
    for (int c : s) {
        if (tr[v][c] == -1) {
            tr[v][c] = ++len;
            assert(len < S);
            pr[len]  = v;
            ls[len]  = c;
        }
        v = tr[v][c];
    }
    z[v] = true;
}

void build() {
    pr[0] = -1;
    ls[0] = -1;
    queue<int> q;
    q.push(0);
    while (q.size()) {
        int v = q.front();
        q.pop();
        pi[v] = (v && pr[v]) ? go[pi[pr[v]]][ls[v]] : 0;
        for (int c = 0; c < 2; ++c) {
            if (tr[v][c] != -1) {
                go[v][c] = tr[v][c];
                q.push(tr[v][c]);
            } else {
                go[v][c] = v ? go[pi[v]][c]: 0;
            }
        }
    }
    for (int i = 0; i <= len; ++i) {
        if (z[i] |= z[pi[i]]) {
            go[i][0] = i;
            go[i][1] = i;
        }
    }
}

int g;
int n;
int m;
int a[N], k[N], b[N][N];

ull dp[N][S][S]; // gen, from, to
vector<pair<int, ull>> small[N][S];
ull tp[S][S];

bool relax(int row) {
    bool f = false;
    for (int i = 0; i < g; ++i) {
        for (int s = 0; s <= len; ++s) {
            small[i][s].clear();
            for (int t = 0; t <= len; ++t) {
                if (dp[i][s][t] < INF) {
                    small[i][s].emplace_back(t, dp[i][s][t]);
                }
            }
        }
    }
    for (int st = 0; st <= len; ++st) {
        fill_n(tp[0], S * S, INF);
        tp[0][st] = 0;
        for (int ind = 0; ind < k[row]; ++ind) {
            int h = b[row][ind];
            for (int i = 0; i <= len; ++i) {
                if (tp[ind][i] >= INF) {
                    continue;
                }
                for (auto e : small[h][i]) {
                    umin(tp[ind + 1][e.x], tp[ind][i] + e.y);
                }
            }
        }
        for (int fn = 0; fn <= len; ++fn) {
            if (dp[a[row]][st][fn] > tp[k[row]][fn]) {
                dp[a[row]][st][fn] = tp[k[row]][fn];
                f = true;
            }
        }
    }
    return f;
}

signed main() {
#ifdef LC
    assert(freopen("input.txt", "r", stdin));
#endif // LC
    ios::sync_with_stdio(0);
    cin.tie(0);

    fill_n(tr[0], 2 * S, -1);
    fill_n(go[0], 2 * S, -1);
    fill_n(dp[0][0], N * S * S, INF);
    cin >> g >> n >> m;
    for (int i = 0; i < n; ++i) {
        cin >> a[i] >> k[i];
        for (int j = 0; j < k[i]; ++j) {
            cin >> b[i][j];
        }
    }
    for (int i = 0; i < m; ++i) {
        int l;
        cin >> l;
        vector<int> c(l);
        for (int &e : c) {
            cin >> e;
        }
        add(c);
    }
    build();
    for (int i = 0; i <= len; ++i) {
        cerr << i << " " << pi[i] << "\t";
        for (int h = 0; h < 2; ++h) {
            cerr << go[i][h] << " ";
            dp[h][i][go[i][h]] = 1;
        }
        cerr << endl;
    }
    for (int it = 0, run = true; it < g - 2 && run; ++it) {
        run = false;
        for (int i = 0; i < n; ++i) {
            run |= relax(i);
        }
    }
    for (int i = 2; i < g; ++i) {
        ull ans = INF;
        for (int j = 0; j <= len; ++j) {
            //cerr << j << " " << z[j] << "\t" << dp[i][0][j] << endl;
            if (!z[j]) {
                umin(ans, dp[i][0][j]);
            }
        }
        if (ans < INF) {
            cout << "NO " << ans << "\n";
        } else {
            cout << "YES\n";
        }
    }
    return 0;
}

#include <bits/stdc++.h>

#define fi first
#define se second

const int N = 150;

using namespace std;

#define ull __int128
int G;
int g, n, m;
int t[N][2];
int link[N], par[N], parc[N];
int dead[N];
ull d[N][N][N];
ull f[N], nf[N];
ull inf = 1;
ull A[N];
vector < vector < int > > v[N];

int go(int v, int c);
int get_link(int v)
{
        if(link[v] == -1){
                if(v == 0 || par[v] == 0) link[v] = 0;
                else link[v] = go(get_link(par[v]), parc[v]);
        }
        return link[v];
}

int go(int v, int c)
{
        if(t[v][c] == -1){
                t[v][c] = (v == 0 ? 0 : go(get_link(v), c));
        }
        return t[v][c];
}

void upd(ull &x, ull y)
{
        x = min(x, y);
}

void print(ull x) {
    if (x < 0) {
        putchar('-');
        x = -x;
    }
    if (x > 9) print(x / 10);
    putchar(x % 10 + '0');
}

int main()
{
        ios_base::sync_with_stdio(0);

        //freopen("input.txt", "r", stdin);
        //freopen("output.txt", "w", stdout);

        //cout << inf << endl;
        for(int i = 0; i < 120; i++) inf += inf;
        for(int i = 0; i < N; i++){
                for(int j = 0; j < N; j++){
                        for(int h = 0; h < N; h++){
                                d[i][j][h] = inf;
                        }
                }
                t[i][0] = t[i][1] = link[i] = -1;
        }

        cin >> g >> n >> m;
        //if(n != g - 2) return 0;
        for(int i = 1; i <= n; i++){
                int x, k;
                cin >> x >> k;
                v[x].push_back(vector < int > (k));
                for(int j = 0; j < k; j++){
                        cin >> v[x].back()[j];
                }
        }
        for(int i = 1; i <= m; i++){
                int k;
                cin >> k;
                int cur = 0;
                for(int j = 0; j < k; j++){
                        int x;
                        cin >> x;
                        if(t[cur][x] == -1){
                                t[cur][x] = ++G;
                                par[G] = cur;
                                parc[G] = x;
                        }
                        cur = t[cur][x];
                }
                dead[cur] = true;
        }

        G += 1;

        for(int i = 0; i < G; i++){
            for(int j = 0; j < 2; j++){
                if(t[i][j] != -1){
                    dead[t[i][j]] |= dead[i];
                }
            }
        }

        for(int i = 0; i < G; i++){
                go(i, 0);
                go(i, 1);
        }

        for(int i = 0; i < G; i++){
                for(int j = i; j > 0; j = get_link(j)){
                        dead[i] |= dead[j];
                }
        }

        for(int i = 0; i < G; i++){
                if(dead[i]) continue;
                if(!dead[t[i][0]]) d[0][i][t[i][0]] = 1;
                if(!dead[t[i][1]]) d[1][i][t[i][1]] = 1;
        }
        A[0] = A[1] = 1;
        for(int i = 2; i < g; i++) A[i] = inf;

        while(true){
                bool done = true;
                for(int i = 2; i < g; i++){
                        for(int j = 0; j < G; j++){
                                if(dead[j]) continue;
                                for(auto &P: v[i]){
                                        for(int h = 0; h < G; h++){
                                                f[h] = inf;
                                        }
                                        f[j] = 0;
                                        for(int x: P){
                                                for(int h = 0; h < G; h++){
                                                        nf[h] = inf;
                                                }
                                                for(int h = 0; h < G; h++) if(f[h] != inf){
                                                        if(dead[h]) continue;
                                                        for(int k = 0; k < G; k++){
                                                                if(dead[k]) continue;
                                                                upd(nf[k], f[h] + d[x][h][k]);
                                                        }
                                                }
                                                for(int h = 0; h < G; h++){
                                                        f[h] = nf[h];
                                                }
                                        }
                                        for(int h = 0; h < G; h++){
                                                if(f[h] < d[i][j][h]){
                                                        d[i][j][h] = f[h];
                                                        done = false;
                                                }
                                        }
                                }
                        }
                        /*
                        if(A[i] == inf){
                                A[i] = 0;
                                for(auto &P: v[i]){
                                        for(int x: P){
                                                A[i] += A[x];
                                                if(A[x] == inf) break;
                                        }
                                }
                                A[i] = min(A[i], inf);
                        }
                        */
                }
                if(done) break;
        }
        ull shit = 1;
        for(int i = 0; i < 63; i++) shit += shit;
        for(int i = 2; i < g; i++){
                ull res = inf;
                for(int j = 0; j < G; j++){
                        if(dead[j]) continue;
                        res = min(res, d[i][0][j]);
                }
                if(res >= shit) printf("YES\n");
                else{
                    printf("NO ");
                    print(res);
                    printf("\n");
                }
        }
}

/*
    This code has been written by MinakoKojima, feel free to ask me question. Blog: http://www.shuizilong.com/house
    Template Date: 2015.10.12
    Note: ...
*/

#pragma comment(linker, "/STACK:36777216")
//#pragma GCC optimize ("O2")
#define LOCAL
//#include <bits/stdc++.h>
#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <climits>
#include <cassert>
#include <complex>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>

//#include <tr1/unordered_set>
//#include <tr1/unordered_map>
//#include <array>

using namespace std;

#define REP(i, n) for (int i=0;i<n;++i)
#define FOR(i, a, b) for (int i=a;i<b;++i)
#define DWN(i, b, a) for (int i=b-1;i>=a;--i)
#define REP_1(i, n) for (int i=1;i<=n;++i)
#define FOR_1(i, a, b) for (int i=a;i<=b;++i)
#define DWN_1(i, b, a) for (int i=b;i>=a;--i)
#define REP_C(i, n) for (int n____=n,i=0;i<n____;++i)
#define FOR_C(i, a, b) for (int b____=b,i=a;i<b____;++i)
#define DWN_C(i, b, a) for (int a____=a,i=b-1;i>=a____;--i)
#define REP_N(i, n) for (i=0;i<n;++i)
#define FOR_N(i, a, b) for (i=a;i<b;++i)
#define DWN_N(i, b, a) for (i=b-1;i>=a;--i)
#define REP_1_C(i, n) for (int n____=n,i=1;i<=n____;++i)
#define FOR_1_C(i, a, b) for (int b____=b,i=a;i<=b____;++i)
#define DWN_1_C(i, b, a) for (int a____=a,i=b;i>=a____;--i)
#define REP_1_N(i, n) for (i=1;i<=n;++i)
#define FOR_1_N(i, a, b) for (i=a;i<=b;++i)
#define DWN_1_N(i, b, a) for (i=b;i>=a;--i)
#define REP_C_N(i, n) for (int n____=(i=0,n);i<n____;++i)
#define FOR_C_N(i, a, b) for (int b____=(i=0,b);i<b____;++i)
#define DWN_C_N(i, b, a) for (int a____=(i=b-1,a);i>=a____;--i)
#define REP_1_C_N(i, n) for (int n____=(i=1,n);i<=n____;++i)
#define FOR_1_C_N(i, a, b) for (int b____=(i=a,b);i<=b____;++i)
#define DWN_1_C_N(i, b, a) for (int a____=(i=b,a);i>=a____;--i)

#define ECH(it, A) for (__typeof((A).begin()) it=(A).begin(); it != (A).end(); ++it)
#define rECH(it, A) for (__typeof((A).rbegin()) it=(A).rbegin(); it != (A).rend(); ++it)
#define REP_S(i, str) for (char*i=str;*i;++i)
#define REP_L(i, hd, suc) for (int i=hd;i;i=suc[i])
#define REP_G(i, u) REP_L(i,hd[u],suc)
#define REP_SS(x, s) for (int x=s;x;x=(x-1)&s)
#define DO(n) for ( int ____n = n; ____n-->0; )
#define REP_2(i, j, n, m) REP(i, n) REP(j, m)
#define REP_2_1(i, j, n, m) REP_1(i, n) REP_1(j, m)
#define REP_3(i, j, k, n, m, l) REP(i, n) REP(j, m) REP(k, l)
#define REP_3_1(i, j, k, n, m, l) REP_1(i, n) REP_1(j, m) REP_1(k, l)
#define REP_4(i, j, k, ii, n, m, l, nn) REP(i, n) REP(j, m) REP(k, l) REP(ii, nn)
#define REP_4_1(i, j, k, ii, n, m, l, nn) REP_1(i, n) REP_1(j, m) REP_1(k, l) REP_1(ii, nn)

#define ALL(A) A.begin(), A.end()
#define LLA(A) A.rbegin(), A.rend()
#define CPY(A, B) memcpy(A, B, sizeof(A))
#define INS(A, P, B) A.insert(A.begin() + P, B)
#define ERS(A, P) A.erase(A.begin() + P)
#define LBD(A, x) (lower_bound(ALL(A), x) - A.begin())
#define UBD(A, x) (upper_bound(ALL(A), x) - A.begin())
#define CTN(T, x) (T.find(x) != T.end())
#define SZ(A) int((A).size())
#define PB push_back
#define MP(A, B) make_pair(A, B)
#define PTT pair<T, T>
#define Ts *this
#define rTs return Ts
#define fi first
#define se second
#define re real()
#define im imag()

#define Rush for(int ____T=RD(); ____T--;)
#define Display(A, n, m) {                      \
  REP(i, n){		                            \
        REP(j, m-1) cout << A[i][j] << " ";     \
        cout << A[i][m-1] << endl;		        \
	}						                    \
}
#define Display_1(A, n, m) {                    \
	REP_1(i, n){		                        \
        REP_1(j, m-1) cout << A[i][j] << " ";   \
        cout << A[i][m] << endl;		        \
	}						                    \
}

typedef long long LL;
//typedef long double DB;
typedef double DB;
typedef unsigned uint;
typedef unsigned long long uLL;

typedef vector<int> VI;
typedef vector<char> VC;
typedef vector<string> VS;
typedef vector<LL> VL;
typedef vector<DB> VF;
typedef set<int> SI;
typedef set<string> SS;
typedef map<int, int> MII;
typedef map<string, int> MSI;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef vector<PII> VII;
typedef vector<VI> VVI;
typedef vector<VII> VVII;

template<class T> inline T& RD(T &);
template<class T> inline void OT(const T &);
//inline int RD(){int x; return RD(x);}
inline LL RD(){LL x; return RD(x);}
inline DB& RF(DB &);
inline DB RF(){DB x; return RF(x);}
inline char* RS(char *s);
inline char& RC(char &c);
inline char RC();
inline char& RC(char &c){scanf(" %c", &c); return c;}
inline char RC(){char c; return RC(c);}
//inline char& RC(char &c){c = getchar(); return c;}
//inline char RC(){return getchar();}

template<class T> inline T& RDD(T &);
inline LL RDD(){LL x; return RDD(x);}

template<class T0, class T1> inline T0& RD(T0 &x0, T1 &x1){RD(x0), RD(x1); return x0;}
template<class T0, class T1, class T2> inline T0& RD(T0 &x0, T1 &x1, T2 &x2){RD(x0), RD(x1), RD(x2); return x0;}
template<class T0, class T1, class T2, class T3> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3){RD(x0), RD(x1), RD(x2), RD(x3); return x0;}
template<class T0, class T1, class T2, class T3, class T4> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5); return x0;}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline T0& RD(T0 &x0, T1 &x1, T2 &x2, T3 &x3, T4 &x4, T5 &x5, T6 &x6){RD(x0), RD(x1), RD(x2), RD(x3), RD(x4), RD(x5), RD(x6); return x0;}
template<class T0, class T1> inline void OT(const T0 &x0, const T1 &x1){OT(x0), OT(x1);}
template<class T0, class T1, class T2> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2){OT(x0), OT(x1), OT(x2);}
template<class T0, class T1, class T2, class T3> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3){OT(x0), OT(x1), OT(x2), OT(x3);}
template<class T0, class T1, class T2, class T3, class T4> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void OT(const T0 &x0, const T1 &x1, const T2 &x2, const T3 &x3, const T4 &x4, const T5 &x5, const T6 &x6){OT(x0), OT(x1), OT(x2), OT(x3), OT(x4), OT(x5), OT(x6);}
inline char& RC(char &a, char &b){RC(a), RC(b); return a;}
inline char& RC(char &a, char &b, char &c){RC(a), RC(b), RC(c); return a;}
inline char& RC(char &a, char &b, char &c, char &d){RC(a), RC(b), RC(c), RC(d); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e){RC(a), RC(b), RC(c), RC(d), RC(e); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f); return a;}
inline char& RC(char &a, char &b, char &c, char &d, char &e, char &f, char &g){RC(a), RC(b), RC(c), RC(d), RC(e), RC(f), RC(g); return a;}
inline DB& RF(DB &a, DB &b){RF(a), RF(b); return a;}
inline DB& RF(DB &a, DB &b, DB &c){RF(a), RF(b), RF(c); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d){RF(a), RF(b), RF(c), RF(d); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e){RF(a), RF(b), RF(c), RF(d), RF(e); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f); return a;}
inline DB& RF(DB &a, DB &b, DB &c, DB &d, DB &e, DB &f, DB &g){RF(a), RF(b), RF(c), RF(d), RF(e), RF(f), RF(g); return a;}
inline void RS(char *s1, char *s2){RS(s1), RS(s2);}
inline void RS(char *s1, char *s2, char *s3){RS(s1), RS(s2), RS(s3);}
template<class T0,class T1>inline T0& RDD(T0&a, T1&b){RDD(a),RDD(b); return a;}
template<class T0,class T1,class T2>inline T1& RDD(T0&a, T1&b, T2&c){RDD(a),RDD(b),RDD(c); return a;}

template<class T> inline void RST(T &A){memset(A, 0, sizeof(A));}
template<class T> inline void FLC(T &A, int x){memset(A, x, sizeof(A));}
template<class T> inline void CLR(T &A){A.clear();}

template<class T0, class T1> inline void RST(T0 &A0, T1 &A1){RST(A0), RST(A1);}
template<class T0, class T1, class T2> inline void RST(T0 &A0, T1 &A1, T2 &A2){RST(A0), RST(A1), RST(A2);}
template<class T0, class T1, class T2, class T3> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3){RST(A0), RST(A1), RST(A2), RST(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void RST(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){RST(A0), RST(A1), RST(A2), RST(A3), RST(A4), RST(A5), RST(A6);}
template<class T0, class T1> inline void FLC(T0 &A0, T1 &A1, int x){FLC(A0, x), FLC(A1, x);}
template<class T0, class T1, class T2> inline void FLC(T0 &A0, T1 &A1, T2 &A2, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x);}
template<class T0, class T1, class T2, class T3> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x);}
template<class T0, class T1, class T2, class T3, class T4> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void FLC(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6, int x){FLC(A0, x), FLC(A1, x), FLC(A2, x), FLC(A3, x), FLC(A4, x), FLC(A5, x), FLC(A6, x);}
template<class T> inline void CLR(priority_queue<T> &Q){while (!Q.empty()) Q.pop();}
template<class T> inline void CLR(stack<T> &S){while (!S.empty()) S.pop();}
template<class T> inline void CLR(queue<T> &Q){while (!Q.empty()) Q.pop();}

template<class T0, class T1> inline void CLR(T0 &A0, T1 &A1){CLR(A0), CLR(A1);}
template<class T0, class T1, class T2> inline void CLR(T0 &A0, T1 &A1, T2 &A2){CLR(A0), CLR(A1), CLR(A2);}
template<class T0, class T1, class T2, class T3> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3){CLR(A0), CLR(A1), CLR(A2), CLR(A3);}
template<class T0, class T1, class T2, class T3, class T4> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4);}
template<class T0, class T1, class T2, class T3, class T4, class T5> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5);}
template<class T0, class T1, class T2, class T3, class T4, class T5, class T6> inline void CLR(T0 &A0, T1 &A1, T2 &A2, T3 &A3, T4 &A4, T5 &A5, T6 &A6){CLR(A0), CLR(A1), CLR(A2), CLR(A3), CLR(A4), CLR(A5), CLR(A6);}
template<class T> inline void CLR(T &A, int n){REP(i, n) CLR(A[i]);}

template<class T> inline bool EPT(T &a){return a.empty();}
template<class T> inline T& SRT(T &A){sort(ALL(A)); return A;}
template<class T, class C> inline T& SRT(T &A, C cmp){sort(ALL(A), cmp); return A;}
template<class T> inline T& RVS(T &A){reverse(ALL(A)); return A;}
template<class T> inline T& UNQQ(T &A){A.resize(unique(ALL(A))-A.begin());return A;}
template<class T> inline T& UNQ(T &A){SRT(A);return UNQQ(A);}
template<class T, class C> inline T& UNQ(T &A, C cmp){SRT(A, cmp);return UNQQ(A);}

//}

/** Constant List .. **/ //{

const int MOD = int(1e9) + 7;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f3f3f3f3f3f3fLL;
const DB EPS = 1e-9;
const DB OO = 1e20;
const DB PI = acos(-1.0); //M_PI;

const int dx[] = {-1, 1, 0, 0};
const int dy[] = {0, 0, 1, -1};

//}

/** Add On .. **/ //{
// <<= '0. Nichi Joo ., //{

template<class T> inline bool checkMin(T &a,const T b){return b < a ? a = b, 1 : 0;}
template<class T> inline bool checkMax(T &a,const T b){return a < b ? a = b, 1 : 0;}
template <class T, class C> inline bool checkUpd(T& a, const T b, C c){return c(b,a) ? a = b, 1 : 0;}
template<class T> inline T min(T a, T b, T c){return min(min(a, b), c);}
template<class T> inline T max(T a, T b, T c){return max(max(a, b), c);}
template<class T> inline T min(T a, T b, T c, T d){return min(min(a, b), min(c, d));}
template<class T> inline T max(T a, T b, T c, T d){return max(max(a, b), max(c, d));}
template<class T> inline T min(T a, T b, T c, T d, T e){return min(min(min(a,b),min(c,d)),e);}
template<class T> inline T max(T a, T b, T c, T d, T e){return max(max(max(a,b),max(c,d)),e);}
template<class T> inline T sqr(T a){return a*a;}
template<class T> inline T cub(T a){return a*a*a;}
template<class T> inline T ceil(T x, T y){return (x - 1) / y + 1;}
template<class T> T abs(T x){return x>0?x:-x;}
inline int sgn(DB x){return x < -EPS ? -1 : x > EPS;}
inline int sgn(DB x, DB y){return sgn(x - y);}

inline DB cos(DB a, DB b, DB c){return (sqr(a)+sqr(b)-sqr(c))/(2*a*b);}
inline DB cot(DB x){return 1./tan(x);};
inline DB sec(DB x){return 1./cos(x);};
inline DB csc(DB x){return 1./sin(x);};

//}
// <<= '1. Bitwise Operation ., //{
namespace BO{

inline bool _1(int x, int i){return bool(x&1<<i);}
inline bool _1(LL x, int i){return bool(x&1LL<<i);}
inline LL _1(int i){return 1LL<<i;}
inline LL _U(int i){return _1(i) - 1;};

inline int reverse_bits(int x){
    x = ((x >> 1) & 0x55555555) | ((x << 1) & 0xaaaaaaaa);
    x = ((x >> 2) & 0x33333333) | ((x << 2) & 0xcccccccc);
    x = ((x >> 4) & 0x0f0f0f0f) | ((x << 4) & 0xf0f0f0f0);
    x = ((x >> 8) & 0x00ff00ff) | ((x << 8) & 0xff00ff00);
    x = ((x >>16) & 0x0000ffff) | ((x <<16) & 0xffff0000);
    return x;
}

inline LL reverse_bits(LL x){
    x = ((x >> 1) & 0x5555555555555555LL) | ((x << 1) & 0xaaaaaaaaaaaaaaaaLL);
    x = ((x >> 2) & 0x3333333333333333LL) | ((x << 2) & 0xccccccccccccccccLL);
    x = ((x >> 4) & 0x0f0f0f0f0f0f0f0fLL) | ((x << 4) & 0xf0f0f0f0f0f0f0f0LL);
    x = ((x >> 8) & 0x00ff00ff00ff00ffLL) | ((x << 8) & 0xff00ff00ff00ff00LL);
    x = ((x >>16) & 0x0000ffff0000ffffLL) | ((x <<16) & 0xffff0000ffff0000LL);
    x = ((x >>32) & 0x00000000ffffffffLL) | ((x <<32) & 0xffffffff00000000LL);
    return x;
}

template<class T> inline bool odd(T x){return x&1;}
template<class T> inline bool even(T x){return !odd(x);}
template<class T> inline T low_bit(T x) {return x & -x;}
template<class T> inline T high_bit(T x) {T p = low_bit(x);while (p != x) x -= p, p = low_bit(x);return p;}
template<class T> inline T cover_bit(T x){T p = 1; while (p < x) p <<= 1;return p;}
template<class T> inline int cover_idx(T x){int p = 0; while (_1(p) < x ) ++p; return p;}

inline int clz(int x){return __builtin_clz(x);}
inline int clz(LL x){return __builtin_clzll(x);}
inline int ctz(int x){return __builtin_ctz(x);}
inline int ctz(LL x){return __builtin_ctzll(x);}
inline int lg2(int x){return !x ? -1 : 31 - clz(x);}
inline int lg2(LL x){return !x ? -1 : 63 - clz(x);}
inline int low_idx(int x){return !x ? -1 : ctz(x);}
inline int low_idx(LL x){return !x ? -1 : ctz(x);}
inline int high_idx(int x){return lg2(x);}
inline int high_idx(LL x){return lg2(x);}
inline int parity(int x){return __builtin_parity(x);}
inline int parity(LL x){return __builtin_parityll(x);}
inline int count_bits(int x){return __builtin_popcount(x);}
inline int count_bits(LL x){return __builtin_popcountll(x);}

} using namespace BO;//}

// <<= '2. Number Theory .,//{
namespace NT{
#define gcd __gcd
inline LL lcm(LL a, LL b){return a*b/gcd(a,b);}

inline void INC(int &a, int b){a += b; if (a >= MOD) a -= MOD;}
inline int sum(int a, int b){a += b; if (a >= MOD) a -= MOD; return a;}

/* ģ�������պó� int ʱ��
inline int sum(uint a, int b){a += b; a %= MOD;if (a < 0) a += MOD; return a;}
inline void INC(int &a, int b){a = sum(a, b);}
*/

inline void DEC(int &a, int b){a -= b; if (a < 0) a += MOD;}
inline int dff(int a, int b){a -= b; if (a < 0) a  += MOD; return a;}
inline void MUL(int &a, int b){a = (LL)a * b % MOD;}
//inline int pdt(int a, int b){return (LL)a * b % MOD;}
inline int pdt(int x,int y) {
    int ret; __asm__ __volatile__ ("\tmull %%ebx\n\tdivl %%ecx\n":"=d"(ret):"a"(x),"b"(y),"c"(MOD));
    return ret;
}

inline int gcd(int m, int n, int &x, int &y){

    x = 1, y = 0; int xx = 0, yy = 1, q;

    while (1){
        q = m / n, m %= n;
        if (!m){x = xx, y = yy; return n;}
        DEC(x, pdt(q, xx)), DEC(y, pdt(q, yy));
        q = n / m, n %= m;
        if (!n) return m;
        DEC(xx, pdt(q, x)), DEC(yy, pdt(q, y));
    }
}

inline int sum(int a, int b, int c){return sum(a, sum(b, c));}
inline int sum(int a, int b, int c, int d){return sum(sum(a, b), sum(c, d));}
inline int pdt(int a, int b, int c){return pdt(a, pdt(b, c));}
inline int pdt(int a, int b, int c, int d){return pdt(pdt(a, b), pdt(c, d));}

inline int pow(int a, LL b){
    int c(1); while (b){
        if (b&1) MUL(c, a);
        MUL(a, a), b >>= 1;
    }
    return c;
}

template<class T> inline T pow(T a, LL b){
    T c(1); while (b){
        if (b&1) c *= a;
        a *= a, b >>= 1;
    }
    return c;
}

template<class T> inline T pow(T a, int b){
    return pow(a, (LL)b);
}

inline int _I(int b){
    int a = MOD, x1 = 0, x2 = 1, q; while (1){
        q = a / b, a %= b;
        if (!a) return x2;
        DEC(x1, pdt(q, x2));

        q = b / a, b %= a;
        if (!b) return x1;
        DEC(x2, pdt(q, x1));
    }
}

inline void DIV(int &a, int b){MUL(a, _I(b));}
inline int qtt(int a, int b){return pdt(a, _I(b));}

struct Int{
    int val;

    operator int() const{return val;}

    Int(int _val = 0):val(_val){
        val %= MOD; if (val < 0) val += MOD;
    }
    Int(LL _val):val(_val){
        _val %= MOD; if (_val < 0) _val += MOD;
        val = _val;
    }

    Int& operator +=(const int& rhs){INC(val, rhs);rTs;}
    Int operator +(const int& rhs) const{return sum(val, rhs);}
    Int& operator -=(const int& rhs){DEC(val, rhs);rTs;}
    Int operator -(const int& rhs) const{return dff(val, rhs);}
    Int& operator *=(const int& rhs){MUL(val, rhs);rTs;}
    Int operator *(const int& rhs) const{return pdt(val, rhs);}
    Int& operator /=(const int& rhs){DIV(val, rhs);rTs;}
    Int operator /(const int& rhs) const{return qtt(val, rhs);}
    Int operator-()const{return MOD-*this;}
};

} using namespace NT;//}

//}

/** I/O Accelerator Interface .. **/ //{
#define g (c=getchar())
#define d isdigit(g)
#define p x=x*10+c-'0'
#define n x=x*10+'0'-c
#define pp l/=10,p
#define nn l/=10,n
template<class T> inline T& RD(T &x){
    char c;while(!d);x=c-'0';while(d)p;
    return x;
}
template<class T> inline T& RDD(T &x){
    char c;while(g,c!='-'&&!isdigit(c));
    if (c=='-'){x='0'-g;while(d)n;}
    else{x=c-'0';while(d)p;}
    return x;
}
inline DB& RF(DB &x){
    //scanf("%lf", &x);
    char c;while(g,c!='-'&&c!='.'&&!isdigit(c));
    if(c=='-')if(g=='.'){x=0;DB l=1;while(d)nn;x*=l;}
        else{x='0'-c;while(d)n;if(c=='.'){DB l=1;while(d)nn;x*=l;}}
    else if(c=='.'){x=0;DB l=1;while(d)pp;x*=l;}
        else{x=c-'0';while(d)p;if(c=='.'){DB l=1;while(d)pp;x*=l;}}
    return x;
}
#undef nn
#undef pp
#undef n
#undef p
#undef d
#undef g
inline char* RS(char *s){
    //gets(s);
    scanf("%s", s);
    return s;
}

LL last_ans; int Case; template<class T> inline void OT(const T &x){
    //printf("Case #%d: ", ++Case);
    //printf("%lld\n", x);
    //printf("%I64d\n", x);
    //printf("%.9f\n", x);
    //printf("%d\n", x);
    cout << x << endl;
    //last_ans = x;
}

//}/* .................................................................................................................................. */

const int N = int(1e2) + 9;
VI E[N], adj[N]; int from[N];
int g, n, m;

namespace ACM{
    const int Z = 2;
    int ch[N][Z], fa[N], Q[N], cz, op, tt; bool gg[N];
    char str[N];

    int new_node(){
        RST(ch[tt]), fa[tt] = gg[tt] = 0;
        return tt++;
    }

#define v ch[u][c]
#define f ch[fa[u]][c]

    void Build(){
        cz = op = 0; int u = 0; REP(c, Z) if (v) Q[op++] = v;
        while (cz < op){
            u = Q[cz++]; REP(c, Z){
                if (v) fa[Q[op++] = v] = f, gg[v] |= gg[f];
                else v = f;
            }
        }
    }

    void Insert(){
        VI s; Rush s.PB(RD());
        int u = 0; REP(i, SZ(s)) {
            int c = s[i]; if (gg[v]) return;
            if (!v) v = new_node();
            u = v;
        }
        gg[u] = 1;
    }

    void Init(){

        RD(g,m,n); REP(i, m) {
            RD(from[i]); Rush E[i].PB(RD());
            for (auto t: E[i]) adj[t].PB(i);
        }

        tt = 0, new_node();
        DO(n) Insert(); Build();
    }

    LL dp[N][N][N];
    LL d[2][N][N];

    void Run(){

        n = tt; FLC(dp, 0x3f); REP(c, 2) REP(u, n) if (!gg[u] && !gg[v]) dp[c][u][v] = 1;

#undef f
#undef v

        // Bellman-Ford
        /*
        while (1) {
            bool ok = 0;
            REP(ei, m) {
                int u = from[ei];
                int p = 0, q = 1; FLC(d[p], 0x3f);
                REP(i, n) d[p][i][i] = 0;

                for (auto v: E[ei]) {
                    swap(p, q); FLC(d[p], 0x3f);
                    REP(i, n) REP(j, n) REP(k, n) checkMin(d[p][i][j], d[q][i][k] + dp[v][k][j]);
                }

                REP(i, n) REP(j, n) if (checkMin(dp[u][i][j], d[p][i][j])) ok = true;
            }
            if (!ok) break;
        }
        */

        // SPFA

#define inQ gg
        RST(inQ); cz = 0, op = 2; REP(i, 2) inQ[Q[i] = i] = 1;
        clock_t time_stamp = clock();
        float time_limit = 0.70 * CLOCKS_PER_SEC;

        while (cz != op) {
            if (clock() - time_stamp > time_limit) break;
            int t = Q[cz]; inQ[t] = 0;
            ++cz; if (cz == g) cz = 0;

            for (auto ei: adj[t]) {
                if (clock() - time_stamp > time_limit) break;
                int u = from[ei];
                int p = 0, q = 1; FLC(d[p], 0x3f);
                REP(i, n) d[p][i][i] = 0;

                for (auto v: E[ei]) {
                    if (clock() - time_stamp > time_limit) break;
                    swap(p, q); FLC(d[p], 0x3f);
                    REP(i, n) {
                        if (clock() - time_stamp > time_limit) break;
                        REP(j, n) REP(k, n) checkMin(d[p][i][j], d[q][i][k] + dp[v][k][j]);
                    }
                }
                if (clock() - time_stamp > time_limit) break;
                REP(i, n) REP(j, n) if (checkMin(dp[u][i][j], d[p][i][j]) && !inQ[u]) {
                    inQ[u] = 1; Q[op++] = u;
                    if (op == g) op = 0;
                }
            }
        }

        // Dijkstra
        // priority_queue<std::tuple<LL, int, int, int>, vector<tuple<LL, int, int, int>>, greater<>> Q;

        FOR(i, 2, g) {
            LL z = INFF;
            REP(u, n) checkMin(z, dp[i][0][u]);
            if (z == INFF) puts("YES");
            else printf("NO %lld\n", z);
        }
    }
} using namespace ACM;

int main(){

#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    //freopen("out.txt", "w", stdout);
#endif

    Init();
    Run();
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void ckmn(ll&x,ll y){x=min(x,y);}
const int A=55;
const ll inf=4e18;
int go[A][2],link[A],leaf[A],root,tsz;
void Add(int&c,int s[],int n){
	if(!c)c=++tsz;
	if(n==0){leaf[c]=1;return;}
	Add(go[c][s[0]],s+1,n-1);
}
void Build(){
	queue<int> q;
	link[root]=root;
	for(int i=0;i<2;i++){
		if(go[root][i]){
			link[go[root][i]]=root;
			q.push(go[root][i]);
		}else go[root][i]=root;
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		leaf[u]|=leaf[link[u]];
		for(int i=0;i<2;i++){
			if(go[u][i])link[go[u][i]]=go[link[u]][i],q.push(go[u][i]);
			else go[u][i]=go[link[u]][i];
		}
	}
}
const int N=105;
int b[N][N],a[N],sz[N],s[A];
ll dp[N][A][A],tmp[A],nxt[A];
bool fl1[N],fl2[N];
int main(){
	root=++tsz;
	int g,n,m;
	scanf("%i %i %i",&g,&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%i %i",&a[i],&sz[i]);
		for(int j=1;j<=sz[i];++j)scanf("%i",&b[i][j]);
	}
	for(int i=1,l;i<=m;++i){
		scanf("%i",&l);
		for(int j=0;j<l;++j)scanf("%i",&s[j]);
		Add(root,s,l);
	}
	Build();
	for(int k=0;k<g;++k)for(int i=1;i<=tsz;++i)for(int j=1;j<=tsz;++j)dp[k][i][j]=inf;
	for(int i=1;i<=tsz;++i){
		if(!leaf[go[i][0]])dp[0][i][go[i][0]]=1;
		if(!leaf[go[i][1]])dp[1][i][go[i][1]]=1;
	}
	fl1[0]=fl1[1]=1;
	while(1){
		bool ok=0;
		for(int i=0;i<g;++i)fl2[i]=0;
		for(int i=1;i<=n;++i){
			bool has=0;
			for(int j=1;j<=sz[i];++j)if(fl1[b[i][j]]&&!fl2[b[i][j]])has=1;
			if(!has)continue;
			for(int st=1;st<=tsz;++st){
				for(int j=1;j<=tsz;++j)tmp[j]=inf;
				tmp[st]=0;
				for(int j=1;j<=sz[i];++j){
					for(int k=1;k<=tsz;++k)nxt[k]=inf;
					for(int k=1;k<=tsz;++k){
						for(int ed=1;ed<=tsz;++ed){
							ckmn(nxt[ed],tmp[k]+dp[b[i][j]][k][ed]);
						}
					}
					for(int k=1;k<=tsz;++k)tmp[k]=nxt[k];
				}
				for(int j=1;j<=tsz;++j)if(dp[a[i]][st][j]>tmp[j]){
					dp[a[i]][st][j]=tmp[j];
					fl2[a[i]]=1;
					ok=1;
				}
			}
		}
		if(!ok)break;
		for(int i=0;i<g;++i)fl1[i]=fl2[i];
	}
	for(int i=2;i<g;++i){
		ll ans=inf;
		for(int ed=1;ed<=tsz;++ed)ans=min(ans,dp[i][root][ed]);
		if(ans==inf)printf("YES\n");
		else printf("NO %lld\n",ans);
	}
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void ckmn(ll&x,ll y){x=min(x,y);}
const int A=55;
const ll inf=4e18;
int go[A][2],link[A],leaf[A],root,tsz;
void Add(int&c,int s[],int n){
	if(!c)c=++tsz;
	if(n==0){leaf[c]=1;return;}
	Add(go[c][s[0]],s+1,n-1);
}
void Build(){
	queue<int> q;
	link[root]=root;
	for(int i=0;i<2;i++){
		if(go[root][i]){
			link[go[root][i]]=root;
			q.push(go[root][i]);
		}else go[root][i]=root;
	}
	while(q.size()){
		int u=q.front();
		q.pop();
		leaf[u]|=leaf[link[u]];
		for(int i=0;i<2;i++){
			if(go[u][i])link[go[u][i]]=go[link[u]][i],q.push(go[u][i]);
			else go[u][i]=go[link[u]][i];
		}
	}
}
const int N=105;
int b[N][N],a[N],sz[N],s[A];
ll dp[N][A][A],tmp[A],nxt[A];
bool fl1[N],fl2[N];
int main(){
	root=++tsz;
	int g,n,m;
	scanf("%i %i %i",&g,&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%i %i",&a[i],&sz[i]);
		for(int j=1;j<=sz[i];++j)scanf("%i",&b[i][j]);
	}
	for(int i=1,l;i<=m;++i){
		scanf("%i",&l);
		for(int j=0;j<l;++j)scanf("%i",&s[j]);
		Add(root,s,l);
	}
	Build();
	for(int k=0;k<g;++k)for(int i=1;i<=tsz;++i)for(int j=1;j<=tsz;++j)dp[k][i][j]=inf;
	for(int i=1;i<=tsz;++i){
		if(!leaf[go[i][0]])dp[0][i][go[i][0]]=1;
		if(!leaf[go[i][1]])dp[1][i][go[i][1]]=1;
	}
	fl1[0]=fl1[1]=1;
	while(1){
		bool ok=0;
		set<int> now;
		ll mn=inf;
		for(int i=0;i<g;++i)fl2[i]=0;
		for(int i=1;i<=n;++i){
			bool has=0;
			for(int j=1;j<=sz[i];++j)if(fl1[b[i][j]]&&!fl2[b[i][j]])has=1;
			if(!has)continue;
			for(int st=1;st<=tsz;++st){
				for(int j=1;j<=tsz;++j)tmp[j]=inf;
				tmp[st]=0;
				for(int j=1;j<=sz[i];++j){
					for(int k=1;k<=tsz;++k)nxt[k]=inf;
					for(int k=1;k<=tsz;++k){
						for(int ed=1;ed<=tsz;++ed){
							ckmn(nxt[ed],tmp[k]+dp[b[i][j]][k][ed]);
						}
					}
					for(int k=1;k<=tsz;++k)tmp[k]=nxt[k];
				}
				for(int j=1;j<=tsz;++j)if(dp[a[i]][st][j]>tmp[j]){
					dp[a[i]][st][j]=tmp[j];
					fl2[a[i]]=1;
					ok=1;
				}
			}
		}
		if(!ok)break;
		for(int i=0;i<g;++i)fl1[i]=fl2[i];
	}
	for(int i=2;i<g;++i){
		ll ans=inf;
		for(int ed=1;ed<=tsz;++ed)ans=min(ans,dp[i][root][ed]);
		if(ans==inf)printf("YES\n");
		else printf("NO %lld\n",ans);
	}
	return 0;
}

// hello darkness my old friend, I've come to talk with you again

#include<bits/stdc++.h>

#define F first
#define S second
#define PB push_back
#define sz(s) int((s).size())
#define bit(n,k) (((n)>>(k))&1)

using namespace std;

typedef unsigned long long ll;
typedef pair<int,int> pii;

const int maxn = 210, MAX = 55, mod = 1e9 + 7, inf = 1e9 + 10;

struct Aho{
    int nxt[MAX][2], f[MAX], C = 0;
    bool bad[MAX];
    Aho(){
	memset(nxt, 0, sizeof nxt);
	memset(f, 0, sizeof f);
	memset(bad, 0, sizeof bad);
	C = 0;
    }
    void in(){
	int k;
	cin >> k;
	int nw = 0;
	while(k--){
	    int x;
	    cin >> x;
	    if(nxt[nw][x] == 0)
		nxt[nw][x] = ++C;
	    nw = nxt[nw][x];
	}
	bad[nw] = 1;
    }
    void build(){
	queue<int> q;
	for(int i = 0; i < 2; i++)
	    if(nxt[0][i] != 0)
		q.push(nxt[0][i]);
	while(sz(q)){
	    int u = q.front();
	    q.pop();
	    bad[u]|= bad[ f[u] ];
	    for(int i = 0; i < 2; i++){
		if(nxt[u][i] == 0)
		    nxt[u][i] = nxt[ f[u] ][i];
		else
		    f[ nxt[u][i] ] = nxt[ f[u] ][i], q.push(nxt[u][i]);
	    }
	}
    }
};Aho aho;

vector<int> change[maxn], used[maxn];
int who[maxn], who2[maxn], start[maxn];

vector<int> bst1[maxn][MAX], bst2[maxn][MAX];

ll dp[maxn][MAX][MAX];
bool seen[maxn][MAX][MAX];

int main(){
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie();

    int G, N, M;
    cin >> G >> N >> M;

    int counter = G;

    for(int i = 0; i < N; i++){
	int a, k;
	cin >> a >> k;
	change[i].resize(k);
	start[i] = counter;
	for(int j = 0; j < k; j++){
	    cin >> change[i][j];
	    who[counter] = i;
	    used[ change[i][j] ].PB(counter);
	    counter++;
	}
	who2[i] = a;
    }
    for(int i = 0; i < M; i++){
	aho.in();
    }
    aho.build();

    int AH = aho.C + 1;

    priority_queue< pair<ll, pair<int, pii> >, vector< pair<ll, pair<int, pii> > >, greater< pair<ll, pair<int, pii> > > > pq;
    for(int i = 0; i < AH; i++){
	if(aho.bad[i] == 0 && aho.bad[ aho.nxt[i][0] ] == 0)
	    dp[0][i][ aho.nxt[i][0] ] = 1, pq.push({1, {0, {i, aho.nxt[i][0]} }});
	if(aho.bad[i] == 0 && aho.bad[ aho.nxt[i][1] ] == 0)
	    dp[1][i][ aho.nxt[i][1] ] = 1, pq.push({1, {1, {i, aho.nxt[i][1]} }});
    }
    auto better = [&](int a, int b, int c, ll x){
		      if(dp[a][b][c] == 0 || dp[a][b][c] > x)
			  dp[a][b][c] = x, pq.push({x, {a, {b, c}}});
		  };
    while(sz(pq)){
	int id = pq.top().S.F, l1 = pq.top().S.S.F, l2 = pq.top().S.S.S;
	pq.pop();
	if(seen[id][l1][l2])
	    continue;
	seen[id][l1][l2] = 1;

	bst1[id][l1].PB(l2);
	bst2[id][l2].PB(l1);

	if(id < G){
	    for(int ID : used[id]){
		if(ID == start[ who[ID] ]){
		    better(ID, l1, l2, dp[id][l1][l2]);
		}
		else{
		    for(int i : bst2[ID-1][l1])
			better(ID, i, l2, dp[ID-1][i][l1] + dp[id][l1][l2]);
		}
	    }
	}
	else if(id - start[ who[id] ] + 1 == sz(change[ who[id] ])){
	    better(who2[ who[id ] ], l1, l2, dp[id][l1][l2]);
	}
	else{
	    int index = id - start[ who[id] ];
	    int c = change[ who[id] ][index + 1];
	    for(int i : bst1[c][l2])
		better(id+1, l1, i, dp[id][l1][l2] + dp[c][l2][i]);
	}
    }

    for(int i = 2; i < G; i++){
	ll bst = 0;
	for(int j : bst1[i][0]){
	    if(bst == 0 || bst > dp[i][0][j])
		bst = dp[i][0][j];
	}
	if(bst == 0)
	    cout << "YES\n";
	else
	cout << "NO " << bst << "\n";
    }
    return 0;
}

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define ll long long
using namespace std;
struct AC
{
	int child[2];
	int fail;
}tree[55];
int g,n,m,now,root=1,tot=1,a[105],b[105],c[105];
bool flag[55];
int s[55],tmp[105];
ll f[205][55][55];
queue<int>q;
void ins(int len)
{
	int cur=root;
	for(int i=1;i<=len;i++)
	{
		if(!tree[cur].child[s[i]])tree[cur].child[s[i]]=++tot;
		if(flag[cur])flag[tree[cur].child[s[i]]]=1;
		cur=tree[cur].child[s[i]];
	}
	flag[cur]=1;
}
void build_AC()
{
	q.push(root);
	while(!q.empty())
	{
		int node=q.front();
		q.pop();
		if(flag[tree[node].fail])flag[node]=1;
		for(int k=0;k<2;k++)
		{
			if(!tree[node].child[k])
			{
				if(node==root)tree[node].child[k]=node;
				else tree[node].child[k]=tree[tree[node].fail].child[k];
			}
			else
			{
				if(node==root)tree[tree[node].child[k]].fail=node;
				else tree[tree[node].child[k]].fail=tree[tree[node].fail].child[k];
				q.push(tree[node].child[k]);
			}
		}
	}
}
bool merge(int x,int y,int z)
{
	bool res=0;
	for(int i=1;i<=tot;i++)
	{
		if(flag[i])continue;
		for(int j=1;j<=tot;j++)
		{
			if(flag[j]||f[x][i][j]==-1)continue;
			for(int k=1;k<=tot;k++)
			{
				if(flag[k]||f[y][j][k]==-1)continue;
				if(f[z][i][k]==-1||f[z][i][k]>f[x][i][j]+f[y][j][k])
				{
					f[z][i][k]=f[x][i][j]+f[y][j][k];
					res=1;
				}
			}
		}
	}
	return res;
}
int main()
{
	scanf("%d%d%d",&g,&n,&m);
	now=n;
	for(int i=1;i<=n;i++)
	{
		int aa,k;
		scanf("%d%d",&aa,&k);
		for(int j=1;j<=k;j++)scanf("%d",&tmp[j]);
		while(k>2)
		{
			now++;
			a[now]=now+2,b[now]=tmp[k-1],c[now]=tmp[k];
			tmp[--k]=now+2;
		}
		a[i]=aa,b[i]=tmp[1],c[i]=k==2?tmp[2]:200;
	}
	while(m--)
	{
		int k;
		scanf("%d",&k);
		for(int i=1;i<=k;i++)scanf("%d",&s[i]);
		ins(k);
	}
	build_AC();
	memset(f,-1,sizeof(f));
	for(int i=1;i<=tot;i++)
	{
		if(flag[i])continue;
		if(flag[tree[i].child[0]]==0)f[0][i][tree[i].child[0]]=1;
		if(flag[tree[i].child[1]]==0)f[1][i][tree[i].child[1]]=1;
	}
	for(int i=1;i<=tot;i++)
	  if(!flag[i])f[200][i][i]=0;
	bool ff=1;
	while(ff)
	{
		ff=0;
		for(int i=1;i<=now;i++)ff|=merge(b[i],c[i],a[i]);
	}
//	for(int i=0;i<g;i++)
//	{
//		printf("i=%d:\n",i);
//		for(int x=1;x<=tot;x++)
//		{
//			for(int y=1;y<=tot;y++)
//			  printf("%lld ",f[i][x][y]);
//			printf("\n");
//		}
//	}
	for(int i=2;i<g;i++)
	{
		ll ans=-1;
		for(int j=1;j<=tot;j++)
		{
			if(flag[j]||f[i][1][j]==-1)continue;
			if(ans<0)ans=f[i][1][j];
			else ans=min(ans,f[i][1][j]);
		}
		if(ans==-1)printf("YES\n");
		else printf("NO %lld\n",ans);
	}
	return 0;
}

// In the name of Allah.
// We're nothing and you're everything.
// Ya Ali!

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 1e2 + 14, maxl = 55, z = 2;
const ull inf = 1ull << 63;
int g, n, m;
int nxt[maxn][z], f[maxn], sz = 1;
bool mark[maxn];
void aho(){
    int q[maxn];
    int head = 0, tail = 0;
    for(int i = 0; i < z; i++)
        if(nxt[0][i])
            q[tail++] = nxt[0][i];
    while(head < tail){
        int v = q[head++];
        for(int i = 0; i < z; i++)
            if(nxt[v][i]){
                f[ nxt[v][i] ] = nxt[ f[v] ][i];
                q[tail++] = nxt[v][i];
            }
            else
                nxt[v][i] = nxt[ f[v] ][i];
    }
}
vector<int> dpf[maxn][maxl];
vector<vector<int> > rule[maxn];
vector<int> adj[maxn];
ull dp[maxn][maxl][maxl], tdp[maxl], nxtdp[maxl];
bool inq[maxn][maxl][maxl];
struct State{
    int i, s, e;
    bool operator < (const State &o) const{
        if(dp[i][s][e] != dp[o.i][o.s][o.e])
            return dp[i][s][e] < dp[o.i][o.s][o.e];
        if(i != o.i)
            return i < o.i;
        if(s != o.s)
            return s < o.s;
        return e < o.e;
    }
};
int main(){
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> g >> n >> m;
    for(int i = 0; i < n; i++){
        int a, k;
        cin >> a >> k;
        vector<int> tmp(k);
        for(auto &x : tmp){
            cin >> x;
            adj[x].push_back(a);
        }
        rule[a].push_back(tmp);
    }
    for(int i = 0; i < m; i++){
        int l;
        cin >> l;
        int v = 0;
        for(int i = 0; i < l; i++){
            int x;
            cin >> x;
            if(!nxt[v][x])
                nxt[v][x] = sz++;
            v = nxt[v][x];
        }
        mark[v] = true;
    }
    assert(sz < maxl);
    aho();
    for(int i = 0; i < sz; i++)
        for(int i = 0; i < sz; i++)
            mark[i] |= mark[f[i]];
    fill(dp[0][0], dp[g][0], inf);
    queue<State> s;
    for(int i = 0; i < 2; i++)
        for(int v = 0; v < sz; v++)
            if(!mark[nxt[v][i]]){
                dpf[i][v] = {nxt[v][i]};
                dp[i][v][nxt[v][i]] = 1;
                s.push({i, v, nxt[v][i]});
            }
    while(s.size()){
        auto [id, st, e] = s.front();
        inq[id][st][e] = false;
        s.pop();
        while(s.size() && s.front().i == id){
            auto [id, st, e] = s.front();
            s.pop();
            inq[id][st][e] = false;
        }
        for(auto i : adj[id])
            for(auto &vec : rule[i]){
                for(int v = 0; v < sz; v++){
                    if(mark[v])
                        continue;
                    vector<int> starts({v});
                    tdp[v] = 0;
                    for(auto &x : vec){
                        if(starts.empty())
                            break;
                        fill(nxtdp, nxtdp + sz, inf);
                        vector<int> nxts;
                        for(auto &s : starts)
                            for(auto &trans : dpf[x][s]){
                                // ull tmp;
                                // assert(!__builtin_uaddll_overflow(tdp[s], dp[x][s][trans], &tmp));
                                if(tdp[s] + dp[x][s][trans] < nxtdp[trans]){
                                    if(nxtdp[trans] == inf)
                                        nxts.push_back(trans);
                                    nxtdp[trans] = tdp[s] + dp[x][s][trans];
                                }
                            }
                        starts = nxts;
                        // sort(nxts.begin(), nxts.end());
                        // nxts.erase(unique(nxts.begin(), nxts.end()), nxts.end());
                        // assert(starts.size() == nxts.size());
                        for(auto &s : starts)
                            tdp[s] = nxtdp[s];
                    }
                    for(auto &e : starts)
                        if(tdp[e] < dp[i][v][e]){
                            if(dp[i][v][e] == inf){
                                // assert(find(dpf[i][v].begin(), dpf[i][v].end(), e) == dpf[i][v].end());
                                dpf[i][v].push_back(e);
                            }
                            dp[i][v][e] = tdp[e];
                            if(!inq[i][v][e])
                                s.push({i, v, e});
                        }
                }
            }
    }
    for(int i = 2; i < g; i++){
        ull ans = *min_element(dp[i][0], dp[i][0] + sz);
        if(ans == inf)
            cout << "YES\n";
        else
            cout << "NO " << ans << '\n';
    }
}

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for(int i = (a); i < (b); ++i)
#define rrep(i,a,b) for(int i = (b); i --> (a);)
#define all(v) (v).begin(),(v).end()
#define trav(x,v) for(auto &x : v)
#define sz(v) int(v.size())
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef unsigned long long ull;
typedef pair<int,ull> pil;
typedef vector<ull> vl;

const ull inf = 1LL<<63;

pil app(pil a, int x){
	return pil( a.first+1, (a.second<<1) ^ x );
}

pil succ(pil a){
	return pil( a.first-1, a.second & ~(1LL << (a.first-1)) );
}

pil pred(pil a){
	return pil( a.first-1, a.second >> 1 );
}

int main(){
	cin.sync_with_stdio(0);
	cin.tie(0);
	cin.exceptions(cin.failbit);

	int g, n, m;
	cin >> g >> n >> m;

	vector<vi> sing(g);
	vector<vector<pii>> lft(g), rgt(g);
	auto mk_new = [&](){
		int ans = sz(sing);
		sing.resize(ans+1);
		lft.resize(ans+1);
		rgt.resize(ans+1);
		return ans;
	};
	rep(_,0,n){
		int a, k, b, c;
		cin >> a >> k;
		if(k == 1){
			cin >> b;
			sing[b].push_back(a);
		} else {
			rep(_, 0, k-2){
				cin >> b;
				int nx = mk_new();
				lft[b].emplace_back(nx, a);
				rgt[nx].emplace_back(b, a);
				a = nx;
			}
			cin >> b >> c;
			lft[b].emplace_back(c, a);
			rgt[c].emplace_back(b, a);
		}
	}

	set<pil> anti;
	rep(_,0,m){
		int l;
		pil cur(0, 0);
		cin >> l;
		rep(_,0,l){
			int x;
			cin >> x;
			cur = app(cur, x);
		}
		anti.insert(cur);
	}
	map<pil, int> ren;
	ren[pil(0, 0)] = 0;
	function<bool(pil)> ins = [&](pil p){
		if(ren.count(p)) return true;
		if(!ins(pred(p))) return false;
		for(pil q = p; q.first; q = succ(q))
			if(anti.count(q))
				return false;
		ren[p] = 0;
		return true;
	};
	trav(p, anti) ins(pred(p));

	int ix = 0;
	trav(pa, ren) pa.second = ix++;

	vector<vi> pre_app(ix, vi(2));

	rep(d,0,2) trav(pa, ren){
		pil p = pa.first;
		if(ren.count(app(p, d))){
			pre_app[pa.second][d] = ren[app(p, d)];
		} else if(anti.count(app(p, d))) {
			pre_app[pa.second][d] = -1;
		} else if(p.first){
			pil q = succ(p);
			while(!ren.count(q)) q = succ(q);
			pre_app[pa.second][d] = pre_app[ren[q]][d];
		} else {
			pre_app[pa.second][d] = 0;
		}
		//cerr << pa.second << " " << d << " " << pre_app[pa.second][d] << endl;
	}

	vector<vector<vl>> dp(sz(sing), vector<vl>(ix, vl(ix, inf)));
	vector<vector<vl>> pd(sz(sing), vector<vl>(ix, vl(ix, inf)));

	priority_queue<pair<ull, pair<int, pii>>> pq;

	auto todo = [&](ull len, int res, int fr, int to){
		if(len < pd[res][fr][to]){
			pd[res][fr][to] = len;
			pq.push({inf - len, {res, {fr, to}}});
		}
	};

	rep(d,0,2) rep(i,0,ix) if(pre_app[i][d] != -1)
		todo(1, d, i, pre_app[i][d]);

	vl rek(sz(sing), inf);

	auto doto = [&](ull len, int res, int fr, int to){
		if(pd[res][fr][to] < len) return;
		dp[res][fr][to] = len;
		rek[res] = min(rek[res], len);
		trav(ser, sing[res]) todo(len, ser, fr, to);
		trav(pa, lft[res]){
			int ri = pa.first, ser = pa.second;
			rep(i,0,ix) if(dp[ri][to][i] < inf)
				todo(len + dp[ri][to][i], ser, fr, i);
		}
		trav(pa, rgt[res]){
			int le = pa.first, ser = pa.second;
			rep(i,0,ix) if(dp[le][i][fr] < inf)
				todo(len + dp[le][i][fr], ser, i, to);
		}
	};

	while(!pq.empty()){
		auto t = pq.top(); pq.pop();
		doto(inf - t.first, t.second.first, t.second.second.first, t.second.second.second);
	}

	rep(i,2,g){
		if(rek[i] == inf) cout << "YES" << endl;
		else cout << "NO" << " " << rek[i] << endl;
	}
}

#include <bits/stdc++.h>
using namespace std;
#define ll long long
void ckmn(ll&x,ll y){x=min(x,y);}const int A=55;const ll inf=4e18;int go[A][2],link[A],leaf[A],root,tsz;
void Add(int&c,int s[],int n){if(!c)c=++tsz;if(n==0){leaf[c]=1;return;}Add(go[c][s[0]],s+1,n-1);}
void Build(){queue<int> q;link[root]=root;for(int i=0;i<2;i++){if(go[root][i]){link[go[root][i]]=root;q.push(go[root][i]);}else go[root][i]=root;}
	while(q.size()){int u=q.front();q.pop();leaf[u]|=leaf[link[u]];for(int i=0;i<2;i++){if(go[u][i])link[go[u][i]]=go[link[u]][i],q.push(go[u][i]);else go[u][i]=go[link[u]][i];}}}
const int N=105;int b[N][N],a[N],sz[N],s[A];ll dp[N][A][A],tmp[A],nxt[A];bool fl1[N],fl2[N];
int main(){root=++tsz;int g,n,m;scanf("%i %i %i",&g,&n,&m);for(int i=1;i<=n;++i){scanf("%i %i",&a[i],&sz[i]);for(int j=1;j<=sz[i];++j)scanf("%i",&b[i][j]);}
	for(int i=1,l;i<=m;++i){scanf("%i",&l);for(int j=0;j<l;++j)scanf("%i",&s[j]);Add(root,s,l);}Build();
	for(int k=0;k<g;++k)for(int i=1;i<=tsz;++i)for(int j=1;j<=tsz;++j)dp[k][i][j]=inf;
	for(int i=1;i<=tsz;++i){if(!leaf[go[i][0]])dp[0][i][go[i][0]]=1;if(!leaf[go[i][1]])dp[1][i][go[i][1]]=1;}
	fl1[0]=fl1[1]=1;while(1){bool ok=0;for(int i=0;i<g;++i)fl2[i]=0;for(int i=1;i<=n;++i){bool has=0;for(int j=1;j<=sz[i];++j)if(fl1[b[i][j]]&&!fl2[b[i][j]])has=1;
			if(!has)continue;for(int st=1;st<=tsz;++st){for(int j=1;j<=tsz;++j)tmp[j]=inf;tmp[st]=0;for(int j=1;j<=sz[i];++j){for(int k=1;k<=tsz;++k)nxt[k]=inf;
					for(int k=1;k<=tsz;++k){for(int ed=1;ed<=tsz;++ed){ckmn(nxt[ed],tmp[k]+dp[b[i][j]][k][ed]);}}for(int k=1;k<=tsz;++k)tmp[k]=nxt[k];}
				for(int j=1;j<=tsz;++j)if(dp[a[i]][st][j]>tmp[j]){dp[a[i]][st][j]=tmp[j];fl2[a[i]]=1;ok=1;}}}if(!ok)break;for(int i=0;i<g;++i)fl1[i]=fl2[i];}
	for(int i=2;i<g;++i){ll ans=inf;for(int ed=1;ed<=tsz;++ed)ans=min(ans,dp[i][root][ed]);if(ans==inf)printf("YES\n");else printf("NO %lld\n",ans);}return 0;}

#include <iostream>
#include <vector>
#include <chrono>
#include <random>
#include <cassert>
#include <queue>
#include <cstring>
#include <algorithm>

std::mt19937 rng((int) std::chrono::steady_clock::now().time_since_epoch().count());

template<const int ALPHA = 2, class T = std::vector<int>, const int off = 0>
struct Aho {
	struct Node {
		int to[ALPHA];
		int size;
		int fail, pfail;
		bool present;

		Node() {
			for(int i = 0; i < ALPHA; i++) {
				to[i] = 0;
			}
			size = 0;
			pfail = fail = 0;
			present = false;
			// maybe initialize some other stuff here
		}

		// maybe add some other stuff here
	};

	Aho() {
		nodes.push_back(Node());
	}

	template<class CH>
	int nextState(int on, CH ch) const {
		return nodes[on].to[ch - off];
	}

	int addString(const T &str) {
		int on = 0;
		for(auto ch : str) {
			if(nodes[on].to[ch-off] == 0) {
				nodes[on].to[ch-off] = (int) nodes.size();
				nodes.push_back(Node());
				nodes.back().size = 1 + nodes[on].size;
			}
			on = nodes[on].to[ch-off];
		}
		// makes this node present
		nodes[on].present = true;
		return on;
	}

	void build() {
		std::queue<int> que;
		que.push(0);
		while(!que.empty()) {
			int on = que.front();
			que.pop();
			if(nodes[nodes[on].fail].present) nodes[on].present = true;
			nodes[on].pfail = nodes[nodes[on].fail].present ? nodes[on].fail : nodes[nodes[on].fail].pfail;
			// do stuff that carries over with fail here
			for(int i = 0; i < ALPHA; i++) {
				int &to = nodes[on].to[i];
				if(to) {
					nodes[to].fail = on == 0 ? 0 : nodes[nodes[on].fail].to[i];
					que.push(to);
				} else {
					to = nodes[nodes[on].fail].to[i];
				}
			}
		}
	}

	std::vector<Node> nodes;
};

const int ms = 103;
const unsigned long long INF = (1LL << 63);

std::vector<std::vector<int>> rules[ms], special[ms];
unsigned long long dp[ms][ms][ms];
unsigned long long tmp[2][ms];

int main() {
	std::ios_base::sync_with_stdio(false); std::cin.tie(NULL);
	std::cerr << INF << '\n';
	int n, m, k;
	std::cin >> n >> m >> k;
	assert(n <= ms);
	while(m--) {
		int a, size;
		std::cin >> a >> size;
		int mx = 0;
		std::vector<int> rule;
		while(size--) {
			int x;
			std::cin >> x;
			mx = std::max(x, mx);
			rule.push_back(x);
		}
		if(mx <= 1) {
			special[a].push_back(rule);
		} else {
			rules[a].push_back(rule);
		}
	}
	special[0].push_back(std::vector<int>(1, 0));
	special[1].push_back(std::vector<int>(1, 1));
	Aho<> aho;
	while(k--) {
		int size;
		std::cin >> size;
		std::vector<int> anti;
		while(size--) {
			int x;
			std::cin >> x;
			assert(x == 0 || x == 1);
			anti.push_back(x);
		}
		aho.addString(anti);
	}
	aho.build();
	for(int i = 0; i < ms; i++) for(int j = 0; j < ms; j++) for(int jj = 0; jj < ms; jj++) dp[i][j][jj] = INF;
	m = (int) aho.nodes.size();
	for(int i = 0; i < n; i++) {
		for(auto endString : special[i]) {
			for(int j = 0; j < m; j++) {
				int st = j;
				for(auto ch : endString) {
					if(aho.nodes[st].pfail != 0 || aho.nodes[st].present) {
						st = -1;
						break;
					}
					st = aho.nextState(st, ch);
					if(aho.nodes[st].pfail != 0 || aho.nodes[st].present) {
						st = -1;
						break;
					}
				}
				if(st != -1) {
					dp[i][j][st] = std::min(dp[i][j][st], (unsigned long long) endString.size());
				}
			}
		}
	}
	std::vector<int> perm;
	for(int i = 2; i < n; i++) {
		perm.push_back(i);
	}
	for(int rep = 0; 1; rep++) {
		//assert(rep < ms);
		if(rep % 3 == 0) std::sort(perm.begin(), perm.end());
		else if(rep % 3 == 1) std::shuffle(perm.begin(), perm.end(), rng);
		else std::sort(perm.rbegin(), perm.rend());
		bool run = false;
		for(auto i : perm) {
			for(int j = 0; j < m; j++) {
				for(auto rule : rules[i]) {
					for(int ii = 0; ii < m; ii++) {
						tmp[0][ii] = tmp[1][ii] = INF;
					}
					tmp[0][j] = 0;
					for(auto ch : rule) {
						for(int ii = 0; ii < m; ii++) if(tmp[0][ii] < INF) for(int jj = 0; jj < m; jj++) {
							tmp[1][jj] = std::min(tmp[1][jj], tmp[0][ii] + dp[ch][ii][jj]);
						}
						for(int ii = 0; ii < m; ii++) {
							tmp[0][ii] = tmp[1][ii];
							tmp[1][ii] = INF;
						}
					}
					for(int ii = 0; ii < m; ii++) {
						if(dp[i][j][ii] > tmp[0][ii]) {
							dp[i][j][ii] = tmp[0][ii];
							run = true;
						}
					}
				}
			}
		}
		if(!run) break;
	}
	for(int i = 2; i < n; i++) {
		unsigned long long mx = INF;
		for(int j = 0; j < m; j++) {
			mx = std::min(mx, dp[i][0][j]);
		}
		if(mx == INF) {
			std::cout << "YES\n";
		} else {
			std::cout << "NO " << mx << "\n";
		}
	}
}

#include"cstdio"
#include"queue"
#define int long long
namespace IAKIOI{
	const int L=1<<20|1;
	char buffer[L],*S,*TT;
	#define getchar() ((S==TT&&(TT=(S=buffer)+fread(buffer,1,L,stdin),S==TT))?EOF:*S++)
	inline void read(int &x){
		x=0;int f=1;char s=getchar();
		while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
		while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
		x*=f;
	}
	inline void write(int x){
		if(x<0){putchar('-');x=-x;}
		if(x>9)write(x/10);
		putchar(x%10+'0');
	}
}
using namespace IAKIOI;
const unsigned int oo=1ull<<63;
unsigned int f[205][52][52];
int G,N,M,n,m,b[55],ty[205],v[205][55][55];
std::vector<std::pair<int,int>>out[205];
int ch[55][2],fail[55],ok[55],rt=1,tot=1;
inline void insert(int*a,int len){
	int nw=rt;
	for(int i=1;i<=len;i++){
		if(!ch[nw][a[i]])ch[nw][a[i]]=++tot;
		nw=ch[nw][a[i]];
	}
	ok[nw]=1;
}
std::queue<int>Q;
inline void getfail(){
	for(int i=0;i<=1;i++)
		if(ch[rt][i])fail[ch[rt][i]]=rt,Q.push(ch[rt][i]);
		else ch[rt][i]=rt;
	while(Q.size()){
		int u=Q.front();Q.pop();
		for(int i=0;i<=1;i++)
			if(ch[u][i]){
				fail[ch[u][i]]=ch[fail[u]][i];
				ok[ch[u][i]]|=ok[fail[ch[u][i]]];
				Q.push(ch[u][i]);
			}
			else ch[u][i]=ch[fail[u]][i];
	}
}
int id[55],num[55];
struct node{
	int x,fr,ed;
	unsigned int num;
	node(int _x=0,int _fr=0,int _ed=0,unsigned int _num=0){
		x=_x;fr=_fr;ed=_ed;num=_num;
	}
	friend bool operator<(node a,node b){
		return a.num>b.num;
	}
};
std::priority_queue<node>Heap;
signed main(){
	read(G),G--;read(N),read(M),n=G;
	for(int i=1,a=0,k=0;i<=N;i++,n+=k){
		read(a),read(k);
		for(int j=1;j<=k;j++)read(b[j]),ty[n+j]=1;
		for(int j=2;j<=k;j++){
			out[n+j].push_back(std::make_pair(n+j-1,b[j-1]));
			out[b[j-1]].push_back(std::make_pair(n+j-1,n+j));
		}
		out[b[k]].push_back(std::make_pair(n+k,-1));
		out[n+1].push_back(std::make_pair(a,-1));
	}
	for(int i=1,len;i<=M;i++){
		read(len);
		for(int j=1;j<=len;j++)read(b[j]);
		insert(b,len);
	}
	getfail();
	int cnt=0;
	for(int i=1;i<=tot;i++)if(!ok[i])id[i]=++cnt,num[cnt]=i;
	for(int i=0;i<=n;i++)
		for(int j=1;j<=cnt;j++)
			for(int k=1;k<=cnt;k++)
				f[i][j][k]=oo;
	for(int i=1;i<=cnt;i++){
		int x=num[i];
		if(id[ch[x][0]]){
			f[0][i][id[ch[x][0]]]=1;
			Heap.push(node(0,i,id[ch[x][0]],1));
		}
		if(id[ch[x][1]]){
			f[1][i][id[ch[x][1]]]=1;
			Heap.push(node(1,i,id[ch[x][1]],1));
		}
	}
	while(Heap.size()){
		node tmp=Heap.top();
		Heap.pop();
		int x=tmp.x,fr=tmp.fr,ed=tmp.ed;
		unsigned int val=tmp.num;
		if(v[x][fr][ed])continue;
		v[x][fr][ed]=1;
		for(std::pair<int,int>u:out[x]){
			int y=u.first,w=u.second;
			if(w==-1){
				if(f[y][fr][ed]>val){
					f[y][fr][ed]=val;
					Heap.push(node(y,fr,ed,f[y][fr][ed]));
				}
			}
			else{
				if(!ty[x]){
					for(int j=1;j<=cnt;j++)
						if(f[y][fr][j]>val+f[w][ed][j]){
							f[y][fr][j]=val+f[w][ed][j];
							Heap.push(node(y,fr,j,f[y][fr][j]));
						}
				}
				else{
					for(int j=1;j<=cnt;j++)
						if(f[y][j][ed]>val+f[w][j][fr]){
							f[y][j][ed]=val+f[w][j][fr];
							Heap.push(node(y,j,ed,f[y][j][ed]));
						}
				}
			}
		}
	}
	for(int i=2;i<=G;i++){
		unsigned int ans=oo;
		for(int j=1;j<=cnt;j++)ans=std::min(ans,f[i][1][j]);
		(ans==oo)?puts("YES"):printf("NO %lld\n",ans);
	}
	return 0;
}

/* be name khoda */

// #define long_enable
#include <iostream>
#include <algorithm>
#include <cstring>
#include <numeric>
#include <vector>
#include <fstream>
#include <set>
#include <queue>
using namespace std;

#ifdef long_enable
typedef long long int ll;
#else
typedef int ll;
#endif

typedef pair<ll, ll> pii;
typedef pair<pii, ll> ppi;
typedef pair<ll, pii> pip;
typedef vector<ll> vi;
typedef vector<pii> vpii;

#define forifrom(i, s, n) for (ll i = s; i < n; ++i)
#define forirto(i, n, e) for (ll i = (n) - 1; i >= e; --i)
#define fori(i, n) forifrom (i, 0, n)
#define forir(i, n) forirto (i, n, 0)

#define F first
#define S second
#define pb push_back
#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define smin(a, b) a = min(a, (b))
#define smax(a, b) a = max(a, (b))

#define debug(x) cout << #x << " -> " << (x) << endl
#define debug2(x, y) cout << #x << ' ' << #y << " -> " << (x) << ' ' << (y) << endl
#define debug3(x, y, z) cout << #x << ' ' << #y << ' ' << #z << " -> " << (x) << ' ' << (y) << ' ' << (z) << endl
#define debug4(x, y, z, t) cout << #x << ' ' << #y << ' ' << #z << ' ' << #t << " -> " << (x) << ' ' << (y) << ' ' << (z) << ' ' << (t) << endl
#define debuga(x, n) cout << #x << " -> "; fori (i1_da, n) { cout << (x)[i1_da] << ' '; } cout << endl
#define debugaa(x, n, m) cout << #x << " ->\n"; fori (i1_daa, n) { fori (i2_daa, m) { cout << (x)[i1_daa][i2_daa] << ' '; } cout << '\n'; } cout << endl

const ll MOD = 1000000007;
const ll INF = 2000000000;
const long long BIG = 1446803456761533460LL;

#define XL (x << 1)
#define XR (XL | 1)
#define MD ((l + r) >> 1)
#define Add(a, b) a = ((a) + (b)) % MOD
#define Mul(a, b) a = (1LL * (a) * (b)) % MOD

// -----------------------------------------------------------------------

const ll maxk = 110;
const ll maxl = 52;
const ll E = 2;

ll G, N, M, K, nn;
ll nxt[maxl][E], F[maxl], q[maxl], ql, qr;
long long dp[maxk][maxl][maxl];
bool vis[maxk][maxl][maxl], anti[maxl];

struct Node {
    ll gene, in, out;
};

typedef pair<long long, Node> pind;

struct Cmp_pind {
    bool operator() (pind &a, pind &b) {
        return a.F > b.F;
    }
};

priority_queue<pind, vector<pind>, Cmp_pind> pq;
vector<pair<Node, long long>> out[maxk][maxl][maxl];
vpii adj[maxk];

void add_to_trie(ll *c, ll l) {
    ll x = 0;
    fori (i, l) {
        if (!nxt[x][c[i]]) nxt[x][c[i]] = nn++;
        x = nxt[x][c[i]];
    }
    anti[x] = 1;
}

void build_aho() {
    fori (e, E) if (nxt[0][e]) q[qr++] = nxt[0][e], anti[nxt[0][e]] |= anti[0];
    while (qr > ql) {
        ll x = q[ql++];
        fori (e, E) {
            if (nxt[x][e]) {
                F[nxt[x][e]] = nxt[F[x]][e];
                q[qr++] = nxt[x][e];
                anti[nxt[x][e]] |= anti[F[nxt[x][e]]];
            } else {
                nxt[x][e] = nxt[F[x]][e];
            }
        }
    }
}

void add_to_grammer(ll a, ll k, ll *b) {
    forir (i, k - 2) {
        adj[b[i + 2]].eb(b[i + 1], K);
        b[i + 1] = K;
        ++K;
    }
    if (k > 1) adj[b[1]].eb(b[0], a);
    else adj[b[0]].eb(-1, a);
}

inline void update(ll gene, ll in, ll out, long long w) {
    long long &dpp = dp[gene][in][out];
    if (dpp == -1 || dpp > w) {
        dpp = w;
        pq.push({w, {gene, in, out}});
    }
}

void calc_dp_dijkstra() {
    memset(dp, -1, sizeof dp);
    fori (i, nn) {
        fori (e, E) if (!anti[nxt[i][e]]) update(e, i, nxt[i][e], 1);
    }
    while (!pq.empty()) {
        Node x = pq.top().S;
        long long w = pq.top().F;
        pq.pop();
        if (vis[x.gene][x.in][x.out]) continue;
        vis[x.gene][x.in][x.out] = 1;

        for (auto [to, v] : out[x.gene][x.in][x.out]) update(to.gene, to.in, to.out, w + v);

        for (auto [from, to] : adj[x.gene]) {
            if (from == -1) {
                update(to, x.in, x.out, w);
            } else fori (i, nn) if (!anti[i]) {
                if (vis[from][i][x.in]) {
                    update(to, i, x.out, dp[from][i][x.in] + w);
                } else {
                    out[from][i][x.in].pb({{to, i, x.out}, w});
                }
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);

    cin >> G >> N >> M;
    K = G, nn = 1;
    fori (i, N) {
        ll a, k; cin >> a >> k;
        ll b[k];
        fori (j, k) {
            cin >> b[j];
        }
        add_to_grammer(a, k, b);
    }
    fori (i, M) {
        ll l; cin >> l;
        ll c[l];
        fori (j, l) cin >> c[j];
        add_to_trie(c, l);
    }

    build_aho();
    calc_dp_dijkstra();

    forifrom (i, 2, G) {
        long long mn = -1;
        fori (j, nn) {
            long long v = dp[i][0][j];
            if (v != -1) {
                if (mn == -1 || v < mn) mn = v;
            }
        }
        if (mn == -1) cout << "YES\n";
        else cout << "NO " << mn << '\n';
    }

}

#include<bits/stdc++.h>
#define ll long long
#define ull unsigned ll
#define uint unsigned
#define pii pair<int,int>
#define pll pair<ll,ll>
#define IT iterator
#define PB push_back
#define fi first
#define se second
#define For(i,j,k) for (int i=(int)(j);i<=(int)(k);i++)
#define Rep(i,j,k) for (int i=(int)(j);i>=(int)(k);i--)
#define CLR(a,v) memset(a,v,sizeof(a));
#define CPY(a,b) memcpy(a,b,sizeof(a));
#define debug puts("wzpakking")
#define y1 ysghysgsygsh
using namespace std;
namespace ACM{
	int ch[55][2],nd=1;
	int fa[55],gg[55],q[55];
	void init(){
		int l,x=1,c;
		scanf("%d",&l);
		For(i,1,l){
			scanf("%d",&c);
			if (!ch[x][c]) ch[x][c]=++nd;
			x=ch[x][c];
		}
		gg[x]=1;
	}
	void build(){
		int h=0,t=0;
		For(i,0,1)
			if (ch[1][i]){
				fa[ch[1][i]]=1;
				q[++t]=ch[1][i];
			}
			else
				ch[1][i]=1;
		while (h!=t){
			int x=q[++h];
			gg[x]|=gg[fa[x]];
			For(i,0,1)
				if (ch[x][i]){
					fa[ch[x][i]]=ch[fa[x]][i];
					q[++t]=ch[x][i];
				}
				else
					ch[x][i]=ch[fa[x]][i];
		}
	}
}
int G,n,m;
int to[105];
int f1[105],f2[105];
vector<int> op[105];
ull d1[55][55];
ull d2[55][55];
ull dis[105][55][55];
int main(){
	scanf("%d%d%d",&G,&n,&m);
	For(i,1,n){
		int l,x;
		scanf("%d%d",&to[i],&l);
		For(j,1,l) scanf("%d",&x),op[i].PB(x);
	}
	For(i,1,m) ACM::init();
	ACM::build();
	m=ACM::nd;
	For(i,0,G-1) For(j,1,m) For(k,1,m)
		dis[i][j][k]=1ull<<63;
	For(i,0,1) For(j,1,m){
		int to=ACM::ch[j][i];
		if (!ACM::gg[to])
			dis[i][j][to]=1;
	}
	f1[0]=f1[1]=1;
	for (;;){
		bool fllag=0;
		memset(f2,0,sizeof(f2));
		For(i,1,n){
			bool flag=0;
			for (auto p:op[i])
				flag|=f1[p]&&(!f2[p]);
			if (!flag) continue;
			For(j,1,m) For(k,1,m)
				d1[j][k]=(j==k?0:(1ull<<63));
			for (auto p:op[i]){
				For(j,1,m) For(k,1,m) d2[j][k]=1ull<<63;
				For(j,1,m) For(k,1,m) For(l,1,m)
					if (d1[j][k]<-dis[p][k][l])
						d2[j][l]=min(d2[j][l],d1[j][k]+dis[p][k][l]);
				For(j,1,m) For(k,1,m) d1[j][k]=d2[j][k];
			}
			For(j,1,m) For(k,1,m)
				if (d1[j][k]<dis[to[i]][j][k]){
					//if (!d1[j][k]) cout<<i<<' '<<to[i]<<' '<<j<<' '<<k<<endl;
					dis[to[i]][j][k]=d1[j][k],fllag=1,f2[to[i]]=1;
				}
		}
		if (!fllag) break;
		For(i,0,G-1) swap(f1[i],f2[i]);
	}
	For(i,2,G-1){
		ull ans=1ull<<63;
		For(j,1,m) ans=min(ans,dis[i][1][j]);
		if (ans==(1ull<<63)) puts("YES");
		else printf("NO %llu\n",ans);
	}
}
/*
抗体个数:50
转移长度:100
基因个数:100
总复杂度:抗体个数^3*基因个数
        *抗体个数^2*转移长度
*/

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "unroll-loops")
using namespace std;

#define ll long long
#define pii pair<int, int>
#define f first
#define s second

#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()

#define pb push_back

#ifdef BALBIT
#define bug(...) cerr<<"#"<<__LINE__<<": "<<#__VA_ARGS__<<"- ", _do(__VA_ARGS__)
template<typename T> void _do(T && x){cerr<<x<<endl;}
template<typename T, typename ...S> void _do(T && x, S && ...y){cerr<<x<<", "; _do(y...);}
#else
#define endl '\n'
#define bug(...)
#endif // BALBIT

#define IOS() ios::sync_with_stdio(0), cin.tie(0)

//const int maxn = 2e5+5;

const int maxt = 53;
int to[maxt][2];
int fail[maxt];
bool isend[maxt];
vector<int> meto[maxt];
int IT = 1;
ll F[102][maxt][maxt];

void buildac(vector<vector<int> > &vv) {
    memset(to, -1, sizeof to);
    sort(ALL(vv), [&](vector<int> a, vector<int> b){return SZ(a) < SZ(b);});
    vector<int> nok(SZ(vv));
    for (int i = 0; i<SZ(vv); ++i) {
        for (int j = i+1; j<SZ(vv); ++j) {
            for (int k = 0; k + SZ(vv[i]) <= SZ(vv[j]); ++k) {
                bool sm = 1;
                for (int l = 0; l<SZ(vv[i]); ++l) {
                    if (vv[i][l] != vv[j][l+k]) {
                        sm = 0; break;
                    }
                }
                if (sm) {
                    nok[j] = 1; break;
                }
            }
        }
    }
    for (int cnt = 0; cnt <SZ(vv); ++cnt) {
        if (nok[cnt]) continue;
        vector<int> v = vv[cnt];
        int at = 0;
        for (int x : v) {
            int nxt = to[at][x] == -1? IT ++: to[at][x];
            to[at][x] = nxt;
            meto[nxt] = meto[at]; meto[nxt].pb(x);
            if (isend[at]) isend[nxt] = 1;
            at = nxt;
        }
        isend[at] = 1;
    }
//    if (to[0][0] == -1) {
//        to[0][0] = IT++;
//        meto[IT-1] = {0};
//    }
//    if (to[0][1] == -1) {
//        to[0][1] = IT++;
//        meto[IT-1] = {1};
//    }
    for (int i = 1; i<IT; ++i) {
        for (int j = 0; j<IT; ++j) {
            if (SZ(meto[j]) < SZ(meto[i]) && SZ(meto[j]) > SZ(meto[fail[i]])) {
                bool ok = 1;
                for (int k = 1; k<=SZ(meto[j]); ++k) {
                    if (meto[i][SZ(meto[i]) - k] != meto[j][SZ(meto[j]) - k]) {
                        ok = 0; break;
                    }
                }
                if (ok) fail[i] = j;
            }
        }
//            bug(i);
//            for (int x : meto[i]) cout<<x<<' ';
//            bug(fail[i]);
    }
    memset(F, -1, sizeof F);
    for (int i = 0; i<IT; ++i) {
        if (!isend[i]) {
            int tmp = i;
            while (tmp!= 0 && (to[tmp][0]==-1)) tmp = fail[tmp];
//            bug(i, tmp);
            if (~to[tmp][0]) {
                F[0][i][to[tmp][0]] = 1;
                bug(i, to[tmp][0]);
            }else F[0][i][0] = 1;
        }
        if (!isend[i]) {
            int tmp = i;
            while (tmp!= 0 && (to[tmp][1]==-1)) tmp = fail[tmp];
//            bug(i, tmp);
            if (~to[tmp][1]) {
                F[1][i][to[tmp][1]] = 1;
                bug(i, to[tmp][1]);
            }else F[1][i][0] = 1;
        }
    }
}

vector<vector<int> > posg;

inline void W(ll &a, ll b) {
    if (a == -1) a = b;
    else if (b != -1) a = min(a,b);
}

ll dp[102][maxt];// position, node

bool go(int N, vector<int> &v) {
    int n = SZ(v);
    bool chg = 0;
    if (n == 1) {
        for (int st = 0; st<IT; ++st) if (!isend[st])
            for (int en = 0; en < IT; ++en)
                if (!isend[en]){
                    ll tmp = F[N][st][en];
                    W(F[N][st][en], F[v[0]][st][en]);
                    if (F[N][st][en] != tmp) chg = 1;
                }
        return chg;
    }
    for (int st = 0; st < IT; ++ st) if (!isend[st]) {
        for (int i =0 ; i<=n; ++i) {
            for (int j = 0; j<IT; ++j) dp[i][j] = -1;
        }
        dp[0][st] = 0;
        for (int i = 1; i<=n; ++i) {
            for (int nd = 0; nd < IT; ++nd) {
                if (!isend[nd]) {
                    for (int frm = 0; frm < IT; ++frm) {
                        if (!isend[frm] && dp[i-1][frm] != -1 && F[v[i-1]][frm][nd] != -1) {
//                            if (dp[i-1][frm] != -1 && i-1 != 0) {
//                                bug(i-1, dp[i-1][frm]); assert(0);
//                            }
                            if (dp[i-1][frm] <= LLONG_MAX - F[v[i-1]][frm][nd])
                                W(dp[i][nd], dp[i-1][frm] + F[v[i-1]][frm][nd]);
                        }
                    }
                }
            }
        }
        for (int en = 0; en < IT; ++en)
            if (!isend[en]) {
                ll tmp = F[N][st][en];
                W(F[N][st][en], dp[n][en]);
                if (F[N][st][en] != tmp) chg = 1;
            }
    }
    return chg;
}

vector<int> rg[103];

signed main(){
    IOS();
    bug(LLONG_MAX);
    bug((1ull << 63) - 1);
    int G,numg,m; cin>>G>>numg>>m;
//    if (m == 0) assert(0);
    vector<int> aofnum;
    for (int i = 0; i<numg; ++i) {
        int a,k; cin>>a>>k;
        aofnum.pb(a);
        vector<int> hi(k);
        vector<int> seen(102,0);
        for (int j = 0; j<k; ++j) {
            cin>>hi[j];
            if (!seen[hi[j]]) rg[hi[j]].pb(i);
            seen[hi[j]] = 1;
        }
        posg.pb(hi);
    }
    vector<vector<int> > gogo;
    for (int i = 0; i<m; ++i) {
        int k; cin>>k;
        vector<int> tmp(k);
        for (int j=0;j<k;++j) cin>>tmp[j];
        gogo.pb(tmp);
    }
    buildac(gogo);
//    assert(IT <= 30);
    bug(IT);
    queue<int> qq;
    vector<int> inq(G+2,0);
    qq.push(G);
    for (int i = 0; i<numg; ++i) {
        rg[G].pb(i);
    }
    while (!qq.empty()) {
        int x = qq.front(); qq.pop(); inq[x] = 0;
        bug(x);
        for (int u : rg[x]) {
            bug(u, aofnum[u]);
            if (go(aofnum[u], posg[u])) {
                if (!inq[aofnum[u]]) {
                    qq.push(aofnum[u]);
                    inq[aofnum[u]] = 1;
                }
            }
        }
    }
    for (int i = 0; i<numg; ++i) {
        if (go(aofnum[i],posg[i])) {
            assert(0);
        }
    }
    for (int N = 2; N<G; ++N) {
        ll re = -1;
        for (int j = 0; j<IT; ++j) {
            if (!isend[j]) {
                W(re, F[N][0][j]);
            }
        }
        if (re == -1) cout<<"YES"<<endl;
        else cout<<"NO"<<' '<<re<<endl;
//        cout<<re<<endl;
    }
}
/*
3 1 0
2 6 1 0 1 0 0 0
*/

#include <bits/stdc++.h>
using namespace std;

// macros
typedef unsigned long long ll;
typedef long double ld;
typedef pair<int, int> ii;
typedef pair<ll, ll> lll;
typedef tuple<int, int, int> iii;
typedef tuple<ll, ll, ll, ll> iiii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
typedef vector<lll> vlll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define FOR(a,b) for(auto& a : b)
#define all(a) a.begin(), a.end()
#define EPS 1e-9
#define pb push_back
#define popb pop_back
#define fi first
#define se second
#define sz size()
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

// input
template<class T> void IN(T& x) {cin >> x;}
template<class H, class... T> void IN(H& h, T&... t) {IN(h); IN(t...); }
template<class H> void INA(H bg, H ed) {while(bg != ed) IN(*bg++);}

// output
template<class T> void OUT(const T& x) {cout << x;}
template<class H, class... T> void OUT(const H& h, const T&... t) {OUT(h); OUT(t...); }

//===================//
//  Added libraries  //
//===================//

//===================//
//end added libraries//
//===================//

void program();
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    program();
}

//===================//
//   begin program   //
//===================//

const int MX = 300;
ll INF = (1ll<<63ll)+(1ll<<62ll);
int og, g, n, m;
int a[MX], k[MX], b[MX][MX];
int l[MX], c[MX][MX], suml;
ll dp[MX][MX][MX];
priority_queue<iiii, vector<iiii>, greater<iiii>> pq;
vi rev[MX];

int getNextState(string t) {
    int x=0, ans=0, longest=0;
    RE(i,m) {
        string s;
        RE(j,l[i]) {
            if(s.sz > longest && s.sz <= t.sz) {
                bool pos = 1;
                RE(k,s.sz) if(t[t.sz-k-1] != s[s.sz-k-1]) {
                    pos=0;
                    break;
                }
                if(pos) longest = s.sz, ans=x;
            }
            s += '0'+c[i][j];
            x++;
        }
        if(s.sz <= t.sz) {
            bool pos = 1;
            RE(k,s.sz) if(t[t.sz-k-1] != s[s.sz-k-1]) {
                pos=0;
                break;
            }
            if(pos) return suml;
        }
    }
    return ans;
}
void fillDpBase() {
    int x=0;
    RE(i,m) {
        string s;
        RE(j,l[i]) {
            dp[0][x][getNextState(s+"0")] = 1;
            dp[1][x][getNextState(s+"1")] = 1;
            s += '0'+c[i][j];
            x++;
        }
    }
    if(m == 0) {
        dp[0][0][0] = 1;
        dp[1][0][0] = 1;
    }
}

void program() {
    IN(g,n,m); og=g;
    RE(i,n) IN(a[i]), IN(k[i]), INA(b[i], b[i]+k[i]);
    RE(i,m) IN(l[i]), INA(c[i], c[i]+l[i]);

    // change transitions so k <= 2
    RE(i,n) {
        if(k[i] > 2) {
            a[n] = g;
            k[n] = k[i]-1;
            RE(j,k[n]) b[n][j] = b[i][j];
            b[i][0] = g; b[i][1] = b[i][k[i]-1];
            k[i] = 2;
            g++; n++;
        }
    }

    // fill rev
    RE(i,n) RE(j,k[i]) rev[b[i][j]].pb(i);

    // set initial dp
    RE(i,m) suml += l[i];
    if(m == 0) suml = 1;
    RE(i,g) RE(j,suml) RE(k,suml) dp[i][j][k]=INF;
    fillDpBase();

    // fill dp
    RE(i,2) RE(j,suml) RE(k,suml) pq.push({dp[i][j][k], i, j, k});
    while(!pq.empty()) {
        iiii p = pq.top(); pq.pop();
        ll X, I, J, K;
        tie(X, I, J, K) = p;
        if(X == INF) break;
        if(dp[I][J][K] != X) continue;
        FOR(i,rev[I]) {
            if(k[i] == 1) {
                if(dp[a[i]][J][K] > X) {
                    dp[a[i]][J][K] = X;
                    pq.push({X, a[i], J, K});
                }
            } else {
                if(b[i][0] == I) {
                    RE(j,suml) {
                        if(dp[b[i][1]][K][j] == INF) continue;
                        ll Y = X + dp[b[i][1]][K][j];
                        if(dp[a[i]][J][j] > Y) {
                            dp[a[i]][J][j] = Y;
                            pq.push({Y, a[i], J, j});
                        }
                    }
                }
                if(b[i][1] == I) {
                    RE(j,suml) {
                        if(dp[b[i][0]][j][J] == INF) continue;
                        ll Y = dp[b[i][0]][j][J] + X;
                        if(dp[a[i]][j][K] > Y) {
                            dp[a[i]][j][K] = Y;
                            pq.push({Y, a[i], j, K});
                        }
                    }
                }
            }
        }
    }

    // print answers
    REP(i,2,og) {
        ll mn = INF;
        RE(j,suml) mn = min(mn, dp[i][0][j]);
        if(mn == INF) OUT("YES\n");
        else OUT("NO ",mn,"\n");
    }
}

#include <iostream>
#include <complex>
#include <vector>
#include <string>
#include <algorithm>
#include <cstdio>
#include <numeric>
#include <cstring>
#include <ctime>
#include <cstdlib>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <cmath>
#include <bitset>
#include <cassert>
#include <queue>
#include <stack>
#include <deque>
#include <random>

using namespace std;
template<typename T1, typename T2> inline void chkmin(T1 &a, T2 b) {if (a > b) a = b;}
template<typename T1, typename T2> inline void chkmax(T1 &a, T2 b) {if (a < b) a = b;}
#define files(FILENAME) read(FILENAME); write(FILENAME)
#define read(FILENAME) freopen((FILENAME + ".in").c_str(), "r", stdin)
#define write(FILENAME) freopen((FILENAME + ".out").c_str(), "w", stdout)
#define all(c) (c).begin(), (c).end()
#define sz(c) (int)(c).size()
#define left left228
#define right right228
#define y1 y1228
#define mp make_pair
#define pb push_back
#define y2 y2228
#define rank rank228
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const string FILENAME = "input";
const unsigned long long INF = (1ULL << 63);
const int MAXN = 55;
const int MAXG = 205;
const int MAXM = 100228;

int nG, G;
int n, m;
vector<vector<int> > d;
vector<vector<pair<int, int> > > d1;
vector<vector<int> > antis;
int uk;
int go[MAXN][2];
int link[MAXN];
bool terminal[MAXN];
vector<int> g[MAXM];
vector<pair<int, int> > gl[MAXM], gr[MAXM];

int addGene() {
	d.pb(vector<int>());
	d1.pb(vector<pair<int, int> >());
	return G++;
}

int node() {
	for (int it = 0; it < 2; it++) {
		go[uk][it] = -1;
	}
	return uk++;
}

void add(vector<int> s) {
	int cur = 0;
	for (int i = 0; i < sz(s); i++) {
		if (go[cur][s[i]] == -1) {
			go[cur][s[i]] = node();
		}
		cur = go[cur][s[i]];
	}
	terminal[cur] = true;
}

struct noda {
	ull t;
	int u;
	int l, r;
};

bool operator <(const noda& a, const noda& b) {
	return mp(a.t, mp(a.u, mp(a.l, a.r))) < mp(b.t, mp(b.u, mp(b.l, b.r)));
}

multiset<noda> s;
ull dist[MAXG][MAXN][MAXN];
bool used[MAXG][MAXN][MAXN];

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	//read(FILENAME);
	cin >> nG >> n >> m;
	G = nG;
	d.resize(G);
	d1.resize(G);
	for (int i = 0; i < n; i++) {
		int a, k;
		cin >> a >> k;
		if (k == 1) {
			int b;
			cin >> b;
			d[a].pb(b);
		} else {
			for (int j = 0; j < k - 2; j++) {
				int a1 = addGene();
				int b;
				cin >> b;
				d1[a].pb(mp(b, a1));
				a = a1;
			}
			int b1, b2;
			cin >> b1 >> b2;
			d1[a].pb(mp(b1, b2));
		}
	}
	for (int i = 0; i < m; i++) {
		int k;
		cin >> k;
		vector<int> cur;
		cur.resize(k);
		for (int j = 0; j < k; j++) {
			cin >> cur[j];
		}
		antis.pb(cur);
	}
	for (int it = 0; it < 2; it++) {
		go[0][it] = -1;
	}
	node();
	for (auto s: antis) {
		add(s);
	}
	queue<int> q;
	q.push(0);
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		if (terminal[link[v]]) {
			terminal[v] = true;
		}
		for (int c = 0; c < 2; c++) {
			if (go[v][c] == -1) {
				go[v][c] = (v == 0 ? 0: go[link[v]][c]);
			} else {
				q.push(go[v][c]);
				link[go[v][c]] = (v == 0 ? 0: go[link[v]][c]);
			}
		}
	}
	for (int i = 0; i < G; i++) {
		for (auto v: d[i]) {
			g[v].pb(i);
		}
		for (auto h: d1[i]) {
			gl[h.first].pb(mp(h.second, i));
			gr[h.second].pb(mp(h.first, i));
		}
	}
	for (int i = 0; i < G; i++) {
		for (int l = 0; l < uk; l++) {
			for (int r = 0; r < uk; r++) {
				dist[i][l][r] = INF;
			}
		}
	}
	for (int i = 0; i < uk; i++) {
		for (int it = 0; it < 2; it++) {
			if (!terminal[i] && !terminal[go[i][it]]) {
				s.insert({1, it, i, go[i][it]});
				dist[it][i][go[i][it]] = 1;
			}
		}
	}
	while (!s.empty()) {
		noda x = (*s.begin());
		s.erase(x);
		int u = x.u;
		int l = x.l;
		int r = x.r;
		ull t = x.t;
		if (used[u][l][r]) {
			continue;
		}
		used[u][l][r] = true;
		for (auto h: g[u]) {
			if (dist[h][l][r] > t) {
				dist[h][l][r] = t;
				s.insert({dist[h][l][r], h, l, r});
			}
		}
		for (auto x: gl[u]) {
			int h = x.first, h1 = x.second;
			for (int rs = 0; rs < uk; rs++) {
				ull nval = dist[h][r][rs] + t;
				if (!terminal[rs] && dist[h1][l][rs] > nval) {
					dist[h1][l][rs] = nval;
					s.insert({dist[h1][l][rs], h1, l, rs});
				}
			}
		}
		for (auto x: gr[u]) {
			int h = x.first, h1 = x.second;
			for (int ls = 0; ls < uk; ls++) {
				ull nval = dist[h][ls][l] + t;
				if (!terminal[ls] && dist[h1][ls][r] > nval) {
					dist[h1][ls][r] = nval;
					s.insert({dist[h1][ls][r], h1, ls, r});
				}
			}
		}
	}
	for (int i = 2; i < nG; i++) {
		ull opt = INF;
		for (int j = 0; j < uk; j++) {
			if (!terminal[j]) {
				chkmin(opt, dist[i][0][j]);
			}
		}
		if (opt == INF) {
			cout << "YES\n";
		} else {
			cout << "NO" << ' ' << opt << '\n';
		}
	}
}

#include <bits/stdc++.h>
#pragma GCC optimize ("O2,unroll-loops")
//#pragma GCC optimize("no-stack-protector,fast-math")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

using namespace std;
typedef unsigned long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<pii, int> piii;
typedef pair<ll, ll> pll;
#define debug(x) cerr<<#x<<'='<<(x)<<endl;
#define debugp(x) cerr<<#x<<"= {"<<(x.first)<<", "<<(x.second)<<"}"<<endl;
#define debug2(x, y) cerr<<"{"<<#x<<", "<<#y<<"} = {"<<(x)<<", "<<(y)<<"}"<<endl;
#define debugv(v) {cerr<<#v<<" : ";for (auto x:v) cerr<<x<<' ';cerr<<endl;}
#define all(x) x.begin(), x.end()
#define pb push_back
#define upd(x, y) x=min(x, y)

const int mod=1000000007;
const int N=55, SGM=103;

int n, m, k, u, v, x, y, t, a, b;
int C[N][2], F[N], bad[N], ts;
int A[SGM];
bool mark[SGM], mark2[SGM];
int topol[SGM], sz;
vector<int> B[SGM];
ll dp[N][N][SGM];
ll d0[N], d1[N];

int main(){
	ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	cin>>k>>n>>m;
	for (int i=1; i<=n; i++){
		cin>>A[i]>>x;
		B[i].resize(x);
		for (int j=0; j<x; j++) cin>>B[i][j];
	}
	mark[0]=mark[1]=1;
	for (int shit=0; shit<=n; shit++){
		for (int i=1; i<=n; i++) if (!mark2[i]){
			bool ok=1;
			for (int j:B[i]) if (!mark[j]) ok=0;
			if (ok){
				mark[A[i]]=1;
				mark2[i]=1;
				topol[sz++]=i;
			}
		}
	}
	// ------------------
	for (int i=0; i<m; i++){
		int v=0;
		cin>>x;
		while (x--){
			cin>>a;
			if (!C[v][a]) C[v][a]=++ts;
			v=C[v][a];
		}
		bad[v]=1;
	}
	queue<int> Q;
	for (int i:{0, 1}) if (C[0][i]) Q.push(C[0][i]);
	while (Q.size()){
		int v=Q.front();
		Q.pop();
		bad[v]|=bad[F[v]];
		for (int i:{0, 1}){
			if (!C[v][i]) C[v][i]=C[F[v]][i];
			else{
				F[C[v][i]]=C[F[v]][i];
				Q.push(C[v][i]);
			}
		}
	}
	// -------------------------
	memset(dp, 63, sizeof(dp)); // maybe not big enough :(
	ll INF=dp[0][0][0];
	for (int v=0; v<=ts; v++) if (!bad[v]) for (int i:{0, 1}){
		int u=C[v][i];
		if (bad[u]) continue ;
		dp[v][u][i]=1;
	}
	for (int shit=0; shit<18; shit++){
		for (int v=0; v<=ts; v++) if (!bad[v]){
			for (int ii=0; ii<sz; ii++){
				int i=topol[ii], c=A[i];
				memset(d0, 63, sizeof(d0));
				d0[v]=0;
				for (int x:B[i]){
					memcpy(d1, d0, sizeof(d1));
					memset(d0, 63, sizeof(d0));
					for (int u=0; u<=ts; u++) if (!bad[u]) for (int vv=0; vv<=ts; vv++){
						upd(d0[vv], d1[u]+dp[u][vv][x]);
					}
				}
				for (int u=0; u<=ts; u++) upd(dp[v][u][c], d0[u]);
			}
		}
	}

	for (int i=2; i<k; i++){
		if (!mark[i]) cout<<"YES\n";
		else{
			ll ans=INF;
			for (int v=0; v<=ts; v++) if (!bad[v]) ans=min(ans, dp[0][v][i]);
			if (ans==INF) cout<<"YES\n";
			else cout<<"NO "<<ans<<"\n";
		}
	}

	return 0;
}

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
using ll = long long;
const ll INF = (ll)1e18 + 7;

// Struct for priority queue operations on index set [1, n]
// push(i, v) overwrites value at position i if one already exists
// decKey is faster but requires that the new key is smaller than the old one
struct Prique {
	const ll INF = 4 * (ll)1e18;
	vector<pair<ll, int>> data;
	const int n;

	Prique(int siz) : n(siz), data(2*siz, {INF, -1}) { data[0] = {-INF, -1}; }
	void push(int i, ll v) {
		data[i+n] = {v, (v >= INF ? -1 : i)};
		for (i += n; i > 1; i >>= 1) data[i>>1] = min(data[i], data[i^1]);
	}
	void decKey(int i, ll v) {
		for (int j = i+n; data[j].first > v; j >>= 1) data[j] = {v, i};
	}
	pair<ll, int> pop() {
		auto res = data[1];
		push(res.second, INF);
		return res;
	}
	bool empty() {
		return data[1].first >= INF;
	}
};

class AhoCora {
	private:
		vector<int> pat_ind; // Index of pattern at this node (-1 if none)
		vector<int> suf_link; // Longest string in automata that is this one's true suffix
		vector<int> pat_link; // Index of next pattern when following suffix links
		vector<map<char, int>> conns; // Edges to children from this node

		// Alloc a new node
		int makeNode() {
			pat_ind.push_back(-1);
			suf_link.push_back(-1);
			pat_link.push_back(-1);
			conns.emplace_back();
			return (int)pat_ind.size() - 1;
		}

		// Get target of edge from node i, labeled with char c. -1 if none.
		int get(int i, char c) {
			auto it = conns[i].find(c);
			if (it == conns[i].end()) return -1;
			else return (*it).second;
		}

		// Set target of edge from node i, labeled with char c
		void set(int i, char c, int t) {
			conns[i][c] = t;
		}

		// Extends the suffix by the given character
		int extend(int i, char c) {
			int res = -1;
			while((i != -1) && (res == -1)) {
				res = get(i, c);
				i = suf_link[i];
			}
			return max(res, 0); // root always works
		}

	public:
		AhoCora() {
			makeNode(); // make root
		}

		// Adds the string to the automata
		// Time complexity: O(|pat| log C)
		void addPattern(const string& pat) {
			int i = 0; // current node
			for (char c : pat) {
				if (get(i, c) == -1) set(i, c, makeNode());
				i = get(i, c);
			}
			pat_ind[i] = 1;
		}

		// Build suf_link and pat_link. Call after inserting all patterns, before matching
		// Time complexity: O(\sum |pat| log C)
		void buildLinks() {
			vector<int> que;
			que.push_back(0);
			for (int j = 0; j < que.size(); ++j) {
				int i = que[j];
				for (auto pr : conns[i]) {
					char c = pr.first;
					int t = pr.second;
					suf_link[t] = extend(suf_link[i], c);
					if (pat_ind[suf_link[t]] != -1) pat_link[t] = suf_link[t];
					else pat_link[t] = pat_link[suf_link[t]];
					que.push_back(t);
				}
			}
		}

		int addChar(int i, char c) {
			int t = extend(i, c);
			if (pat_ind[t] != -1 || pat_link[t] != -1) return -1;
			else return t;

		}

		int size() {
			return pat_ind.size();
		}
};

const int G = 102;
const int N = 100;
const int M = 50;

vector<int> apps[G]; // Patterns where g appears
vector<int> mts[N]; // Patterns
ll moves[G][M+1][M+1]; // What which symbol can transform to and how fast?
ll cur[2][M+1][M+1];

vector<int> ss, tt;

void clearCur(int d, int k) {
	for (int s = 0; s < k; ++s) {
		for (int t = 0; t < k; ++t) cur[d][s][t] = INF;
	}
}

void updateVal(int i, int s, int t, ll v, Prique& que) {
	if (moves[i][s][t] > v) {
		moves[i][s][t] = min(moves[i][s][t], v);
		que.decKey(i, v);
		// cerr << "updateVal(" << i << ' ' << s << ' ' << t << ' ' << v << ")\n";
	}
}

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);

	int g, n, m;
	cin >> g >> n >> m;

	// read mutations
	for (int j = 0; j < n; ++j) {
		int i, len;
		cin >> i >> len;
		mts[j].resize(len + 1);
		mts[j][0] = i;
		for (int x = 1; x <= len; ++x) {
			cin >> mts[j][x];

			bool first_app = 1;
			for (int y = 1; y < x; ++y) {
				if (mts[j][y] == mts[j][x]) first_app = 0;
			}
			if (first_app) apps[mts[j][x]].push_back(j);
		}
	}

	// read antibodies, build the Aho-Corasick
	AhoCora ac;
	for (int i = 0; i < m; ++i) {
		string str;
		int len;
		cin >> len;
		for (int j = 0; j < len; ++j) {
			int b;
			cin >> b;
			str.push_back('0' + b);
		}
		ac.addPattern(str);
	}
	ac.buildLinks();
	int k = ac.size();

	// How many times can a string be updated?
	// 	It has k^2 pairs -> k^2 times
	//	Each time, we process some patterns. A pattern of length LEN can be processed LEN k^2 times
	//	Processing it takes len k^3 time (which for a max-length pattern, is already almost TL!)

	// If we store the transitions in a segment tree, we don't need to redo all of the work, just APPS * log k * k^3 of it
	// Still, k seems far too large!

	// Calculate initial pattern-avoiding moves
	for (int i = 0; i < g; ++i) {
		for (int s = 0; s < k; ++s) {
			for (int t = 0; t < k; ++t) moves[i][s][t] = INF;
		}
	}

	Prique que(g);
	for (int s = 0; s < k; ++s) {
		int t = ac.addChar(s, '0');
		if (t != -1) updateVal(0, s, t, 1, que);
		// cerr << s << " + 0 = " << t << '\n';

		t = ac.addChar(s, '1');
		if (t != -1) updateVal(1, s, t, 1, que);
		// cerr << s << " + 1 = " << t << '\n';
	}

	// While new, faster ways are found, apply them
	while(! que.empty()) {
		int i = que.pop().second;

		// cerr << "pushing updates from " << i << endl;
		for (int pat_ind : apps[i]) {
			// cerr << "updating pattern " << pat_ind << "!" << endl;

			vector<int>& pat = mts[pat_ind];
			int ti = pat[0];

			clearCur(0, k);
			clearCur(1, k);
			for (int s = 0; s < k; ++s) cur[0][s][s] = 0;
			for (int j = 1; j < pat.size(); ++j) {

				int ci = pat[j];
				int d1 = (j & 1);
				int d0 = 1 - d1;
				clearCur(d1, k);

				for (int p = 0; p < k; ++p) {
					tt.clear();
					for (int t = 0; t < k; ++t) {
						if (moves[ci][p][t] < INF) tt.push_back(t);
					}
					if (tt.empty()) continue;

					ss.clear();
					for (int s = 0; s < k; ++s) {
						if (cur[d0][s][p] < INF) ss.push_back(s);
					}

					for (auto s : ss) {
						for (auto t : tt) {
							cur[d1][s][t] = min(cur[d1][s][t], cur[d0][s][p] + moves[ci][p][t]);
						}
					}
				}
			}

			int dl = ((int)pat.size() - 1) & 1;
			for (int s = 0; s < k; ++s) {
				for (int t = 0; t < k; ++t) {
					// if (cur[dl][s][t] < INF) cerr << s << ' ' << t << " is now possible for " << ti << endl;
					updateVal(ti, s, t, cur[dl][s][t], que);
				}
			}
		}
	}

	// Output res
	for (int i = 2; i < g; ++i) {
		ll res = INF;
		for (int t = 0; t < k; ++t) {
			res = min(res, moves[i][0][t]);
		}
		if (res >= INF) cout << "YES\n";
		else cout << "NO " << res << '\n';
	}
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
typedef double db;
typedef string str;

typedef pair<int,int> pi;
typedef pair<ll,ll> pl;
typedef pair<db,db> pd;

typedef vector<int> vi;
typedef vector<ll> vl;
typedef vector<db> vd;
typedef vector<str> vs;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<pd> vpd;

#define mp make_pair
#define f first
#define s second
#define sz(x) (int)(x).size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend()
#define rsz resize
#define ins insert
#define ft front()
#define bk back()
#define pf push_front
#define pb push_back
#define eb emplace_back
#define lb lower_bound
#define ub upper_bound

#define FOR(i,a,b) for (int i = (a); i < (b); ++i)
#define F0R(i,a) FOR(i,0,a)
#define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i)
#define R0F(i,a) ROF(i,0,a)
#define trav(a,x) for (auto& a: x)

const int MOD = 1e9+7; // 998244353;
const int MX = 2e5+5;
const ll INF = 1e18;
const ld PI = acos((ld)-1);
const int xd[4] = {1,0,-1,0}, yd[4] = {0,1,0,-1};
mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

template<class T> bool ckmin(T& a, const T& b) {
	return b < a ? a = b, 1 : 0; }
template<class T> bool ckmax(T& a, const T& b) {
	return a < b ? a = b, 1 : 0; }
constexpr int pct(int x) { return __builtin_popcount(x); }
constexpr int bits(int x) { return 31-__builtin_clz(x); } // floor(log2(x))
ll cdiv(ll a, ll b) { return a/b+((a^b)>0&&a%b); } // divide a by b rounded up
ll fdiv(ll a, ll b) { return a/b-((a^b)<0&&a%b); } // divide a by b rounded down
ll half(ll x) { return fdiv(x,2); }

template<class T, class U> T fstTrue(T lo, T hi, U f) {
	hi ++; assert(lo <= hi); // assuming f is increasing
	while (lo < hi) { // find first index such that f is true
		T mid = half(lo+hi);
		f(mid) ? hi = mid : lo = mid+1;
	}
	return lo;
}
template<class T, class U> T lstTrue(T lo, T hi, U f) {
	lo --; assert(lo <= hi); // assuming f is decreasing
	while (lo < hi) { // find first index such that f is true
		T mid = half(lo+hi+1);
		f(mid) ? lo = mid : hi = mid-1;
	}
	return lo;
}
template<class T> void remDup(vector<T>& v) {
	sort(all(v)); v.erase(unique(all(v)),end(v)); }

// INPUT
template<class A> void re(complex<A>& c);
template<class A, class B> void re(pair<A,B>& p);
template<class A> void re(vector<A>& v);
template<class A, size_t SZ> void re(array<A,SZ>& a);

template<class T> void re(T& x) { cin >> x; }
void re(db& d) { str t; re(t); d = stod(t); }
void re(ld& d) { str t; re(t); d = stold(t); }
template<class H, class... T> void re(H& h, T&... t) { re(h); re(t...); }

template<class A> void re(complex<A>& c) { A a,b; re(a,b); c = {a,b}; }
template<class A, class B> void re(pair<A,B>& p) { re(p.f,p.s); }
template<class A> void re(vector<A>& x) { trav(a,x) re(a); }
template<class A, size_t SZ> void re(array<A,SZ>& x) { trav(a,x) re(a); }

// TO_STRING
#define ts to_string
str ts(char c) { return str(1,c); }
str ts(const char* s) { return (str)s; }
str ts(str s) { return s; }
str ts(bool b) {
	#ifdef LOCAL
		return b ? "true" : "false";
	#else
		return ts((int)b);
	#endif
}
template<class A> str ts(complex<A> c) {
	stringstream ss; ss << c; return ss.str(); }
str ts(vector<bool> v) {
	str res = "{"; F0R(i,sz(v)) res += char('0'+v[i]);
	res += "}"; return res; }
template<size_t SZ> str ts(bitset<SZ> b) {
	str res = ""; F0R(i,SZ) res += char('0'+b[i]);
	return res; }
template<class A, class B> str ts(pair<A,B> p);
template<class T> str ts(T v) { // containers with begin(), end()
	#ifdef LOCAL
		bool fst = 1; str res = "{";
		for (const auto& x: v) {
			if (!fst) res += ", ";
			fst = 0; res += ts(x);
		}
		res += "}"; return res;
	#else
		bool fst = 1; str res = "";
		for (const auto& x: v) {
			if (!fst) res += " ";
			fst = 0; res += ts(x);
		}
		return res;

	#endif
}
template<class A, class B> str ts(pair<A,B> p) {
	#ifdef LOCAL
		return "("+ts(p.f)+", "+ts(p.s)+")";
	#else
		return ts(p.f)+" "+ts(p.s);
	#endif
}

// OUTPUT
template<class A> void pr(A x) { cout << ts(x); }
template<class H, class... T> void pr(const H& h, const T&... t) {
	pr(h); pr(t...); }
void ps() { pr("\n"); } // print w/ spaces
template<class H, class... T> void ps(const H& h, const T&... t) {
	pr(h); if (sizeof...(t)) pr(" "); ps(t...); }

// DEBUG
void DBG() { cerr << "]" << endl; }
template<class H, class... T> void DBG(H h, T... t) {
	cerr << ts(h); if (sizeof...(t)) cerr << ", ";
	DBG(t...); }
#ifdef LOCAL // compile with -DLOCAL
	#define dbg(...) cerr << "LINE(" << __LINE__ << ") -> [" << #__VA_ARGS__ << "]: [", DBG(__VA_ARGS__)
#else
	#define dbg(...) 0
#endif

// FILE I/O
void setIn(str s) { freopen(s.c_str(),"r",stdin); }
void setOut(str s) { freopen(s.c_str(),"w",stdout); }
void unsyncIO() { ios_base::sync_with_stdio(0); cin.tie(0); }
void setIO(str s = "") {
	unsyncIO();
	// cin.exceptions(cin.failbit);
	// throws exception when do smth illegal
	// ex. try to read letter into int
	if (sz(s)) { setIn(s+".in"), setOut(s+".out"); } // for USACO
}

using ul = uint64_t;
typedef vector<vector<ul>> Mat;
const ul BIG = 1ULL<<63;

ul ADD(ul a, ul b) {
	if (a == BIG || b == BIG) return BIG;
	assert(a < BIG && b < BIG);
	return min(a+b,BIG);
}

int G,N,M;
Mat dp[1000], done[1000], ID;
vi sing[1000];
vpi lef[1000], rig[1000];

int make(int a, vi b) {
	if (a == -1) {
		assert(sz(b) > 1);
		a = G++;
	}
	dbg(sz(b));
	if (sz(b) == 1) {
		sing[b[0]].pb(a);
	} else {
		assert(sz(b) == 2);
		//dbg("NOT ONE",sz(b));
		lef[b[0]].pb({b[1],a});
		rig[b[1]].pb({b[0],a});
	}
	return a;
}

int compress(vi v) {
	if (sz(v) == 1) return v[0];
	return make(-1,{compress(vi(all(v)-1)),v.bk});
}

map<vi,int> state;
vector<vi> rstate;
int co = 0;

bool endsWith(vi a, vi b) {
	return sz(a) >= sz(b) && vi(end(a)-sz(b),end(a)) == b;
}

int main() {
	// dbg(BIG,2*BIG);
	setIO();
	re(G,N,M);
	int _G = G;
	F0R(i,N) {
		int a,k; re(a,k); vi b(k); re(b);
		if (k == 1) make(a,b); // OK
		else {
			int x = compress(vi(all(b)-1));
			make(a,{x,b.bk});
		}
	}
	state[{}] = 0;
	vector<vi> ban;
	F0R(i,M) {
		int L; re(L);
		vi c(L); re(c);
		F0R(j,L+1) {
			vi pref = vi(begin(c),begin(c)+j);
			state[pref] = 0;
		}
		ban.pb(c);
	}
	trav(t,state) {
		bool bad = 0;
		trav(u,ban) if (endsWith(t.f,u)) bad = 1;
		if (bad) {
			t.s = -1;
			continue;
		}
		t.s = co++;
		rstate.pb(t.f);
	}
	dbg(rstate);
	assert(co);
	ID.assign(co,vector<ul>(co,BIG));
	F0R(i,G) {
		dp[i] = ID; // OK
		done[i] = vector<vector<ul>>(co,vector<ul>(co,0));
	}
	typedef pair<ul,array<int,3>> T;
	priority_queue<T,vector<T>,greater<T>> pq;
	auto ad = [&](int i, int j, int k, ul val) {
		if (ckmin(dp[i][j][k],val)) pq.push({dp[i][j][k],{i,j,k}});
	};
	auto process = [&](int x, int b, int c) {
		assert(!done[x][b][c]); done[x][b][c] = 1;
		ul v = dp[x][b][c];
		trav(t,sing[x]) ad(t,b,c,v);
		trav(t,lef[x]) {
			F0R(d,co) if (done[t.f][c][d])
				ad(t.s,b,d,ADD(v,dp[t.f][c][d]));
		}
		trav(t,rig[x]) {
			F0R(a,co) if (done[t.f][a][b])
				ad(t.s,a,c,ADD(dp[t.f][a][b],v));
		}
	};
	auto gen = [](int ind) {
		Mat res = ID;
		F0R(i,sz(rstate)) {
			vi v = rstate[i]; v.pb(ind);
			while (!state.count(v)) v.erase(begin(v));
			int label = state[v]; if (label == -1) continue;
			res[i][label] = 1;
		}
		return res;
	};
	F0R(i,2) dp[i] = gen(i);
	F0R(i,2) F0R(j,co) F0R(k,co) if (dp[i][j][k] != BIG) process(i,j,k);
	while (sz(pq)) {
		auto a = pq.top(); pq.pop();
		if (a.f > dp[a.s[0]][a.s[1]][a.s[2]]) continue;
		process(a.s[0],a.s[1],a.s[2]);
	}
	FOR(i,2,_G) {
		ul mn = BIG; F0R(j,co) ckmin(mn,dp[i][0][j]);
		if (mn == BIG) ps("YES");
		else ps("NO",mn);
	}
	//dbg(state);
	// you should actually read the stuff at the bottom
}

/* stuff you should look for
	* int overflow, array bounds
	* special cases (n=1?)
	* do smth instead of nothing and stay organized
	* WRITE STUFF DOWN
*/

/**
    BOI 2020 : Virus
*/
#include<bits/stdc++.h>
using namespace std;
struct Aho_Corasick {
    static const int ALPHA = 2;
    static const int nax = 128;
    /**
        add string and build Aho-Corasick DFA
        status :
        You are given some strings...
        https://codeforces.com/contest/1202/problem/E
        -> This just ensures that DFA is correct, but not accepting state
        More to test...
        Indie Album, codeforces
        /// binary string searching :P
        BOI 2019 Virus
    */

    int nxt[nax][ALPHA] = {};
    int link[nax] = {};
    int val[nax] = {};
    int top = 0; /// would it cause UB again :P, be careful with = {}

    void add_string (string const &s) {
        int v = 0;
        for (char ch : s) {
            int c = ch - 'a';

            if (nxt[v][c]) {
                v = nxt[v][c];
            } else {
                nxt[v][c] = ++ top;
                v = top;
            }
        }
        ++ val[v];
    }

    void add_string (vector <int> const &a) {
        int v = 0;
        for (int c : a) {
            if (nxt[v][c])
                v = nxt[v][c];
            else {
                nxt[v][c] = ++ top;
                v = top;
            }
        }
        ++ val[v];
    }

    void get_link () {
        // build DFA
        static int q[nax];
        int topQ = 0;
        q[topQ ++] = 0;
        for (int _i = 0 ; _i < topQ ; ++ _i) {
            int cur = q[_i];

            val[cur] += val[link[cur]];

            for (int i = 0 ; i < ALPHA ; ++ i) {
                if (nxt[cur][i]) {
                    link[nxt[cur][i]] = cur ? nxt[link[cur]][i] : 0;
                    q[topQ ++] = nxt[cur][i];
                } else {
                    nxt[cur][i] = nxt[link[cur]][i];
                }
            }
        }
    }
};
using ull = uint64_t;
const ull INF = 1ull << 63;

struct node_t {
    ull val;
    int from;
    int st;
    int en;
    node_t () : val(), from(), st(), en() {}
    node_t (ull val, int from, int st, int en) : val(val), from(from), st(st), en(en) {}

    bool operator <(const node_t &other) const {
        return val > other.val;
    }
};

priority_queue<node_t> pq;
Aho_Corasick dfa;
int n, g, m;
vector <int> e[228];
vector <pair <int, int>> el[228];
vector <pair <int, int>> er[228];

ull dp[220][220][220];
bool used[220][220][220];

int main () {
    scanf("%d %d %d", &g, &n, &m);

    int tot = g;
    for (int __ = 1 ; __ <= n; ++ __) {
        static int c[150];
        int a, k;
        scanf("%d %d", &a, &k);
        for (int i = 1 ; i <= k; ++ i) {
            scanf("%d", c + i);
        }

        if (k == 1) {
           e[c[1]].push_back(a);
        } else {
            int cur_a = a;
            for (int i = 1 ; i <= k - 2 ; ++ i) {
                int new_gene = ++ tot;
                er[c[i]].emplace_back(cur_a, new_gene);
                el[new_gene].emplace_back(cur_a, c[i]);
                cur_a = new_gene;
            }
            er[c[k - 1]].emplace_back(cur_a, c[k]);
            el[c[k]].emplace_back(cur_a, c[k - 1]);
        }
    }

    for (int __ = 1 ; __ <= m ; ++ __ ) {
        int len;
        scanf("%d", &len);
        vector <int> input(len);
        for (int &i : input)
            scanf("%d", &i);
        dfa.add_string(input);
    }

    dfa.get_link();

    for (int i = 0 ; i < 210 ; ++ i)
    for (int j = 0 ; j < 210 ; ++ j)
    for (int k = 0 ; k < 210 ; ++ k)
        dp[i][j][k] = INF;

    for (int to_add = 0 ; to_add < 2 ; ++ to_add) {
        for (int st = 0 ; st <= dfa.top ; ++ st) {
            if (dfa.val[st] == 0 && dfa.val[dfa.nxt[st][to_add]] == 0) {
                dp[to_add][st][dfa.nxt[st][to_add]] = 1;
                pq.emplace(1, to_add, st, dfa.nxt[st][to_add]);
            }
        }
    }

    while (!pq.empty()) {
        auto [val, node, st, en] = pq.top();
        pq.pop();
        if (used[node][st][en]) continue;
        used[node][st][en] = true;
        for (int to : e[node])
            if (dp[to][st][en] > val) {
                dp[to][st][en] = val;
                pq.emplace(val, to, st, en);
            }

        for (auto [x, y] : er[node]) {
            for (int new_ed = 0 ; new_ed <= dfa.top; ++ new_ed) {
                if (dp[x][st][new_ed] > val + dp[y][en][new_ed]) {
                    dp[x][st][new_ed] = val + dp[y][en][new_ed];
                    pq.emplace(dp[x][st][new_ed], x, st, new_ed);
                }
            }
        }

        for (auto [x, y] : el[node]) {
            for (int new_st = 0; new_st <= dfa.top; ++ new_st) {
                if (dp[x][new_st][en] > dp[y][new_st][st] + val) {
                    dp[x][new_st][en] = dp[y][new_st][st] + val;
                    pq.emplace(dp[x][new_st][en], x, new_st, en);
                }
            }
        }
    }

    for (int i = 2 ; i < g ; ++ i) {
        ull ans = INF;
        for (int j = 0 ; j <= dfa.top; ++ j) {
            ans = min(ans, dp[i][0][j]);
        }
        if (ans == INF) {
            puts("YES");
        } else {
            printf("NO %llu\n", ans);
        }
    }
}

/**
    BOI 2020 : Virus
*/
#include<bits/stdc++.h>
using namespace std;
struct Aho_Corasick {
    static const int ALPHA = 2;
    static const int nax = 128;
    /**
        add string and build Aho-Corasick DFA
        status :
        You are given some strings...
        https://codeforces.com/contest/1202/problem/E
        -> This just ensures that DFA is correct, but not accepting state
        More to test...
        Indie Album, codeforces
    */

    int nxt[nax][ALPHA] = {};
    int link[nax] = {};
    int val[nax] = {};
    int top = 0; /// would it cause UB again :P, be careful with = {}

    Aho_Corasick () {
        memset(nxt, 0, sizeof(nxt));
        memset(link, 0, sizeof(link));
        memset(val, 0, sizeof(val));
    }

    void add_string (string const &s) {
        int v = 0;
        for (char ch : s) {
            int c = ch - 'a';

            if (nxt[v][c]) {
                v = nxt[v][c];
            } else {
                nxt[v][c] = ++ top;
                v = top;
            }
        }
        ++ val[v];
    }

    void add_string (vector <int> const &a) {
        int v = 0;
        for (int c : a) {
            if (nxt[v][c])
                v = nxt[v][c];
            else {
                nxt[v][c] = ++ top;
                v = top;
            }
        }
        ++ val[v];
    }

    void get_link () {
        // build DFA
        static int q[nax];
        int topQ = 0;
        q[topQ ++] = 0;
        for (int _i = 0 ; _i < topQ ; ++ _i) {
            int cur = q[_i];

            val[cur] += val[link[cur]];

            for (int i = 0 ; i < ALPHA ; ++ i) {
                if (nxt[cur][i]) {
                    link[nxt[cur][i]] = cur ? nxt[link[cur]][i] : 0;
                    q[topQ ++] = nxt[cur][i];
                } else {
                    nxt[cur][i] = nxt[link[cur]][i];
                }
            }
        }
    }
};
using ull = uint64_t;
const ull INF = 1ull << 63;

struct node_t {
    ull val;
    int from;
    int st;
    int en;
    node_t () : val(), from(), st(), en() {}
    node_t (ull val, int from, int st, int en) : val(val), from(from), st(st), en(en) {}

    bool operator <(const node_t &other) const {
        return val > other.val;
    }
};

priority_queue<node_t> pq;
Aho_Corasick dfa;
int n, g, m;
vector <int> e[228];
vector <pair <int, int>> el[228];
vector <pair <int, int>> er[228];

ull dp[220][220][220];
bool used[220][220][220];

//// so hard to implement. :V

int main () {
    scanf("%d %d %d", &g, &n, &m);

    int tot = 100;
    for (int __ = 1 ; __ <= n; ++ __) {
        static int c[150];
        int a, k;
        scanf("%d %d", &a, &k);
        for (int i = 1 ; i <= k; ++ i) {
            scanf("%d", c + i);
        }

        if (k == 1) {
           e[c[1]].push_back(a);
        } else {
            int cur_a = a;
            for (int i = 1 ; i <= k - 2 ; ++ i) {
                int new_gene = ++ tot;
                er[c[i]].emplace_back(cur_a, new_gene);
                el[new_gene].emplace_back(cur_a, c[i]);
                cur_a = new_gene;
            }
                /// cur_a -> c[k - 1], c[k]
            er[c[k - 1]].emplace_back(cur_a, c[k]);
            el[c[k]].emplace_back(cur_a, c[k - 1]);
        }
    }

 ///   fprintf(stderr, "PASSED HERE\n");

    for (int __ = 1 ; __ <= m ; ++ __ ) {
        int len;
        scanf("%d", &len);
        vector <int> input(len);
        for (int &i : input)
            scanf("%d", &i);
        dfa.add_string(input);
    }

    dfa.get_link();

    for (int i = 0 ; i < 210 ; ++ i)
    for (int j = 0 ; j < 210 ; ++ j)
    for (int k = 0 ; k < 210 ; ++ k)
        dp[i][j][k] = INF;

    for (int to_add = 0 ; to_add < 2 ; ++ to_add) {
        for (int st = 0 ; st <= dfa.top ; ++ st) {
            if (dfa.val[st] == 0 && dfa.val[dfa.nxt[st][to_add]] == 0) {
                dp[to_add][st][dfa.nxt[st][to_add]] = 1;
                pq.emplace(1, to_add, st, dfa.nxt[st][to_add]);
            }
        }
    }

    while (!pq.empty()) {
        auto [val, node, st, en] = pq.top();
        pq.pop();
        if (used[node][st][en]) continue;
        used[node][st][en] = true;
        for (int to : e[node])
            if (dp[to][st][en] > val) {
                dp[to][st][en] = val;
                pq.emplace(val, to, st, en);
            }

        for (auto [x, y] : er[node]) {
            for (int new_ed = 0 ; new_ed <= dfa.top; ++ new_ed) {
                if (dp[x][st][new_ed] > val + dp[y][en][new_ed]) {
                    dp[x][st][new_ed] = val + dp[y][en][new_ed];
                    pq.emplace(dp[x][st][new_ed], x, st, new_ed);
                }
            }
        }

        for (auto [x, y] : el[node]) {
            for (int new_st = 0; new_st <= dfa.top; ++ new_st) {
                if (dp[x][new_st][en] > dp[y][new_st][st] + val) {
                    dp[x][new_st][en] = dp[y][new_st][st] + val;
                    pq.emplace(dp[x][new_st][en], x, new_st, en);
                }
            }
        }
    }

    for (int i = 2 ; i < g ; ++ i) {
        ull ans = INF;

        for (int j = 0 ; j <= dfa.top; ++ j) {
            if (dfa.val[j] == 0)
            ans = min(ans, dp[i][0][j]);
        }

        if (ans == INF) {
            puts("YES");
        } else {
            printf("NO %llu\n", ans);
        }
    }

}

/**
35 66 0
2 2 1 1
2 1 2
3 2 2 2
3 1 3
4 2 3 3
4 1 4
5 2 4 4
5 1 5
6 2 5 5
6 1 6
7 2 6 6
7 1 7
8 2 7 7
8 1 8
9 2 8 8
9 1 9
10 2 9 9
10 1 10
11 2 10 10
11 1 11
12 2 11 11
12 1 12
13 2 12 12
13 1 13
14 2 13 13
14 1 14
15 2 14 14
15 1 15
16 2 15 15
16 1 16
17 2 16 16
17 1 17
18 2 17 17
18 1 18
19 2 18 18
19 1 19
20 2 19 19
20 1 20
21 2 20 20
21 1 21
22 2 21 21
22 1 22
23 2 22 22
23 1 23
24 2 23 23
24 1 24
25 2 24 24
25 1 25
26 2 25 25
26 1 26
27 2 26 26
27 1 27
28 2 27 27
28 1 28
29 2 28 28
29 1 29
30 2 29 29
30 1 30
31 2 30 30
31 1 31
32 2 31 31
32 1 32
33 2 32 32
33 1 33
34 2 33 33
34 1 34
*/

#include<cstdio>
#include<algorithm>
#include<vector>
#include<queue>
#include<string>
using namespace std;
typedef unsigned long long ull;
ull D[60][210][60];
int B[210], E[210], Z[210], w[210], Bad[210], ED[210];
ull Res[210], INF = (1ll<<62);
int K, n, m, cnt, ccc;
struct AA{
    string z;
    bool operator <(const AA &p)const{
        return z.size()<p.z.size();
    }
};
struct Trie{
    int Ch[2];
    int p, fail;
    int c;
}T[210];
void Aho(){
    int Q[210]={0}, head=0,tail=0;
    Q[++tail] = 1;
    int i, j;
    while(head < tail){
        int x = Q[++head];
        if(x==1)T[x].fail=1;
        else if(T[x].p==1)T[x].fail=1;
        else T[x].fail = T[T[T[x].p].fail].Ch[T[x].c];
        for(i=0;i<2;i++){
            if(T[x].Ch[i]) Q[++tail] = T[x].Ch[i];
        }
        for(i=0;i<2;i++){
            if(T[x].Ch[i]) continue;
            int t = T[x].fail;
            T[x].Ch[i] = T[t].Ch[i];
            if(!T[x].Ch[i])T[x].Ch[i]=1;
        }
    }
    for(i=1;i<=ccc;i++){
        for(j=0;j<2;j++){
            if(Bad[i] || Bad[T[i].Ch[j]])T[i].Ch[j] = 0;
            if(T[i].Ch[j]){
                //printf("%d %d %d\n",i,j,T[i].Ch[j]);
            }
        }
    }
}
struct BB{
    int x, y, z;
    ull d;
    bool operator <(const BB &p)const{
        return d>p.d;
    }
};
priority_queue<BB>PQ;
void Put(int i, int j, int k, ull d){
    if(D[i][j][k]<=d)return;
    if(Bad[i]||Bad[k])return;
    D[i][j][k]=d;
    PQ.push({i,j,k,d});
}
int main(){
    int i, j, k;
    scanf("%d%d%d",&K,&n,&m);
    for(i=1;i<=n;i++){
        int a, c;
        scanf("%d%d",&a,&c);
        Z[i] = a;
        B[i] = ++cnt;
        w[cnt] = 0;
        for(j=0;j<c;j++){
            cnt++;
            scanf("%d",&w[cnt]);
        }
        E[i]=cnt;
        ED[cnt] = i;
    }
    vector<AA>VV;
    for(i=1;i<=m;i++){
        int a, c;
        scanf("%d",&c);
        string s="";
        while(c){
            scanf("%d",&a);
            if(a)s+='1';
            else s+='0';
            c--;
        }
        VV.push_back({s});
    }
    sort(VV.begin(),VV.end());
    vector<string>V;
    for(i=0;i<m;i++){
        for(j=0;j<i;j++){
            if(VV[i].z.find(VV[j].z)!=string::npos)break;
        }
        if(j==i)V.push_back(VV[i].z);
    }
    ccc = 1;
    for(auto &t : V){
        int cur = 1;
        for(auto &ch : t){
            int c = ch-'0';
            if(!T[cur].Ch[c]){
                T[cur].Ch[c]=++ccc;
                T[ccc].p = cur;
                T[ccc].c = c;
            }
            cur = T[cur].Ch[c];
        }
        Bad[cur] = 1;
    }
    Aho();
    for(i=1;i<=ccc;i++){
        for(j=1;j<=cnt;j++){
            for(k=1;k<=ccc;k++){
                D[i][j][k]=INF;
            }
        }
    }
    for(i=1;i<=n;i++){
        for(j=1;j<=ccc;j++){
            if(Bad[j])continue;
            Put(j,B[i],j,0);
        }
    }
    while(!PQ.empty()){
        BB t = PQ.top();
        PQ.pop();
        if(D[t.x][t.y][t.z]!=t.d)continue;
        if(ED[t.y]){
            int x = Z[ED[t.y]];
            for(i=1;i<=cnt;i++){
                if(w[i] == x){
                    for(j=1;j<=ccc;j++){
                        if(Bad[j])continue;
                        Put(j, i, t.z, D[j][i-1][t.x] + t.d);
                    }
                }
            }
        }
        else{
            int x = w[t.y+1];
            if(x==0 || x==1){
                Put(t.x, t.y+1, T[t.z].Ch[x], t.d+1);
            }
            else{
                for(i=1;i<=n;i++){
                    if(Z[i]!=x)continue;
                    for(j=1;j<=ccc;j++){
                        Put(t.x, t.y+1, j, t.d+D[t.z][E[i]][j]);
                    }
                }
            }
        }
    }
    for(i=1;i<=K;i++)Res[i]=INF;
    for(i=1;i<=n;i++){
        for(j=1;j<=ccc;j++){
            if(Bad[j])continue;
            if(Res[Z[i]] > D[1][E[i]][j]){
                Res[Z[i]] = D[1][E[i]][j];
            }
        }
    }
    for(i=2;i<K;i++){
        if(Res[i]>=INF)puts("YES");
        else printf("NO %llu\n",Res[i]);
    }
}

#include <bits/stdc++.h>

using namespace std;

using ll = int64_t;
//using ll = long long;
using ull = uint64_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using f64 = double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ld = long double;

//#ifndef ONLINE_JUDGE
#define FWRITE
//#endif

namespace io
{

#ifndef FWRITE
#include <unistd.h>
	auto unistd_read = read;
	auto unistd_write = write;
#endif
	const int BUFSIZE = 1 << 20;

	int isize, osize;
	char ibuf[BUFSIZE + 10], obuf[BUFSIZE + 10];
	char* is, * it, * os = obuf, * ot = obuf + BUFSIZE;

	char getchar()
	{
		if (is == it)
		{
			is = ibuf;
#ifdef FWRITE
			it = ibuf + fread(ibuf, 1, BUFSIZE, stdin);
#else
			it = ibuf + unistd_read(STDIN_FILENO, ibuf, BUFSIZE);
#endif
			if (is == it) return EOF;
		}
		return *is++;
	}

	char getalpha()
	{
		char c = getchar();
		while (!isalpha(c)) c = getchar();
		return c;
	}

	void putchar(char c)
	{
		*os++ = c;
		if (os == ot)
		{
#ifdef FWRITE
			fwrite(obuf, 1, BUFSIZE, stdout);
#else
			unistd_write(STDOUT_FILENO, obuf, BUFSIZE);
#endif
			os = obuf;
		}
	}

	int inp() {
		int x = 0, f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return -1;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return f ? -x : x;
	}

	ll inp_ll() {
		ll x = 0; int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
			if (ch == '-') f = 1;
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return f ? -x : x;
	}

	template<class T>
	bool read(T& x)
	{
		x = 0;
		int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return 0;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		if (f) x = -x;
		return 1;
	}

	bool read(char* s)
	{
		char* t = s;
		char ch = getchar();
		for (; ch == ' ' || ch == '\n'; ch = getchar());
		for (; ch != ' ' && ch != '\n' && ch != EOF; ch = getchar())
			*t++ = ch;
		*t = 0;
		return s != t;
	}

	template<class T, class... Args>
	bool read(T& x, Args&... args)
	{
		return read(x) && read(args...);
	}

	template<class T>
	bool readln(T& x)
	{
		x = 0;
		int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return 0;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		if (f) x = -x;
		for (; ch != '\n' && ch != EOF; ch = getchar());
		return 1;
	}

	bool readln(char* s)
	{
		char* t = s;
		while (1)
		{
			char ch = getchar();
			if (ch == '\n' || ch == EOF) break;
			*t++ = ch;
		}
		*t = 0;
		return s != t;
	}

	template<class T, class... Args>
	bool readln(T& x, Args&... args)
	{
		return read(x) && readln(args...);
	}

	template<class T>
	void write(T x)
	{
		static char s[22];
		static char* it = s + 20;
		static char* end = s + 20;

		if (x < 0)
		{
			putchar('-');
			x = -x;
		}

		do
		{
			*--it = x % 10 + '0';
			x /= 10;
		} while (x);
		/*
		if (!x)
			*-- it = '0';
		while (x)
		{
			*-- it = x%10+'0';
			x /= 10;
		}
		*/
		for (; it < end; ++it)
			putchar(*it);
	}

	void write(const char* s)
	{
		for (; *s; ++s) putchar(*s);
	}

	template<>
	void write(char* s)
	{
		write((const char*)s);
	}

	template<>
	void write(char c)
	{
		putchar(c);
	}

	template<class T, class... Args>
	void write(T x, Args... args)
	{
		write(x);
		write(args...);
	}

	void writeln()
	{
		putchar('\n');
	}

	template<class T, class... Args>
	void writeln(T x, Args... args)
	{
		write(x);
		writeln(args...);
	}

	template<class Iterator>
	bool input(Iterator st, Iterator ed)
	{
		for (; st != ed; ++st)
		{
			if (!read(*st)) return false;
		}
		return true;
	}

	template<class T>
	bool input(T& a)
	{
		return input(a.begin(), a.end());
	}

	template<class Iterator>
	void print(Iterator st, Iterator ed, const char* c = " ")
	{
		int flag = 0;
		for (; st != ed; ++st)
		{
			if (flag) write(c);
			flag = 1;
			write(*st);
		}
		writeln();
	}

	template<class T>
	void print(const T& a, const char* c = " ")
	{
		print(a.begin(), a.end(), c);
	}

	struct ender
	{
		~ender()
		{
			if (os != obuf)
#ifdef FWRITE
				fwrite(obuf, 1, os - obuf, stdout);
#else
				unistd_write(STDOUT_FILENO, obuf, os - obuf);
#endif
		}
	}__ender;

}

int64_t power(int64_t a, int64_t b, int64_t p)
{
	if (!b) return 1;
	int64_t t = power(a, b >> 1, p);
	t = t * t % p;
	if (b & 1) t = t * a % p;
	return t;
}

pll exgcd(ll a, ll b)
{
	if (b == 0) return { 1, 0 };
	//auto [x, y] = exgcd(b, a % b);
	auto e = exgcd(b, a % b);
	ll x = e.first;
	ll y = e.second;
	return { y, x - a / b * y };
}

//mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
mt19937 rd(chrono::steady_clock::now().time_since_epoch().count());
//mt19937 rd(678);

using namespace io;

template<class T>
inline bool freshmin(T& a, const T& b)
{
	if (a > b)
	{
		a = b;
		return true;
	}
	else
		return false;
}

template<class T>
inline bool freshmax(T& a, const T& b)
{
	if (a < b)
	{
		a = b;
		return true;
	}
	else
		return false;
}

template<class T>
auto arr(int n = 0)
{
	return vector<T>(n);
}

template<class T, class... Args>
auto arr(int n, Args... args)
{
	return vector<decltype(arr<T>(args...))>(n, arr<T>(args...));
}

int dx[] = { -1, 1, 0, 0, -1, -1, 1, 1 };
int dy[] = { 0, 0, -1, 1, -1, 1, -1, 1 };

template<class T>
T det(T x1, T y1, T x2, T y2, T x3, T y3)
{
	return x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3;
}
/*
template<class T>
T dis(T x1, T y1, T x2, T y2)
{
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}
*/

#ifdef ONLINE_JUDGE
const int OJ = 1;
#else
const int OJ = 0;
#endif
/*
void init()
{
}
*/
namespace ACAutomaton
{
	static const int MAXN = 40010; // number of nodes in AC automaton
	static const int MAXM = 2; // cardinal of alphabet

	int tot;

	struct node
	{
		node* next[MAXM];
		node* fail;
		int val;
	};

	node tree[MAXN];
	node* root;

	node* new_node()
	{
		node* it = &tree[++tot];
		for (int i = 0; i < MAXM; ++i) it->next[i] = 0;
		it->fail = 0;
		it->val = 0;
		return it;
	}

	void init()
	{
		tot = 0;
		root = new_node();
	}

	node* add(const vector<int>& s)
	{
		node* it = root;
		for (auto c : s)
		{
			int x = c;
			if (!it->next[x]) it->next[x] = new_node();
			it = it->next[x];
		}
		it->val = 1;
		//printf("%x\n", it);
		return it;
	}

	void build()
	{
		root->fail = root;
		queue<node*> Q;
		for (int i = 0; i < MAXM; ++i)
			if (root->next[i])
			{
				root->next[i]->fail = root;
				Q.push(root->next[i]);
			}
			else
				root->next[i] = root;
		while (!Q.empty())
		{
			node* it = Q.front();
			Q.pop();
			for (int i = 0; i < MAXM; ++i)
			{
				if (!it->next[i])
					it->next[i] = it->fail->next[i];
				else
				{
					it->next[i]->fail = it->fail->next[i];
					it->next[i]->val |= it->next[i]->fail->val;
					Q.push(it->next[i]);
				}
			}
		}
	}
}

void solve()
{
	int G, N, M;
	read(G, N, M);
	int nG = G;
	auto relations = arr<vector<pair<int, vector<int>>>>(nG);
	for (int i = 0; i < N; ++i)
	{
		int a, k;
		read(a, k);
		auto b = arr<int>(k);
		input(b);
		if (k <= 2)
		{
			auto prod = make_pair(a, b);
			for (auto x : b)
				relations[x].push_back(prod);
		}
		else
		{
			int cur = a;
			for (int j = 0; j < k - 2; ++j)
			{
				nG++;
				relations.resize(nG);
				auto prod = make_pair(cur, vector<int>{ b[j], nG - 1 });
				relations[b[j]].push_back(prod);
				relations[nG - 1].push_back(prod);
				cur = nG - 1;
			}
			auto prod = make_pair(cur, vector<int>{ b[k - 2], b[k - 1] });
			relations[b[k - 2]].push_back(prod);
			relations[b[k - 1]].push_back(prod);
		}
	}
	using namespace ACAutomaton;
	init();
	for (int i = 0; i < M; ++i)
	{
		int k;
		read(k);
		auto b = arr<int>(k);
		input(b);
		add(b);
	}
	build();
	auto f = arr<ull>(nG + 1, tot + 1, tot + 1);
	const ull INF = 1ULL << 63;
	for (int a = 0; a < nG; ++a)
		for (int x = 1; x <= tot; ++x)
			for (int y = 1; y <= tot; ++y)
				f[a][x][y] = INF;
	struct point
	{
		int a, x, y;
		ull val;
		bool operator < (const point& rhs) const
		{
			return val > rhs.val;
		}
	};
	priority_queue<point> q;
	auto go = [&](int a, int x, int y, ull d)
	{
		if (freshmin(f[a][x][y], d))
		{
			q.push({ a, x, y, d });
		}
	};
	for (int a = 0; a < 2; ++a)
		for (int x = 1; x <= tot; ++x)
			if (!tree[x].val && !tree[x].next[a]->val)
				go(a, x, tree[x].next[a] - tree, 1);
	while (!q.empty())
	{
		auto [s, x, y, d] = q.top();
		q.pop();
		if (f[s][x][y] != d) continue;
		for (auto &[a, b] : relations[s])
		{
			if (b.size() == 1)
				go(a, x, y, f[s][x][y]);
			else
			{
				assert(b.size() == 2);
				if (b[0] == s)
				{
					for (int z = 1; z <= tot; ++z) if (!tree[z].val)
						go(a, x, z, f[b[0]][x][y] + f[b[1]][y][z]);
				}
				if (b[1] == s)
				{
					for (int z = 1; z <= tot; ++z) if (!tree[z].val)
						go(a, z, y, f[b[0]][z][x] + f[b[1]][x][y]);
				}
			}
		}
	}
	for (int a = 2; a < G; ++a)
	{
		ull res = INF;
		for (int y = 1; y <= tot; ++y) if (!tree[y].val)
			freshmin(res, f[a][1][y]);
		if (res == INF)
			writeln("YES");
		else
			writeln("NO ", ll(res));
	}
}

int main()
{
	if (!OJ)
	{
		freopen("try.in", "r", stdin);
		freopen("try.out", "w", stdout);
	}

	int T = 1;
	//read(T);
	//init();
	for (int test = 1; test <= T; ++test)
	{
		//write("Case #", test, ": ");
		solve();
	}

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

using ll = int64_t;
//using ll = long long;
using ull = uint64_t;
using i32 = int32_t;
using u32 = uint32_t;
using i64 = int64_t;
using u64 = uint64_t;
using f64 = double;
using pii = pair<int, int>;
using pll = pair<ll, ll>;
using ld = double;

#define X first
#define Y second

//#ifndef ONLINE_JUDGE
#define FWRITE
//#endif

namespace io
{

#ifndef FWRITE
#include <unistd.h>
	auto unistd_read = read;
	auto unistd_write = write;
#endif
	const int BUFSIZE = 1 << 20;

	int isize, osize;
	char ibuf[BUFSIZE + 10], obuf[BUFSIZE + 10];
	char* is, * it, * os = obuf, * ot = obuf + BUFSIZE;

	char getchar()
	{
		if (is == it)
		{
			is = ibuf;
#ifdef FWRITE
			it = ibuf + fread(ibuf, 1, BUFSIZE, stdin);
#else
			it = ibuf + unistd_read(STDIN_FILENO, ibuf, BUFSIZE);
#endif
			if (is == it) return EOF;
		}
		return *is++;
	}

	char getalpha()
	{
		char c = getchar();
		while (!isalpha(c)) c = getchar();
		return c;
	}

	void putchar(char c)
	{
		*os++ = c;
		if (os == ot)
		{
#ifdef FWRITE
			fwrite(obuf, 1, BUFSIZE, stdout);
#else
			unistd_write(STDOUT_FILENO, obuf, BUFSIZE);
#endif
			os = obuf;
		}
	}

	int inp() {
		int x = 0, f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return -1;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return f ? -x : x;
	}

	ll inp_ll() {
		ll x = 0; int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
			if (ch == '-') f = 1;
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		return f ? -x : x;
	}

	template<class T>
	bool read(T& x)
	{
		x = 0;
		int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return 0;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		if (f) x = -x;
		return 1;
	}

	bool read(char* s)
	{
		char* t = s;
		char ch = getchar();
		for (; ch == ' ' || ch == '\n'; ch = getchar());
		for (; ch != ' ' && ch != '\n' && ch != EOF; ch = getchar())
			*t++ = ch;
		*t = 0;
		return s != t;
	}

	template<class T, class... Args>
	bool read(T& x, Args&... args)
	{
		return read(x) && read(args...);
	}

	template<class T>
	bool readln(T& x)
	{
		x = 0;
		int f = 0; char ch;
		for (ch = getchar(); !isdigit(ch); ch = getchar())
		{
			if (ch == EOF) return 0;
			if (ch == '-') f = 1;
		}
		for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
		if (f) x = -x;
		for (; ch != '\n' && ch != EOF; ch = getchar());
		return 1;
	}

	bool readln(char* s)
	{
		char* t = s;
		while (1)
		{
			char ch = getchar();
			if (ch == '\n' || ch == EOF) break;
			*t++ = ch;
		}
		*t = 0;
		return s != t;
	}

	template<class T, class... Args>
	bool readln(T& x, Args&... args)
	{
		return read(x) && readln(args...);
	}

	template<class T>
	void write(T x)
	{
		static char s[22];
		static char* it = s + 20;
		static char* end = s + 20;

		if (x < 0)
		{
			putchar('-');
			x = -x;
		}

		do
		{
			*--it = x % 10 + '0';
			x /= 10;
		} while (x);
		/*
		if (!x)
			*-- it = '0';
		while (x)
		{
			*-- it = x%10+'0';
			x /= 10;
		}
		*/
		for (; it < end; ++it)
			putchar(*it);
	}

	void write(const char* s)
	{
		for (; *s; ++s) putchar(*s);
	}

	template<>
	void write(char* s)
	{
		write((const char*)s);
	}

	template<>
	void write(char c)
	{
		putchar(c);
	}

	template<class T, class... Args>
	void write(T x, Args... args)
	{
		write(x);
		write(args...);
	}

	void writeln()
	{
		putchar('\n');
	}

	template<class T, class... Args>
	void writeln(T x, Args... args)
	{
		write(x);
		writeln(args...);
	}

	template<class Iterator>
	bool input(Iterator st, Iterator ed)
	{
		for (; st != ed; ++st)
		{
			if (!read(*st)) return false;
		}
		return true;
	}

	template<class T>
	bool input(T& a)
	{
		return input(a.begin(), a.end());
	}

	template<class Iterator>
	void print(Iterator st, Iterator ed, const char* c = " ")
	{
		int flag = 0;
		for (; st != ed; ++st)
		{
			if (flag) write(c);
			flag = 1;
			write(*st);
		}
		writeln();
	}

	template<class T>
	void print(const T& a, const char* c = " ")
	{
		print(a.begin(), a.end(), c);
	}

	struct ender
	{
		~ender()
		{
			if (os != obuf)
#ifdef FWRITE
				fwrite(obuf, 1, os - obuf, stdout);
#else
				unistd_write(STDOUT_FILENO, obuf, os - obuf);
#endif
		}
	}__ender;

}

int64_t power(int64_t a, int64_t b, int64_t p)
{
	if (!b) return 1;
	int64_t t = power(a, b >> 1, p);
	t = t * t % p;
	if (b & 1) t = t * a % p;
	return t;
}

pll exgcd(ll a, ll b)
{
	if (b == 0) return { 1, 0 };
	//auto [x, y] = exgcd(b, a % b);
	auto e = exgcd(b, a % b);
	ll x = e.first;
	ll y = e.second;
	return { y, x - a / b * y };
}

//mt19937_64 rd(chrono::steady_clock::now().time_since_epoch().count());
//mt19937 rd(chrono::steady_clock::now().time_since_epoch().count());
mt19937 rd(1);

using namespace io;

template<class T>
inline void freshmin(T& a, const T& b)
{
	if (a > b) a = b;
}

template<class T>
inline void freshmax(T& a, const T& b)
{
	if (a < b) a = b;
}

//const ll B = 31;
//const ll MOD = 1000000007;
//const int INF = 1000000010;
//const ll INFll = 4000000000000000000LL;
//const int MAXN = 600010;
//const int MAXK = 21;

int dx[] = { -1, 1, 0, 0, -1, -1, 1, 1 };
int dy[] = { 0, 0, -1, 1, -1, 1, -1, 1 };

template<class T>
T det(T x1, T y1, T x2, T y2, T x3, T y3)
{
	return x1 * y2 - x2 * y1 + x2 * y3 - x3 * y2 + x3 * y1 - x1 * y3;
}

template<class T>
T dis(T x1, T y1, T x2, T y2)
{
	return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

static const int MAXN = 40010; // number of nodes in AC automaton
static const int MAXM = 2; // cardinal of alphabet

int tot;

struct node
{
	node* next[MAXM];
	node* fail;
	int val;
};

node tree[MAXN];
node* root;

node* new_node()
{
	node* it = &tree[++tot];
	for (int i = 0; i < MAXM; ++i) it->next[i] = 0;
	it->fail = 0;
	it->val = 0;
	return it;
}

void init()
{
	tot = 0;
	root = new_node();
}

node* add(const vector<int>& s)
{
	node* it = root;
	for (auto c : s)
	{
		int x = c;
		if (!it->next[x]) it->next[x] = new_node();
		it = it->next[x];
	}
	it->val = 1;
	//printf("%x\n", it);
	return it;
}

void build()
{
	root->fail = root;
	queue<node*> Q;
	for (int i = 0; i < MAXM; ++i)
		if (root->next[i])
		{
			root->next[i]->fail = root;
			Q.push(root->next[i]);
		}
		else
			root->next[i] = root;
	while (!Q.empty())
	{
		node* it = Q.front();
		Q.pop();
		for (int i = 0; i < MAXM; ++i)
		{
			if (!it->next[i])
				it->next[i] = it->fail->next[i];
			else
			{
				it->next[i]->fail = it->fail->next[i];
				it->next[i]->val |= it->next[i]->fail->val;
				Q.push(it->next[i]);
			}
		}
	}
}

const ull INFull = 1ULL << 63;

ull f[111][55][55];

void solve()
{
	int G, N, M;
	read(G, N, M);
	vector<vector<vector<int>>> v(G);
	for (int i = 0; i < N; ++i)
	{
		int a, k;
		read(a, k);
		vector<int> b(k);
		input(b);
		v[a].push_back(b);
	}
	init();
	for (int i = 0; i < M; ++i)
	{
		int k;
		read(k);
		vector<int> b(k);
		input(b);
		add(b);
	}
	build();
	for (int a = 0; a < G; ++a)
		for (int x = 1; x <= tot; ++x)
			for (int y = 1; y <= tot; ++y)
				f[a][x][y] = INFull;
	for (int a = 0; a < 2; ++a)
		for (int x = 1; x <= tot; ++x) if (!tree[x].val && !tree[x].next[a]->val)
			f[a][x][tree[x].next[a] - tree] = 1;

	ll time_stamp = clock();
	while (1)
	{
		int flag = 0;

		for (int a = 0; a < G; ++a)
		{
			for (const auto& b : v[a])
			{
				static ull g[55][55], tmp[55][55];
				for (int x = 1; x <= tot; ++x)
					for (int y = 1; y <= tot; ++y) g[x][y] = INFull;
				for (int x = 1; x <= tot; ++x) if (!tree[x].val) g[x][x] = 0;

				for (const auto& c : b)
				{
					for (int x = 1; x <= tot; ++x)
						for (int y = 1; y <= tot; ++y) tmp[x][y] = g[x][y], g[x][y] = INFull;
					for (int x = 1; x <= tot; ++x) if (!tree[x].val)
						for (int y = 1; y <= tot; ++y) if (!tree[y].val && tmp[x][y] < INFull)
							for (int z = 1; z <= tot; ++z) if (!tree[z].val && f[c][y][z] < INFull)
							{
								if (g[x][z] > tmp[x][y] + f[c][y][z])
								{
									g[x][z] = tmp[x][y] + f[c][y][z];
								}
							}
				}

				for (int x = 1; x <= tot; ++x)
					for (int y = 1; y <= tot; ++y)
						if (f[a][x][y] > g[x][y])
						{
							flag = 1;
							f[a][x][y] = g[x][y];
						}
			}
		}

		if (flag == 0) break;
		if (clock() - time_stamp > 720000) break;
	}

	for (int a = 2; a < G; ++a)
	{
		ull res = INFull;
		for (int y = 1; y <= tot; ++y)
			if (f[a][1][y] < res)
			{
				res = f[a][1][y];
			}
		if (res == INFull)
			writeln("YES");
		else
			writeln("NO ", ll(res));
	}
}

int main()
{

	int T = 1;
	//read(T);
	//init();
	for (int test = 1; test <= T; ++test)
	{
		//write("Case #", test, ": ");
		solve();
	}

	return 0;
}

/*

Code for problem C by cookiedoth
Generated 23 Jul 2020 at 02.27 PM

──────▄▌▐▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▌
───▄▄██▌█░ВЕЗЁМ▄▀▀▀▄░ГУСЕЙ░░░░░░░
───████▌█▄███▀░◐░▄▀▀▀▄░░РАБОТЯГИ░
──██░░█▌█░░▄███▀░◐░░▄▀▀▀▄░░░░░░░
─██░░░█▌█░░░░▐░▄▀▀▀▌░░░░◐░▀███▄░
▄██████▌█▄███▀░◐░░░▌░░░░░▐░░░░░░
███████▌█░░░░▌░░░░░▌░░░░░▐░░░░░░
███████▌█▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▌
▀(@)▀▀▀▀▀▀▀(@)(@)▀▀▀▀▀▀▀▀▀▀▀▀▀(@)▀(@)

~_^
=_=
¯\_(ツ)_/¯

*/

#include <iostream>
#include <fstream>
#include <vector>
#include <set>
#include <map>
#include <bitset>
#include <algorithm>
#include <iomanip>
#include <cmath>
#include <ctime>
#include <functional>
#include <unordered_set>
#include <unordered_map>
#include <string>
#include <queue>
#include <deque>
#include <stack>
#include <complex>
#include <cassert>
#include <random>
#include <cstring>
#include <numeric>
#define ll long long
#define ull unsigned long long
#define ld long double
#define null NULL
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define debug(a) cerr << #a << " = " << a << endl
#define forn(i, n) for (int i = 0; i < n; ++i)
#define sz(a) (int)a.size()

using namespace std;

template<class T> int chkmax(T &a, T b) {
	if (b > a) {
		a = b;
		return 1;
	}
	return 0;
}

template<class T> int chkmin(T &a, T b) {
	if (b < a) {
		a = b;
		return 1;
	}
	return 0;
}

template<class iterator> void output(iterator begin, iterator end, ostream& out = cerr) {
	while (begin != end) {
		out << (*begin) << " ";
		begin++;
	}
	out << endl;
}

template<class T> void output(T x, ostream& out = cerr) {
	output(x.begin(), x.end(), out);
}

void fast_io() {
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
}

int G0, G, n, m;
vector<vector<int> > singleMut;
vector<vector<pair<int, int> > > doubleMut;

int newGene() {
	singleMut.push_back(vector<int> ());
	doubleMut.push_back(vector<pair<int, int> > ());
	return G++;
}

vector<vector<int> > C;

void read() {
	cin >> G0 >> n >> m;
	G = G0;
	singleMut.resize(G);
	doubleMut.resize(G);
	for (int i = 0; i < n; ++i) {
		int a, k;
		cin >> a >> k;
		if (k == 1) {
			int b;
			cin >> b;
			singleMut[a].push_back(b);
		} else {
			for (int j = 0; j < k - 2; ++j) {
				int a1 = newGene();
				int b;
				cin >> b;
				doubleMut[a].emplace_back(b, a1);
				a = a1;
			}
			int b1, b2;
			cin >> b1 >> b2;
			doubleMut[a].emplace_back(b1, b2);
		}
	}
	for (int i = 0; i < m; ++i) {
		int k;
		cin >> k;
		vector<int> cur(k);
		for (int j = 0; j < k; ++j) {
			cin >> cur[j];
		}
		C.push_back(cur);
	}
}

const int K = 2;
const int mx = 55;
const int maxG = 205;
int V, go[mx][K], link[mx], term[mx];

int new_vertex() {
	for (int it = 0; it < K; ++it) {
		go[V][it] = -1;
	}
	return (V++);
}

void init() {
	new_vertex();
}

void add_string(vector<int> s) {
	// cerr << "add_string" << endl;
	// output(all(s));
	int v = 0;
	for (auto c : s) {
		if (go[v][c] == -1) {
			go[v][c] = new_vertex();
		}
		v = go[v][c];
	}
	term[v] = 1;
}

void bfs() {
	queue<int> q;
	q.push(0);
	while (!q.empty()) {
		int v = q.front();
		q.pop();
		if (term[link[v]]) {
			term[v] = 1;
		}
		for (int c = 0; c < K; ++c) {
			if (go[v][c] == -1) {
				go[v][c] = (v == 0 ? 0 : go[link[v]][c]);
			} else {
				q.push(go[v][c]);
				link[go[v][c]] = (v == 0 ? 0 : go[link[v]][c]);
			}
		}
	}

	// std::cerr << "automaton" << std::endl;
	// std::cerr << "ptr = " << V << std::endl;
	// for (int i = 0; i < V; ++i) {
	// 	std::cerr << "vertex " << i << ", term = " << term[i] << ", go =";
	// 	for (int j = 0; j < K; ++j) {
	// 		cerr << " " << go[i][j];
	// 	}
	// 	cerr << endl;
	// }
}

void build() {
	init();
	for (auto s : C) {
		add_string(s);
	}
	bfs();
}

vector<vector<int> > rev_single;
vector<vector<pair<int, int> > > rev_double_l, rev_double_r;

void prepare_aux() {
	rev_single.resize(G);
	rev_double_l.resize(G);
	rev_double_r.resize(G);
	for (int i = 0; i < G; ++i) {
		for (auto v : singleMut[i]) {
			rev_single[v].push_back(i);
		}
		for (auto pp : doubleMut[i]) {
			rev_double_l[pp.first].emplace_back(pp.second, i);
			rev_double_r[pp.second].emplace_back(pp.first, i);
		}
	}
}

struct Achievement {
	ull t;
	int geneId, from, to;
};

bool operator < (const Achievement &a, const Achievement &b) {
	return a.t < b.t;
}

const ull INF = (ull)1 << 63;
multiset<Achievement> S;
ull dist[maxG][mx][mx];
int used[maxG][mx][mx];

void djkstra() {
	for (int i = 0; i < G; ++i) {
		for (int from = 0; from < V; ++from) {
			for (int to = 0; to < V; ++to) {
				dist[i][from][to] = INF;
			}
		}
	}
	for (int i = 0; i < V; ++i) {
		for (int it = 0; it < K; ++it) {
			if (!term[i] && !term[go[i][it]]) {
				S.insert({1, it, i, go[i][it]});
				dist[it][i][go[i][it]] = 1;
			}
		}
	}
	while (!S.empty()) {
		Achievement cur = (*S.begin());
		S.erase(S.begin());
		int gene = cur.geneId;
		int from = cur.from;
		int to = cur.to;
		ull t = cur.t;
		if (used[gene][from][to]) {
			continue;
		}
		for (auto v1 : rev_single[gene]) {
			if (chkmin(dist[v1][from][to], t)) {
				S.insert({dist[v1][from][to], v1, from, to});
			}
		}
		for (auto pp : rev_double_l[gene]) {
			int v1 = pp.first, v2 = pp.second;
			for (int final = 0; final < V; ++final) {
				if (!term[final] && chkmin(dist[v2][from][final], t + dist[v1][to][final])) {
					S.insert({dist[v2][from][final], v2, from, final});
				}
			}
		}
		for (auto pp : rev_double_r[gene]) {
			int v1 = pp.first, v2 = pp.second;
			for (int start = 0; start < V; ++start) {
				if (!term[start] && chkmin(dist[v2][start][to], dist[v1][start][from] + t)) {
					S.insert({dist[v2][start][to], v2, start, to});
				}
			}
		}
	}
}

void print_ans() {
	for (int i = 2; i < G0; ++i) {
		ull opt = INF;
		for (int j = 0; j < V; ++j) {
			if (!term[j]) {
				chkmin(opt, dist[i][0][j]);
			}
		}
		if (opt == INF) {
			cout << "YES\n";
		} else {
			cout << "NO " << opt << '\n';
		}
	}
}

signed main() {
	fast_io();
	read();
	build();
	prepare_aux();
	djkstra();
	print_ans();
}

#include <bits/stdc++.h>
struct Automaton {
    int tot, nbad;
    int nxt[100][2], bad[100], id[100], link[100];
    Automaton() : tot(1), nxt{}, bad{}, link{} {}
    void add(std::vector<int> s) {
        int p = 1;
        for (auto c : s) {
            if (!nxt[p][c])
                nxt[p][c] = ++tot;
            p = nxt[p][c];
        }
        bad[p] = 1;
    }
    void build() {
        for (int i = 1; i <= tot; ++i)
            if (bad[i])
                bad[nxt[i][0]] = bad[nxt[i][1]] = 1;
        std::queue<int> que;
        que.push(1);
        nxt[0][0] = nxt[0][1] = 1;
        bad[0] = 0;
        while (!que.empty()) {
            int u = que.front();
            que.pop();
            bad[u] |= bad[link[u]];
            for (int c = 0; c < 2; ++c) {
                if (nxt[u][c]) {
                    link[nxt[u][c]] = nxt[link[u]][c];
                    que.push(nxt[u][c]);
                } else {
                    nxt[u][c] = nxt[link[u]][c];
                }
            }
        }
        nbad = 0;
        for (int i = 1; i <= tot; ++i)
            if (!bad[i])
                id[i] = nbad++;
    }
};
int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    int g, n, m;
    std::cin >> g >> n >> m;
    std::vector<std::vector<std::tuple<int, int, int>>> e(g);
    int tot = g;
    auto add = [&](int x, int a, int b) {
        e[a].emplace_back(x, b, 0);
        e[b].emplace_back(x, a, 1);
    };
    for (int i = 0; i < n; ++i) {
        int u;
        std::cin >> u;
        int k;
        std::cin >> k;
        std::vector<int> v(k);
        for (int j = 0; j < k; ++j)
            std::cin >> v[j];
        if (k == 1) {
            e[v[0]].emplace_back(u, -1, -1);
            continue;
        }
        for (int j = 0; j < k - 1; ++j) {
            if (j == k - 2) {
                add(u, v[j], v[j + 1]);
            } else {
                e.emplace_back();
                add(u, v[j], tot);
                u = tot++;
            }
        }
    }
    Automaton am;
    for (int i = 0; i < m; ++i) {
        int l;
        std::cin >> l;
        std::vector<int> a(l);
        for (int j = 0; j < l; ++j)
            std::cin >> a[j];
        am.add(a);
    }
    am.build();
    std::vector<std::vector<std::vector<uint64_t>>> dp(tot);
    for (auto &v : dp)
        v.assign(am.nbad, std::vector<uint64_t>(am.nbad, 1ull << 63));
    std::priority_queue<std::tuple<uint64_t, int, int, int>, std::vector<std::tuple<uint64_t, int, int, int>>, std::greater<>> h;
    for (int c = 0; c < 2; ++c) {
        for (int i = 1; i <= am.tot; ++i) {
            if (!am.bad[i] && !am.bad[am.nxt[i][c]]) {
                dp[c][am.id[i]][am.id[am.nxt[i][c]]] = 1;
                h.emplace(1, c, am.id[i], am.id[am.nxt[i][c]]);
            }
        }
    }
    while (!h.empty()) {
        auto [d, u, x, y] = h.top();
        h.pop();
        if (d != dp[u][x][y])
            continue;
        for (auto [t, v, p] : e[u]) {
            if (p == -1) {
                if (dp[t][x][y] > d) {
                    dp[t][x][y] = d;
                    h.emplace(d, t, x, y);
                }
            } else if (p == 0) {
                for (int z = 0; z < am.nbad; ++z) {
                    if (dp[t][x][z] > d + dp[v][y][z]) {
                        dp[t][x][z] = d + dp[v][y][z];
                        h.emplace(dp[t][x][z], t, x, z);
                    }
                }
            } else {
                for (int z = 0; z < am.nbad; ++z) {
                    if (dp[t][z][y] > d + dp[v][z][x]) {
                        dp[t][z][y] = d + dp[v][z][x];
                        h.emplace(dp[t][z][y], t, z, y);
                    }
                }
            }
        }
    }
    for (int u = 2; u < g; ++u) {
        uint64_t ans = 1ull << 63;
        for (int i = 0; i < am.nbad; ++i)
            if (ans > dp[u][0][i])
                ans = dp[u][0][i];
        if (ans == (1ull << 63)) {
            std::cout << "YES\n";
        } else {
            std::cout << "NO " << ans << "\n";
        }
    }
    return 0;
}

//#pragma GCC optimize("O3")
#include <bits/stdc++.h>

using namespace std;

#define TIME (clock() * 1.0 / CLOCKS_PER_SEC)
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;

const int X = 55;
const int M = 110;
const ull INF = (ull)1 << (ull)63;

ull sum(ull a, ull b)
{
    if (a == INF || b == INF)
        return INF;
    if (a + b >= INF)
        return INF;
    return a + b;
}

vector<vector<int>> seq[M];
int g, n, m;
vector<string> s;

int to[X][2], r, go[X][2];
bool term[X], good[X];

int exists(string c)
{
    int st = 0;
    for (char x : c)
    {
        int d = x - '0';
        if (to[st][d] == -1)
            return -1;
        st = to[st][d];
    }
    return st;
}

int getsuf(string c)
{
    for (int i = 0; i < (int)c.size(); i++)
    {
        string cur = c.substr(i, (int)c.size() - i);
        int st = exists(cur);
        if (st != -1)
            return st;
    }
    return 0;
}

bool is_good(string c)
{
    for (int i = 0; i < (int)c.size(); i++)
    {
        string cur = c.substr(i, (int)c.size() - i);
        int st = exists(cur);
        if (st != -1 && term[st])
            return false;
    }
    return true;
}

void dfs(int p, string c)
{
    good[p] = is_good(c);
    go[p][0] = getsuf(c + "0");
    go[p][1] = getsuf(c + "1");
    if (to[p][0] != -1)
        dfs(to[p][0], c + "0");
    if (to[p][1] != -1)
        dfs(to[p][1], c + "1");
}

ull dp[M][X][X], cur[2][X];

int main()
{
#ifdef ONPC
    freopen("input", "r", stdin);
#endif
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
    cin >> g >> n >> m;
    for (int i = 0; i < n; i++)
    {
        int a, k;
        cin >> a >> k;
        vector<int> c(k);
        for (int t = 0; t < k; t++)
            cin >> c[t];
        seq[a].push_back(c);
    }
    for (int i = 0; i < m; i++)
    {
        int k;
        cin >> k;
        string c = "";
        for (int t = 0; t < k; t++)
        {
            char x;
            cin >> x;
            c += x;
        }
        s.push_back(c);
    }
    memset(to, -1, sizeof(to));
    r = 1;
    for (string c : s)
    {
        int st = 0;
        for (char x : c)
        {
            int d = x - '0';
            if (to[st][d] == -1)
                to[st][d] = r++;
            st = to[st][d];
        }
        term[st] = true;
    }
    dfs(0, "");
    for (int i = 0; i < g; i++)
        for (int j = 0; j < r; j++)
            for (int h = 0; h < r; h++)
                dp[i][j][h] = INF;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < r; j++)
            if (good[j] && good[go[j][i]])
                dp[i][j][go[j][i]] = 1;
    while (TIME < 0.5)
    {
        for (int i = 2; i < g; i++)
            for (int st = 0; st < r; st++)
                if (good[st])
                {
                    for (const vector<int>& ids : seq[i])
                    {
                        for (int l = 0; l < 2; l++)
                            for (int t = 0; t < r; t++)
                                cur[l][t] = INF;
                        cur[0][st] = 0;
                        int now = 0;
                        for (int u : ids)
                        {
                            for (int t = 0; t < r; t++)
                                cur[1 - now][t] = INF;
                            for (int t = 0; t < r; t++)
                                for (int b = 0; b < r; b++)
                                    if (good[t] && good[b])
                                        cur[1 - now][t] = min(cur[1 - now][t], sum(cur[now][b], dp[u][b][t]));
                            now = 1 - now;
                        }
                        for (int t = 0; t < r; t++)
                            dp[i][st][t] = min(dp[i][st][t], cur[now][t]);
                    }
                }
    }
    for (int i = 2; i < g; i++)
    {
        ull ans = INF;
        for (int t = 0; t < r; t++)
            if (good[t])
                ans = min(ans, dp[i][0][t]);
        if (ans == INF)
            cout << "YES\n";
        else
            cout << "NO " << ans << "\n";
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vpi;

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define bk back()
#define sz(x) (int)(x).size()

const ll MX = (1ULL<<63)-1;

ll trans[105][55][55]; //matrices
vi sing[105]; // node relies on i
vpi doubf[105]; // f relies on (i, s)
vpi doubs[105]; // f relies on (s, i)

ll comb(ll a, ll b){
    if(a == -1 || b == -1) return -1;
    if(a > MX-b) return -1;
    return a+b;
}

bool cmp(ll a, ll b){ //a < b
    if(a == b) return 0;
    if(a == -1) return 0;
    if(b == -1) return 1;
    return a < b;
}

int suf[55];
int to[55][2];
int TO[55][2];
bool bad[55];

pi par[55];
int cnt = 0;

void AhoInsert(vi c){
    int cur = 0;
    for(auto u: c){
        if(to[cur][u] == -1){
            to[cur][u] = ++cnt;
            par[cnt] = mp(cur, u);
        }
        cur = to[cur][u];
    }
    bad[cur] = 1;
}

int go(int node, int t);

int getLink(int node){
    if(suf[node] != -1) return suf[node];
    if(node == 0 || par[node].f == 0){
        suf[node] = 0;
    }
    else{
        suf[node] = go(getLink(par[node].f), par[node].s);
    }
    return suf[node];
}

int BAD[55];

bool isBad(int node){
    if(node == -2) return 1;
    if(BAD[node] != -1){
        return BAD[node];
    }
    if(node == 0){
        BAD[node] = 0;
    }
    else if(bad[node]){
        BAD[node] = 1;
    }
    else{
        BAD[node] = isBad(getLink(node));
    }
    return BAD[node];
}

int go(int node, int t){
    if(node == -2) return -2;
    if(TO[node][t] != -1){
        return TO[node][t];
    }

    if(to[node][t] != -1){
        if(isBad(to[node][t])){
            TO[node][t] = -2;
        }
        else{
            TO[node][t] = to[node][t];
        }
    }
    else if(node == 0){
        TO[node][t] = 0;
    }
    else{
        if(isBad(getLink(node))){
            TO[node][t] = -2;
        }
        else TO[node][t] = go(getLink(node), t);
    }
    return TO[node][t];
}

void genAho(){
    for(int i = 0; i <= cnt; i++){
        for(int j = 0; j < 2; j++){
            go(i, j);
        }
    }
}

int main(){
    for(int i = 0; i < 55; i++){
        suf[i] = -1;
        BAD[i] = -1;
        for(int j = 0; j < 2; j++){
            TO[i][j] = to[i][j] = -1;
        }
    }
    int G, N, M;
    cin >> G >> N >> M;

    int matind = G-1;

    for(int i = 1; i <= N; i++){
        int a, k;
        cin >> a >> k;
        vi B;
        for(int j = 1; j <= k; j++){
            int BB;
            cin >> BB;
            B.pb(BB);
        }

        if(sz(B) == 1){
            sing[B[0]].pb(a);
        }
        else if(sz(B) == 2){
            doubf[B[0]].pb(mp(a, B[1]));
            doubs[B[1]].pb(mp(a, B[0]));
        }
        else{
            matind++;
            doubf[B[0]].pb(mp(matind, B[1]));
            doubs[B[1]].pb(mp(matind, B[0]));
            for(int i = 2; i < sz(B)-1; i++){
                matind++;
                doubf[matind-1].pb(mp(matind, B[i]));
                doubs[B[i]].pb(mp(matind, matind-1));
            }
            doubf[matind].pb(mp(a, B.bk));
            doubs[B.bk].pb(mp(a, matind));
        }
    }

    for(int i = 1; i <= M; i++){
        vi c;
        int l;
        cin >> l;
        for(int j = 1; j <= l; j++){
            int C;
            cin >> C;
            c.pb(C);
        }
        AhoInsert(c);
    }

    genAho();
    // for(int i = 0; i <= cnt; i++){
    //     cout << i << " " << suf[i] << " " << to[i][0] << " " << to[i][1] << " " << TO[i][0] << " " << TO[i][1] << "\n";
    // }

    for(int i = 0; i <= matind; i++){
        for(int j = 0; j <= cnt; j++){
            for(int k = 0; k <= cnt; k++){
                trans[i][j][k] = -1;
            }
        }
    }

    priority_queue<pair<ll, vi>, vector<pair<ll, vi>>, greater<pair<ll, vi>>> pq;

    for(int i = 0; i <= cnt; i++){
        for(int j = 0; j < 2; j++){
            if(TO[i][j] != -2){
                trans[j][i][TO[i][j]] = 0;
                //cout << j << " " << i << " " << TO[i][j] << "\n";
                pq.push(mp(0, vi{j, i, TO[i][j]}));
                //trans[j][i][to[i][j]] = 1;
            }
        }
    }

    while(sz(pq)){
        pair<ll, vi> p = pq.top();
        pq.pop();
        if(trans[p.s[0]][p.s[1]][p.s[2]] < p.f) continue;

        for(auto u: sing[p.s[0]]){
            if(cmp(p.f, trans[u][p.s[1]][p.s[2]])){
                trans[u][p.s[1]][p.s[2]] = p.f;
                pq.push(mp(p.f, vi{u, p.s[1], p.s[2]}));
            }
        }
        for(auto u: doubf[p.s[0]]){
            for(int i = 0; i <= cnt; i++){
                if(cmp(comb(comb(trans[p.s[0]][p.s[1]][p.s[2]], trans[u.s][p.s[2]][i]), 1), trans[u.f][p.s[1]][i])){
                    trans[u.f][p.s[1]][i] = comb(comb(trans[p.s[0]][p.s[1]][p.s[2]], trans[u.s][p.s[2]][i]), 1);
                    pq.push(mp(trans[u.f][p.s[1]][i], vi{u.f, p.s[1], i}));
                }
            }
        }
        for(auto u: doubs[p.s[0]]){
            for(int i = 0; i <= cnt; i++){
                if(cmp(comb(comb(trans[u.s][i][p.s[1]], trans[p.s[0]][p.s[1]][p.s[2]]), 1), trans[u.f][i][p.s[2]])){
                    trans[u.f][i][p.s[2]] = comb(comb(trans[u.s][i][p.s[1]], trans[p.s[0]][p.s[1]][p.s[2]]), 1);
                    pq.push(mp(trans[u.f][i][p.s[2]], vi{u.f, i, p.s[2]}));
                }
            }
        }
    }

    for(int i = 2; i <= G-1; i++){
        ll ans = -1;
        for(int j = 0; j <= cnt; j++){
            if(cmp(trans[i][0][j], ans)){
                ans = trans[i][0][j];
            }
        }
        if(ans == -1){
            cout << "YES" << "\n";
        }
        else cout << "NO" << " " << ans+1 << "\n";
    }

}

#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#define pb push_back
#define pi pair<int, int>
#define l first
#define r second
#define all(x) x.begin(), x.end()
#define fori(a, b, step) for (int i = a; i < b; i += step)
#define forj(a, b, step) for (int j = a; j < b; j += step)
#define int long long

const int maxn = 3e5 + 1, mod = 998244353;

using namespace std;

int G, N, M;

vector<vector<int> > v[102];
vector<int> g[51];
int dp[102][51][51];

struct trie {
    short next[2] = {-1, -1};
    short go[2] = {-1, -1};
    short link = -1;
    short p = -1;
    bool pc = 0, trm = 0;

    trie() {}
};

trie t[51];
int mx = 0;

void add_string(int ci) {
    int x = 0;
    for (int i = 0; i < g[ci].size(); i++) {
        if (t[x].next[g[ci][i]] == -1)
            t[x].next[g[ci][i]] = ++mx;
        t[t[x].next[g[ci][i]]].p = x;
        t[t[x].next[g[ci][i]]].pc = g[ci][i];
        x = t[x].next[g[ci][i]];
    }
    t[x].trm = 1;
}

extern int slink(int x);

int go(int x, int st) {
    if (t[x].go[st] != -1)
        return t[x].go[st];
    if (t[x].next[st] != -1) {
        t[x].go[st] = t[x].next[st];
        return t[x].go[st];
    }
    if (x == 0)
        return (t[x].go[st] = 0);
    return (t[x].go[st] = go(slink(x), st));
}

int slink(int x) {
    if (t[x].link != -1)
        return t[x].link;
    if (x == 0 || t[x].p == 0)
        return (t[x].link = 0);
    return (t[x].link = go(slink(t[x].p), t[x].pc));
}

int gmin(int x, int y) {
    if (x == -1) return y;
    if (y == -1) return x;
    return min(x, y);
}

signed main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    cin >> G >> N >> M;
    for (int i = 0; i < N; i++) {
        int a, k; cin >> a >> k;
        v[a].pb(vector<int>(k, 0));
        for (int j = 0; j < k; j++)
            cin >> v[a].back()[j];
    }
    for (int i = 0; i < M; i++) {
        int l; cin >> l;
        g[i].resize(l);
        for (int j = 0; j < l; j++)
            cin >> g[i][j];
        add_string(i);
    }
    for (int i = 0; i < G; i++)
        for (int j = 0; j <= mx; j++)
            for (int l = 0; l <= mx; l++)
                dp[i][j][l] = -1;
    for (int i = 0; i <= mx; i++) {
        for (int x = i; x != 0; x = slink(x))
            if (t[x].trm) {
                t[i].trm = 1;
                break;
            }
    }
    for (int i = 0; i <= mx; i++) {
        if (t[i].trm) continue;
        int g0 = go(i, 0), g1 = go(i, 1);
        if (!t[g0].trm) dp[0][i][g0] = 1;
        if (!t[g1].trm) dp[1][i][g1] = 1;
    }
    for (int cntr = 0; cntr < G; cntr++) {
        for (int i = 2; i < G; i++) {
            for (auto cv : v[i]) {
                int cd[mx + 1][mx + 1];
                for (int x = 0; x <= mx; x++)
                    for (int y = 0; y <= mx; y++)
                        cd[x][y] = -1;
                for (int x = 0; x <= mx; x++) {
                    if (t[x].trm) continue;
                    for (int y = 0; y <= mx; y++)
                        cd[x][y] = dp[cv[0]][x][y];
                    for (int j = 1; j < cv.size(); j++) {
                        int pv[mx + 1];
                        for (int z = 0; z <= mx; z++)
                            pv[z] = -1;
                        for (int y = 0; y <= mx; y++)
                            for (int z = 0; z <= mx; z++) {
                                if (cd[x][y] == -1 || dp[cv[j]][y][z] == -1)
                                    continue;
                                pv[z] = gmin(pv[z], cd[x][y] + dp[cv[j]][y][z]);
                            }
                        for (int z = 0; z <= mx; z++)
                            cd[x][z] = pv[z];
                    }
                }
                for (int x = 0; x <= mx; x++)
                    for (int y = 0; y <= mx; y++)
                        dp[i][x][y] = gmin(dp[i][x][y], cd[x][y]);
            }
        }
    }
    for (int i = 2; i < G; i++) {
        int can = -1;
        for (int j = 0; j <= mx; j++)
            can = gmin(can, dp[i][0][j]);
        if (can == -1) cout << "YES";
        else cout << "NO " << can;
        cout << '\n';
    }
    return 0;
}

#ifdef APTEST
#include "debug_tools/program.h"
#endif
#include <algorithm>
#include <iostream>
#include <iterator>
#include <limits>
#include <queue>
using namespace std;
const unsigned int maxl = 50, maxk = 100, maxn = maxk, maxg = maxn + 2, maxm = 50;
constexpr unsigned int maxv = maxg * 2, maxe = maxk * 2, avert = maxm * 2;
typedef unsigned long long Length;
constexpr Length inf = numeric_limits<Length>::max() / 3;
template <class T>
using StateMatrix = T[maxv + 10][avert + 10][avert + 10];

class MutationGraph
{
public:
    struct Mutation
    {
        unsigned int to, another;
        const Mutation* pre;
    } mut[maxe + 10];
    const Mutation* head[maxv + 10];

    inline void add(const unsigned int from, const unsigned int to, const unsigned int another)
    {
        new (cur) Mutation { to, another, head[from] };
        head[from] = cur++;
    }

private:
    Mutation* cur = mut;
} single, asFirst, asSecond;
StateMatrix<Length> dis;
unsigned int gcur;

namespace AhoCorasick
{
    unsigned int ch[avert + 10][2], fail[avert + 10], id[avert + 10];
    bool isEnd[avert + 10];
    unsigned int vcur;

    void readString()
    {
        unsigned int len;
        cin >> len;
        unsigned int ptr = 0;
        for (unsigned int i = 0; i < len; ++i)
        {
            unsigned int cb;
            cin >> cb;
            if (!ch[ptr][cb])
                ch[ptr][cb] = ++vcur;
            ptr = ch[ptr][cb];
        }
        isEnd[ptr] = true;
    }
    unsigned int reLabel()
    {
        unsigned int icur = 0;
        for (unsigned int i = 0; i <= vcur; ++i)
            if (!isEnd[i])
                id[i] = icur++;
        return icur;
    }
    unsigned int build()
    {
        queue<unsigned int> q;
        for (unsigned int i : ch[0])
            if (i)
                q.push(i);
        while (!q.empty())
        {
            const unsigned int cur = q.front();
            q.pop();
            for (unsigned int i = 0; i < 2; ++i)
                if (!ch[cur][i])
                    ch[cur][i] = ch[fail[cur]][i];
                else
                {
                    const unsigned int cv = ch[cur][i];
                    fail[cv] = ch[fail[cur]][i];
                    isEnd[cv] = isEnd[cv] || isEnd[fail[cv]];
                    q.push(cv);
                }
        }
        return reLabel();
    }
}
void addMutation(const unsigned int a)
{
    static unsigned int buf[maxk + 10];
    unsigned int k;
    cin >> k;
    copy_n(istream_iterator<unsigned int>(cin), k, buf);
    if (k == 1)
    {
        single.add(buf[0], a, 0);
        return;
    }
    unsigned int lst = buf[k - 1];
    for (const unsigned int* i = buf + k - 2; i > buf; --i)
    {
        const unsigned int virt = gcur++;
        asFirst.add(*i, virt, lst);
        asSecond.add(lst, virt, *i);
        lst = virt;
    }
    asFirst.add(buf[0], a, lst);
    asSecond.add(lst, a, buf[0]);
}
struct StateNode
{
    unsigned int id, start, end;
    Length dis;

    template <class T>
    inline T& operator[](StateMatrix<T> mat) const { return mat[id][start][end]; }
};
struct StateLess
{
    inline bool operator()(const StateNode& a, const StateNode& b) const
    {
        return a.dis > b.dis;
    }
};
typedef priority_queue<StateNode, vector<StateNode>, StateLess> Heap;
static void dpInit(Heap& q)
{
    using namespace AhoCorasick;
    for (unsigned int i = 0; i <= vcur; ++i)
    {
        if (isEnd[i])
            continue;
        for (unsigned int j = 0; j < 2; ++j)
        {
            const unsigned int nvert = ch[i][j];
            if (!isEnd[nvert])
            {
                dis[j][id[i]][id[nvert]] = 1;
                q.push(StateNode { j, id[i], id[nvert], 1 });
            }
        }
    }
}
void dijkstra(const unsigned int acId)
{
    static StateMatrix<bool> vis;
    Heap q;
    fill(reinterpret_cast<Length*>(dis), reinterpret_cast<Length*>(dis) + sizeof(dis) / sizeof(Length), inf);
    dpInit(q);
    auto update = [&q](const StateNode&& sn) {
        if (sn[dis] > sn.dis)
        {
            sn[dis] = sn.dis;
            q.push(sn);
        }
    };
    while (!q.empty())
    {
        const StateNode cur = q.top();
        q.pop();
        if (cur[vis])
            continue;
        cur[vis] = true;
        for (auto i = single.head[cur.id]; i; i = i->pre)
            update(StateNode { i->to, cur.start, cur.end, cur.dis });
        for (auto i = asFirst.head[cur.id]; i; i = i->pre)
            for (unsigned int j = 0; j < acId; ++j)
                update(StateNode { i->to, cur.start, j, cur.dis + dis[i->another][cur.end][j] });
        for (auto i = asSecond.head[cur.id]; i; i = i->pre)
            for (unsigned int j = 0; j < acId; ++j)
                update(StateNode { i->to, j, cur.end, dis[i->another][j][cur.start] + cur.dis });
    }
}

int main()
{
#ifndef APTEST
    ios_base::sync_with_stdio(false);
#endif
    unsigned int g, n, m;
    cin >> g >> n >> m;
    gcur = g;
    for (unsigned int i = 0; i < n; ++i)
    {
        unsigned int a;
        cin >> a;
        addMutation(a);
    }
    for (unsigned int i = 0; i < m; ++i)
        AhoCorasick::readString();
    const unsigned int acId = AhoCorasick::build();
    dijkstra(acId);
    for (unsigned int i = 2; i < g; ++i)
    {
        Length ans = inf;
        for (unsigned int s = 0; s < acId; ++s)
            ans = min(ans, *min_element(dis[i][s], dis[i][s] + acId));
        if (ans < inf)
            cout << "NO " << ans << "\n";
        else
            cout << "YES\n";
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using Vi = vector<int>;
using Pii = pair<int,int>;
#define pb push_back
#define mp make_pair
#define x first
#define y second
#define rep(i,b,e) for (int i = (b); i < (e); i++)
#define each(a,x) for (auto& a : (x))
#define all(x) (x).begin(),(x).end()
#define sz(x) int((x).size())

using ull = unsigned long long;
constexpr ull INF = 1ull << 63;

ull add(ull a, ull b) {
	if (a >= INF || b >= INF) {
		return INF;
	}
	return a+b;
}

struct Matrix {
	int n;
	vector<ull> M;

	Matrix(int _n = 0) : n(_n), M(_n*_n, INF) { }

	const ull* operator[](int i) const { return &M[i*n]; }
	ull* operator[](int i) { return &M[i*n]; }

	Matrix& operator+=(const Matrix& r) {
		rep(i, 0, sz(M)) M[i] = min(M[i], r.M[i]);
		return *this;
	}

	Matrix operator*(const Matrix& r) const {
		static Vi nice;
		Matrix ret(n);

		rep(i, 0, n) {
			nice.clear();
			rep(k, 0, n) if ((*this)[i][k] < INF) nice.pb(k);
			rep(j, 0, n) each(k, nice) {
				ret[i][j] = min(ret[i][j], add((*this)[i][k], r[k][j]));
			}
		}
		return ret;
	}
};

struct Aho {
	vector<array<int, 2>> nxt;
	vector<bool> acc;
	Vi suf;

	Aho() {
		nxt.pb({-1, -1});
		nxt.pb({1, 1});
		acc.resize(2);
	}

	void add(const Vi& s) {
		int cur = 0;
		each(e, s) {
			if (nxt[cur][e] == -1) {
				acc.pb(0);
				nxt.pb({-1, -1});
				nxt[cur][e] = sz(nxt)-1;
			}
			cur = nxt[cur][e];
		}
		acc[cur] = 1;
	}

	void build() {
		queue<int> que;
		suf.resize(sz(nxt), -1);

		rep(i, 0, 2) {
			int& j = nxt[0][i];
			if (j != -1) {
				suf[j] = 0;
				que.push(j);
			} else {
				j = 0;
			}
		}

		while (!que.empty()) {
			int i = que.front();
			que.pop();
			rep(j, 0, 2) {
				int& e = nxt[i][j];
				if (e != -1) {
					suf[e] = nxt[suf[i]][j];
					que.push(e);
				} else {
					e = nxt[suf[i]][j];
				}
			}
			acc[i] = acc[i] || acc[suf[i]];
		}
	}

	Matrix getMatrix(int e) {
		Matrix ret(sz(nxt));
		rep(i, 0, sz(nxt)) {
			int j = nxt[i][e];
			if (acc[j]) j = 1;
			ret[i][j] = 1;
		}
		return ret;
	}
};

int main() {
	int g, n, m; cin >> g >> n >> m;
	vector<vector<Vi>> mutations(g);

	rep(i, 0, n) {
		int a, k; cin >> a >> k;
		Vi mut(k);
		each(j, mut) cin >> j;
		mutations[a].pb(move(mut));
	}

	Aho aho;

	rep(i, 0, m) {
		int k; cin >> k;
		Vi tmp(k);
		each(j, tmp) cin >> j;
		aho.add(tmp);
	}

	int dim = sz(aho.nxt);
	vector<Matrix> dp(g, {dim});
	aho.build();
	dp[0] = aho.getMatrix(0);
	dp[1] = aho.getMatrix(1);

	bool chg = 1;

	while (chg) {
		chg = 0;
		rep(i, 2, g) {
			Matrix mat(dim);
			each(mut, mutations[i]) {
				Matrix tmp(dim);
				rep(j, 0, dim) tmp[j][j] = 0;
				each(j, mut) tmp = tmp*dp[j];
				mat += tmp;
			}

			rep(j, 0, sz(mat.M)) if (dp[i].M[j] != mat.M[j]) {
				chg = 1;
				dp[i] = mat;
				break;
			}
		}
	}

	rep(i, 2, g) {
		ull ans = INF;
		rep(j, 0, dp[i].n) if (j != 1) ans = min(ans, dp[i][0][j]);
		if (ans < INF) {
			cout << "NO " << ans << '\n';
		} else {
			cout << "YES\n";
		}
	}
	return 0;
}

// Null
#include <bits/stdc++.h>

#define pb push_back
#define F first
#define S second
#define all(x) x.begin(), x.end()
#define debug(x) cerr << #x << " : " << x << '\n'
#define U S.F.F
#define V S.F.S
#define Ba S.S

using namespace std;

typedef long long ll;
typedef long double ld;
typedef string str;
typedef pair<ll, ll> pll;

const ll Mod = 1000000007LL;
const int N = 2e5 + 10;
const ll Inf = 2242545357980376863LL;
const ll Log = 30;

int G, n, m;
vector< pair<int, vector<int> > > con;
vector<int> req[N];

int b[N];

int nx[N][2], Sz = 1;
int F[N], bad[N], Que[N];

void Build(){
	int nw, l = 0, r = 0;
	for(int i = 0; i < 2; i++)
		if(nx[0][i])
			Que[r ++] = nx[0][i];
	while(r - l){
		nw = Que[l ++];
		bad[nw] |= bad[F[nw]];
		for(int i = 0; i < 2; i++)
			if(nx[nw][i])
				F[nx[nw][i]] = nx[F[nw]][i], Que[r ++] = nx[nw][i];
			else
				nx[nw][i] = nx[F[nw]][i];
	}
}

const int L = 52;
const int MV = 102;

ll dp[L][L][MV];

typedef pair<ll, pair< pair<int, int>, int> > T;

set<T> st;

int main(){
	ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);

	cin >> G >> n >> m;
	int firstG = G;

	ll a, k;
	vector<int> R;
	for(int i = 1; i <= n; i++){
		cin >> a >> k;
		R.clear();
		for(int j = 0; j < k; j++) cin >> b[j];
		if(k == 1){
			R.pb(b[0]);
			con.pb({a, R});
			continue;
		}
		while(k > 2){
			R.clear();
			R.pb(b[k - 2]);
			R.pb(b[k - 1]);
			b[k - 2] = G;
			k --;
			con.pb({G, R});
			G ++;
		}
		R.clear();
		R.pb(b[0]);
		R.pb(b[1]);
		con.pb({a, R});
	}
	for(int i = 0; i < (int) con.size(); i++){
		for(auto y : con[i].S)
			req[y].pb(i);
	}

	assert(G <= MV);

	int ch;
	for(int i = 0; i < m; i++){
		cin >> k;
		int nw = 0;
		for(int i = 0; i < k; i++){
			cin >> ch;
			if(!nx[nw][ch]){
				nx[nw][ch] = Sz ++;
			}
			nw = nx[nw][ch];
		}
		bad[nw] = 1;
	}
	Build();
	{
		/*
		debug(Sz);
		for(auto x : con){

			cerr << '\n';
			cerr << x.F << " -> ";
			for(auto y : x.S) cerr << y << ' ';
			cerr << '\n';

		}
		for(int i = 0; i < Sz; i++) cerr << F[i] << ' ';
		cerr << '\n';
		cerr << '\n';
		*/
	}

	memset(dp, 31, sizeof dp);
	for(int i = 0; i < Sz; i++){
		//if(bad[i]) debug(i);
		if(bad[i]) continue;
		if(! bad[nx[i][0]]) dp[i][nx[i][0]][0] = 1;

		if(! bad[nx[i][1]]) dp[i][nx[i][1]][1] = 1;

		st.insert({dp[i][nx[i][0]][0], {{i, nx[i][0]}, 0}});
		st.insert({dp[i][nx[i][1]][1], {{i, nx[i][1]}, 1}});
	}

	//debug(Inf);
	//debug(dp[3][3][3]);

	T fr;
	while(!st.empty()){
		fr = *st.begin(); st.erase(st.begin());
		if(fr.F >= Inf) break;

		for(int tr : req[fr.Ba]){
			if(con[tr].S.size() == 1){
				if(dp[fr.U][fr.V][con[tr].F] > fr.F){
					st.erase({dp[fr.U][fr.V][con[tr].F], {fr.S.F, con[tr].F}});
					dp[fr.U][fr.V][con[tr].F] = fr.F;
					st.insert({dp[fr.U][fr.V][con[tr].F], {fr.S.F, con[tr].F}});
				}
				continue;
			}
			assert(con[tr].S.size() == 2);
			if(con[tr].S[0] == fr.Ba){
				for(int z = 0; z < Sz; z++){
					if(dp[fr.U][z][con[tr].F] > fr.F + dp[fr.V][z][con[tr].S[1]]){
						st.erase({dp[fr.U][z][con[tr].F], {{fr.U, z}, con[tr].F}});
						dp[fr.U][z][con[tr].F] = fr.F + dp[fr.V][z][con[tr].S[1]];
						st.insert({dp[fr.U][z][con[tr].F], {{fr.U, z}, con[tr].F}});
					}
				}
			}
			if(con[tr].S[1] == fr.Ba){
				for(int z = 0; z < Sz; z++){
					if(dp[z][fr.V][con[tr].F] > fr.F + dp[z][fr.U][con[tr].S[0]]){

						st.erase({dp[z][fr.V][con[tr].F], {{z, fr.V}, con[tr].F}});
						dp[z][fr.V][con[tr].F] = fr.F + dp[z][fr.U][con[tr].S[0]];
						st.insert({dp[z][fr.V][con[tr].F], {{z, fr.V}, con[tr].F}});
					}
				}
			}
		}
	}

	for(int i = 2; i < firstG; i++){
		ll answ = Inf;

		for(int j = 0; j < Sz; j++) answ = min(answ, dp[0][j][i]);

		if(answ >= Inf) cout << "YES\n";
		else cout << "NO " << answ << '\n';
	}
	return 0;
}

#include<bits/stdc++.h>
#define LL long long
#define ull unsigned long long
using namespace std;
const int N=103;
const int S=55;
const ull INF = -1;

int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
void print(LL x){
    if(x>9) print(x/10);
    putchar(x%10+'0');
}

int G,n,m;
int a[N],k[N],b[N][N];
int l[S],c[S][S];
ull dp[N][S][S];
ull tp[S][S];
int cnt;
queue<int>q;
struct ACauto{
    int t[S][2],val[S],fail[S];
    void ins(int len,int *s){
        int now=0;
        for(int i=1;i<=len;i++){
            int v=s[i];
            if(!t[now][v]) t[now][v]=++cnt;
            now=t[now][v];
        }
        val[now]++;
    }
    void build(){
        for(int i=0;i<2;i++)
			if(t[0][i]) {
        		fail[t[0][i]]=0;
				q.push(t[0][i]);
			}
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=0;i<2;i++) {
            	if(t[u][i]) {
					fail[t[u][i]]=t[fail[u]][i];
					q.push(t[u][i]);
				}
            	else t[u][i]=t[fail[u]][i];
			}
        }
        for(int j=0;j<=cnt;++j){
        	int flag=val[j],i=j;
        	while(i){
        		i=fail[i];
        		flag=max(flag,val[i]);
			}
			val[j]=flag;
			if(val[j]) t[j][0]=t[j][1]=j;
		}
		//for(int i=0;i<=cnt;++i) cout<<t[i][0]<<" "<<t[i][1]<<endl;
    }
}AC;

bool sol(int row){
	bool re=0;
	for(int st=0;st<=cnt;++st){
		fill_n(tp[0],S*S,INF);
		tp[0][st]=0;
		for(int it=1;it<=k[row];++it){
			int h=b[row][it];
			for(int i=0;i<=cnt;++i){
				if(tp[it-1][i]>=INF)
					continue;
				for(int j=0;j<=cnt;++j)
					if(dp[h][i][j]<INF)
						tp[it][j]=min(tp[it][j],tp[it-1][i]+dp[h][i][j]);
			}
		}
		for(int ed=0;ed<=cnt;++ed){
			if(dp[a[row]][st][ed]>tp[k[row]][ed]){
				dp[a[row]][st][ed]=tp[k[row]][ed];
				re=1;
			}
		}
	}
	return re;
}
int main(){
//	freopen("1.in","r",stdin);
//	freopen("1.out","w",stdout);
	scanf("%d%d%d",&G,&n,&m);
	for(int i=1;i<=n;++i){
		scanf("%d%d",&a[i],&k[i]);
		for(int j=1;j<=k[i];++j){
			scanf("%d",&b[i][j]);
		}
	}
	for(int i=1;i<=m;++i){
		scanf("%d",&l[i]);
		for(int j=1;j<=l[i];++j){
			scanf("%d",&c[i][j]);
		}
		AC.ins(l[i],c[i]);
	}
	AC.build();
	fill_n(dp[0][0],N*S*S,INF);
	for(int i=0;i<=cnt;++i){
		for(int h=0;h<2;++h){
			dp[h][i][AC.t[i][h]]=1;
		}
	}
	int flag=1,it=0;
	for(;flag&&it<G-2;++it){
		flag=0;
		for(int i=1;i<=n;++i) flag|=sol(i);
	}
//	cout<<it<<" "<<G-2<<endl;
	for(int i=2;i<G;++i) {
        ull ans=INF;
        for(int j=0;j<=cnt;++j)
			if(!AC.val[j]){
        		ans=min(ans,dp[i][0][j]);
			}
        if(ans<INF) cout<<"NO " <<ans<<endl;
		else cout<<"YES"<<endl;
    }
    return 0;
}
/*
5 3 1
2 2 1 1
3 2 2 2
4 2 3 3
2 1 1

*/

#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0,f=1;char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(isdigit(ch))
	{
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const uint64_t INF=1ull<<63;
struct AhoCorasick{
	int n;
	vector<array<int,2>>go,child;
	vector<int>par,link,terminal;
	AhoCorasick():n(1),child(n+1,{0,0}),par(n+1,0),terminal(n+1,0){};
	inline void addString(vector<int>str)
	{
		int u=1;
		for(int c:str)
		{
			if(!child[u][c])
			{
				child[u][c]=++n;
				child.push_back({0,0});
				par.push_back(u);
				terminal.push_back(false);
			}
			u=child[u][c];
		}
		terminal[u]=true;
	}
	inline void build()
	{
		go.resize(n+1);
		link.resize(n+1);
		queue<int>qu;
		qu.push(1);
		link[1]=1;
		while(!qu.empty())
		{
			int u=qu.front();
			qu.pop();
			if(terminal[link[u]]||terminal[par[u]])terminal[u]=true;
			go[u][0]=(child[u][0]?child[u][0]:(u==1?1:go[link[u]][0]));
			go[u][1]=(child[u][1]?child[u][1]:(u==1?1:go[link[u]][1]));
			for(int c=0;c<2;++c)if(child[u][c])
			{
				int v=child[u][c];
				link[v]=(u==1?1:go[link[u]][c]);
				qu.push(v);
			}
		}
	}
};
int main()
{
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	int G=read(),N=read(),M=read();
	vector<tuple<int,int,int>>muts;
	vector<vector<int>>conOf(G);
	vector<uint64_t>ans(G,INF);
	for(int i=0;i<N;++i)
	{
		int a=read(),cnt=read(),x=read(),y,z;
		if(cnt==1)
		{
			conOf[x].push_back((int)muts.size());
			muts.emplace_back(x,-1,a);
			continue;
		}
		for(int j=1;j<cnt;++j)
		{
			y=read();
			if(j==cnt-1)z=a;
			else
			{
				z=(int)conOf.size();
				conOf.emplace_back();
			}
			conOf[x].push_back((int)muts.size());
			conOf[y].push_back((int)muts.size());
			muts.emplace_back(x,y,z);
			x=z;
		}
	}
	AhoCorasick ac;
	for(int i=0;i<M;++i)
	{
		int cnt=read();
		vector<int>str(cnt);
		for(int&x:str)x=read();
		ac.addString(str);
	}
	ac.build();
	int S=ac.n,H=(int)conOf.size();
	vector<vector<vector<uint64_t>>>dp(H,vector<vector<uint64_t>>(S+1,vector<uint64_t>(S+1,INF)));
	using pq_type=tuple<uint64_t,int,int,int>;
	priority_queue<pq_type,vector<pq_type>,greater<pq_type>>pq;
	for(int u=1;u<=S;++u)if(!ac.terminal[u])for(int k=0;k<2;++k)
	{
		int v=ac.go[u][k];
		if(!ac.terminal[v])
		{
			dp[k][u][v]=1;
			pq.emplace(1,k,u,v);
		}
	}
	int ansLeft=G-2;
	while(!pq.empty()&&ansLeft>0)
	{
		uint64_t dist;
		int u,x,y;
		tie(dist,u,x,y)=pq.top();
		pq.pop();
		if(dist>dp[u][x][y])continue;
		if(1<u&&u<G&&ans[u]>dist)
		{
			--ansLeft;
			ans[u]=dist;
		}
		for(int i:conOf[u])
		{
			int w=get<2>(muts[i]),v=u^get<0>(muts[i])^get<1>(muts[i]);
			if(v==-1)
			{
				if(dp[w][x][y]>dist)pq.emplace(dp[w][x][y]=dist,w,x,y);
				continue;
			}
			if(u==get<0>(muts[i]))for(int z=1;z<=S;++z)if(dp[u][x][y]+dp[v][y][z]<dp[w][x][z])pq.emplace(dp[w][x][z]=dp[u][x][y]+dp[v][y][z],w,x,z);
			if(u==get<1>(muts[i]))for(int z=1;z<=S;++z)if(dp[v][z][x]+dp[u][x][y]<dp[w][z][y])pq.emplace(dp[w][z][y]=dp[v][z][x]+dp[u][x][y],w,z,y);
		}
	}
	for(int i=2;i<G;++i)
	if(ans[i]==INF)cout<<"YES\n";
	else cout<<"NO "<<ans[i]<<'\n';
	return 0;
}
/*
*/

// O(K * L^3 * log)

#include <bits/stdc++.h>

using namespace std;

const int MK = 1000, ML = 51;

namespace AhoCorasick {
	struct node {
		int next[2];
		bool leaf;
		int p;
		char pch;
		int link;
		int go[2];
	};

	node t[ML + 1];
	int sz;

	void readString() {
		int len;
		ignore = scanf("%d", &len);

		int v = 0;
		for (int i = 0, c; i < len; i++) {
			ignore = scanf("%d", &c);

			if (t[v].next[c] == -1) {
				memset(t[sz].next, -1, sizeof t[sz].next);
				memset(t[sz].go, -1, sizeof t[sz].go);
				t[sz].link = -1;
				t[sz].p = v;
				t[sz].pch = c;
				t[v].next[c] = sz++;
			}

			v = t[v].next[c];
		}

		t[v].leaf = true;
	}

	int go(int v, int c);

	int get_link(int v) {
		if (t[v].link == -1) {
			if (v == 0 || t[v].p == 0) t[v].link = 0;
			else t[v].link = go(get_link(t[v].p), t[v].pch);

			get_link(t[v].link);
			if (t[t[v].link].leaf) t[v].leaf = true;
		}

		return t[v].link;
	}

	int go(int v, int c) {
		if (t[v].go[c] == -1) {
			if (t[v].next[c] != -1) t[v].go[c] = t[v].next[c];
			else t[v].go[c] = v == 0 ? 0 : go(get_link(v), c);
		}

		return t[v].go[c];
	}

	int to[ML][2];
	int create(int m) {
		t[0].p = t[0].link = -1;
		memset(t[0].next, -1, sizeof t[0].next);
		memset(t[0].go, -1, sizeof t[0].go);
		sz = 1;

		for (int i = 0; i < m; i++) readString();

		int cnt = 0;
		map<int, int> mp;
		for (int i = 0; i < sz; i++) {
			get_link(i);
			if (t[i].leaf) continue;

			mp[i] = cnt++;
		}

		for (auto p : mp) {
			int v = p.first;
			for (int c = 0; c < 2; c++) {
				int u = go(v, c);
				if (t[u].leaf) to[p.second][c] = -1;
				else to[p.second][c] = mp[u];
			}
		}

		return cnt;
	}
}

typedef unsigned long long ull;

struct Int {
	static const ull INF;

	ull x;

	Int(ull x = INF) : x(x) { }

	Int operator + (const Int& rhs) const {
		if (x == INF || rhs.x == INF) return INF;

		return min(x + rhs.x, INF);
	}

	bool operator < (const Int& rhs) const {
		if (x == INF) return false;
		if (rhs.x == INF) return true;
		return x < rhs.x;
	}
};

const ull Int::INF = 1ULL << 63;

int a[MK], b[3 * MK], firstB[MK], lastB[MK];
vector<int> mutations[MK];

void simplifyMutations(int& n, int g) {
	int it = lastB[n - 1];

	for (int i = 0; i < n; i++) {
		int k = lastB[i] - firstB[i];
		if (k <= 2) continue;

		a[n] = g;
		firstB[n] = firstB[i];
		lastB[n] = lastB[i] - 1;

		firstB[i] = it;
		b[it++] = g;
		b[it++] = b[lastB[i] - 1];
		lastB[i] = it;

		g++;
		n++;
	}

	for (int i = 0; i < n; i++) {
		for (int j = firstB[i]; j < lastB[i]; j++) {
			mutations[b[j]].push_back(i);
		}
	}
}

int L;
Int dp[MK][ML][ML];
set<tuple<ull, int, int, int>> S;

void update(int f, int s, int e, const Int& val) {
	if (val < dp[f][s][e]) {
		if (dp[f][s][e].x != Int::INF) {
			S.erase(make_tuple(dp[f][s][e].x, f, s, e));
		}

		dp[f][s][e] = val;

		S.emplace(val.x, f, s, e);
	}
}

void recalcMutationFast(int mut, int f, int s, int e) {
	int x = a[mut];
	int y = b[firstB[mut]];

	int k = lastB[mut] - firstB[mut];
	if (k == 1) {
		update(x, s, e, dp[y][s][e]);

		return;
	}

	assert(k == 2);

	int z = b[firstB[mut] + 1];

	if (y == f) {
		for (int t = 0; t < L; t++) {
			update(x, s, t, dp[y][s][e] + dp[z][e][t]);
		}
	}

	if (z == f) {
		for (int t = 0; t < L; t++) {
			update(x, t, e, dp[y][t][s] + dp[z][s][e]);
		}
	}
}

int main() {
	int g, n, m;
	ignore = scanf("%d %d %d", &g, &n, &m);

	for (int i = 0, it = 0, k; i < n; i++) {
		ignore = scanf("%d %d", a + i, &k);

		firstB[i] = it;
		for (int j = 0; j < k; j++) {
			ignore = scanf("%d", b + (it++));
		}

		lastB[i] = it;
	}

	simplifyMutations(n, g);

	L = AhoCorasick::create(m);

	for (int s = 0; s < L; s++) {
		for (int c = 0; c < 2; c++) {
			if (AhoCorasick::to[s][c] == -1) continue;

			update(c, s, AhoCorasick::to[s][c], 1);
		}
	}

	while (S.empty() == false) {
		int f, s, e;
		tie(ignore, f, s, e) = *S.begin();

		S.erase(S.begin());

		for (int i : mutations[f]) recalcMutationFast(i, f, s, e);
	}

	for (int i = 2; i < g; i++) {
		Int ans;
		for (int s = 0; s < L; s++)
			for (int e = 0; e < L; e++)
				ans = min(dp[i][s][e], ans);

		if (ans.x == Int::INF) printf("%s\n", "YES");
		else printf("%s %llu\n", "NO", ans.x);
	}

	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ull;

vector<array<int,2>> tree(1);
int terminal[110];

ull inf = (1ull<<63)-1;

int s;
struct Mat {
  vector<ull> data;
  Mat() {
    data.assign(s*s, inf);
  }
};

Mat operator*(const Mat&a, const Mat&b) {
  Mat r;
  for (int i = 0; i < s; i++) {
    for (int k = 0; k < s; k++) {
      for (int j = 0; j < s; j++) {
	//if (a.data[i*s+k] != inf && b.data[k*s+j] != inf)
	r.data[i*s+j] = min(r.data[i*s+j], a.data[i*s+k]+b.data[k*s+j]);
      }
    }
  }
  return r;
}

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
  int g, n, m;
  cin >> g >> n >> m;

  vector<pair<int,vector<int>>> mut;
  vector<vector<vector<int>>> node(g);
  for (int i = 0; i < n; i++) {
    int a, k;
    cin >> a >> k;
    node[a].push_back(vector<int>(k));
    mut.emplace_back(a, vector<int>());
    for (int&v : node[a].back()) {
      cin >> v;
      mut.back().second.push_back(v);
    }
  }

  for (int i = 0; i < m; i++) {
    int k;
    cin >> k;
    int p = 0;
    while (k--) {
      int c;
      cin >> c;
      if (!tree[p][c]) {
	tree[p][c] = tree.size();
	tree.push_back({0,0});
      }
      p = tree[p][c];
    }
    terminal[p] = 1;
  }

  {
    vector<int> link(tree.size());
    queue<int> q;
    q.push(0);
    while (q.size()) {
      int p = q.front();
      q.pop();
      int par = link[p];
      terminal[p] |= terminal[par];
      for (int c : {0,1}) {
	if (!tree[p][c]) {
	  tree[p][c] = tree[par][c];
	} else {
	  link[tree[p][c]] = p ? tree[par][c] : 0;
	  q.push(tree[p][c]);
	}
      }
    }
  }
  s = tree.size();
  for (int p = 0; p < s; p++)
    if (terminal[p]) tree[p][0] = tree[p][1] = p;

  vector<Mat> mat(g);
  for (int c : {0,1}) {
    for (int i = 0; i < s; i++) {
      mat[c].data[i*s+tree[i][c]] = 1;
    }
  }

  vector<int> changed(g,1);
  while (1) {
    int found = 0;
    //random_shuffle(mut.begin(), mut.end());
    vector<int> nchanged(g);
    for (auto&[a,v] : mut) {
      //for (int a = 2; a < g; a++) {
      //for (auto&v : node[a]) {
      int need = 0;
      for (int b : v) if (changed[b]) need = 1;
      if (!need) continue;
      Mat prod = mat[v[0]];
      for (int i = 1; i < (int)v.size(); i++) {
	prod = prod*mat[v[i]];
      }
      for (int i = 0; i < s*s; i++) {
	if (prod.data[i] < mat[a].data[i]) {
	  mat[a].data[i] = prod.data[i];
	  nchanged[a] = 1;
	  found = 1;
	}
      }
      //}
    }
    changed = nchanged;
    if (!found) break;
  }

  for (int a = 2; a < g; a++) {
    ull mi = inf;
    for (int i = 0; i < s; i++) {
      if (!terminal[i])
	mi = min(mi, mat[a].data[i]);
    }
    if (mi < inf) cout << "NO " << mi << endl;
    else cout << "YES" << endl;
  }
}

#include <bits/stdc++.h>
#ifdef local
#define debug(...) qqbx(#__VA_ARGS__, __VA_ARGS__)
#define safe cerr<<__PRETTY_FUNCTION__<<" line "<<__LINE__<<" safe\n"
template<typename H, typename ...T>
void qqbx(const char *s, const H h, T ...args) {
    for(; *s && *s != ','; ++s) if(*s != ' ') std::cerr << *s;
    std::cerr << " = " << h << (sizeof...(T) ? ", " : "\n");
    if constexpr(sizeof...(T)) qqbx(++s, args...);
}
#else
#define debug(...) ((void)0)
#define safe ((void)0)
#endif // local
#define pb emplace_back

using namespace std;
typedef int64_t ll;
const int N = 225, K = 51;

void chkmn(ll &x, ll v) {
    if(v != -1 && (x == -1 || x > v)) x = v;
}
struct AhoCorasick {
    int ch[N][2], tot;
    int isEnd[N], fail[N];
    void ins(vector<int> &s) {
        int now = 0;
        for(int c: s) {
            if(!ch[now][c])
                ch[now][c] = ++tot;
            now = ch[now][c];
        }
        isEnd[now] = true;
    }
    void buildFail() {
        queue<int> q;
        vector<int> tmp;
        for(int c = 0; c < 2; c++) if(ch[0][c]) q.push(ch[0][c]);
        while(!q.empty()) {
            int i = q.front(); q.pop();
            int f = fail[i];
            isEnd[i] |= isEnd[f];
            for(int c = 0; c < 2; c++) {
                if(ch[i][c]) {
                    fail[ch[i][c]] = ch[f][c];
                    q.push(ch[i][c]);
                } else {
                    ch[i][c] = ch[f][c];
                }
            }
        }
    }
    void dfs(int i=0, string s="") {
        cout << s << '\t' << i << '\n';
        for(int c = 0; c < 2; c++) if(ch[i][c]) dfs(ch[i][c], s + char('0'+c));
    }
} AC;
struct Matrix : array<array<ll,K>,K> {
    Matrix(){
        for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) at(i)[j] = -1;
    }
    Matrix& operator+=(const Matrix &rhs) {
        for(int i = 0; i < K; i++) for(int j = 0; j < K; j++) chkmn(at(i)[j], rhs[i][j]);
        return *this;
    }
    Matrix& operator*=(const Matrix &rhs) {
        Matrix lhs = *this;
        *this = Matrix();
        for(int i = 0; i < K; i++) for(int k = 0; k < K; k++) {
            for(int j = 0; j < K; j++) {
                if(lhs[i][k] != -1 && rhs[k][j] != -1) {
                    chkmn(at(i)[j], lhs[i][k] + rhs[k][j]);
                }
            }
        }
        return *this;
    }
};
Matrix dp[N];
vector<vector<int>> code[N];
int vis[N];
void dfs(int i) {
    vis[i] = true;
    Matrix &best = dp[i];
    for(auto &v: code[i]) {
        Matrix now;
        for(int j = 0; j < K; j++) now[j][j] = 0;
        for(int j: v) {
            if(!vis[j]) dfs(j);
            now *= dp[j];
        }
        if(i == 4) {
            debug(dp[0][0][3]);
            debug(dp[3][3][4]);
            debug(now[0][4]);
        }
        best += now;
    }
    /* dp[i] = best; */
}
signed main() {
    ios_base::sync_with_stdio(0), cin.tie(0);
    int g, n, m;
    cin >> g >> n >> m;
    for(int i = 0; i < n; i++) {
        int a, k;
        cin >> a >> k;
        code[a].pb(k);
        for(int &x: code[a].back()) cin >> x;
        /* reverse(code[a].begin(), code[a].end()); */
    }
    for(int i = 0; i < m; i++) {
        int L;
        cin >> L;
        vector<int> w(L);
        for(int &x: w) cin >> x;
        AC.ins(w);
    }
    /* AC.dfs(); */
    AC.buildFail();
    vis[0] = vis[1] = 100;
    for(int c = 0; c < 2; c++) {
        for(int i = 0; i <= AC.tot; i++) {
            int j = AC.ch[i][c];
            if(!AC.isEnd[j]) {
                debug(i, j);
                dp[c][i][j] = 1;
            }
        }
        /* for(int i = 0; i <= AC.tot; i++) for(int j = 0; j <= AC.tot; j++) cout << dp[c][i][j] << " \n"[j==AC.tot]; */
    }
    for(int t = 0; t < 10; t++) {
        for(int i = 2; i < g; i++) {
            dfs(i);
        }
    }
    for(int i = 2; i < g; i++) {
        ll ans = -1;
        for(int c = 0; c <= AC.tot; c++) if(dp[i][0][c] != -1) {
            chkmn(ans, dp[i][0][c]);
        }
        if(ans == -1) cout << "YES\n";
        else cout << "NO " << ans << '\n';
    }
}

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;

struct gene{
    int gInd;
    vector<int> sor;
    vector<vector<vector<bool>>> volt;
};

struct pont{
    int t[2] = {-1, -1};
    int c, os = -1, tav = 0;
    bool veg = false;
};

struct adat{
    int ind, sorInd, kezd, koz, veg;
    long long ert;

    bool operator < (adat a) const{
        return ert > a.ert;
    }
};

long long table[102][51][51];
vector<adat> elek[102][51][51];
int maxn;

vector<pont> trie;

void Init()
{
    trie.push_back(pont());
    return;
}

void Add(vector<int> &v)
{
    int x = 0;
    for(int y : v)
    {
        if(trie[x].t[y] == -1)
        {
            trie[x].t[y] = (int)trie.size();
            trie.push_back(pont());
            trie[trie[x].t[y]].tav = trie[x].tav+1;
            trie[trie[x].t[y]].os = x;
            trie[trie[x].t[y]].c = y;
        }

        x = trie[x].t[y];
    }

    trie[x].veg = true;

    return;
}

bool sortFunc(int a, int b){
    return trie[a].tav < trie[b].tav;
}

void AhoCorasick()
{
    vector<int> sor((int)trie.size()-1);
    for(int i = 0; i < (int)trie.size()-1; i++)
        sor[i] = i+1;

    sort(sor.begin(), sor.end(), sortFunc);

    if(trie[0].t[0] == -1)
        trie[0].t[0] = 0;
    if(trie[0].t[1] == -1)
        trie[0].t[1] = 0;

    for(int x : sor)
    {
        trie[x].os = trie[trie[x].os].os;
        if(trie[x].os == -1)
            trie[x].os = 0;
        else
            trie[x].os = trie[trie[x].os].t[trie[x].c];

        if(trie[x].t[0] == -1)
            trie[x].t[0] = trie[trie[x].os].t[0];
        if(trie[x].t[1] == -1)
            trie[x].t[1] = trie[trie[x].os].t[1];

        trie[x].veg = (trie[x].veg | trie[trie[x].os].veg);
    }

    maxn = trie.size();

    return;
}

void UjElem(vector<gene> &v, priority_queue<adat> &pq, adat d)
{
    if(v[d.ind].volt[d.sorInd][d.kezd][d.veg])
        return;

    if(table[v[d.ind].sor[d.sorInd]][d.koz][d.veg] == -1)
    {
        elek[v[d.ind].sor[d.sorInd]][d.koz][d.veg].push_back(d);
        return;
    }

    d.ert += table[v[d.ind].sor[d.sorInd]][d.koz][d.veg];
    d.sorInd++;

    pq.push(d);

    return;
}

void Megold(vector<gene> &v)
{
    priority_queue<adat> pq;

    for(int i = 0; i < (int)v.size(); i++)
        for(int j = 0; j < maxn; j++)
            for(int k = 0; k < maxn; k++)
                UjElem(v, pq, {i, 0, j, j, k, 0});

    while(pq.size() > 0)
    {
        adat d = pq.top();
        pq.pop();

        if(v[d.ind].volt[d.sorInd-1][d.kezd][d.veg])
            continue;

        v[d.ind].volt[d.sorInd-1][d.kezd][d.veg] = true;

        if(d.sorInd == (int)v[d.ind].sor.size() && (table[v[d.ind].gInd][d.kezd][d.veg] == -1 || d.ert < table[v[d.ind].gInd][d.kezd][d.veg]))
        {
            table[v[d.ind].gInd][d.kezd][d.veg] = d.ert;
            for(adat temp : elek[v[d.ind].gInd][d.kezd][d.veg])
                UjElem(v, pq, temp);

            elek[v[d.ind].gInd][d.kezd][d.veg].clear();

            continue;
        }
        else if(d.sorInd == (int)v[d.ind].sor.size())
            continue;

        for(int i = 0; i < maxn; i++)
        {
            adat d2 = d;

            d2.koz = d.veg;
            d2.veg = i;

            UjElem(v, pq, d2);
        }
    }

    return;
}

int main()
{
    cin.sync_with_stdio(false);
    cin.tie(0);

    int g, n, m;
    cin>>g>>n>>m;

    vector<gene> v(n);
    for(int i = 0; i < n; i++)
    {
        int a;
        cin>>v[i].gInd;
        cin>>a;

        v[i].sor.resize(a);
        for(int j = 0; j < a; j++)
            cin>>v[i].sor[j];
    }

    Init();
    for(int i = 0; i < m; i++)
    {
        int a;
        cin>>a;
        vector<int> sor(a);
        for(int j = 0; j < a; j++)
            cin>>sor[j];

        Add(sor);
    }

    AhoCorasick();

    for(int i = 0; i < n; i++)
        v[i].volt.resize(v[i].sor.size(), vector<vector<bool>>(maxn, vector<bool>(maxn, false)));

    for(int i = 0; i < g; i++)
        for(int j = 0; j < maxn; j++)
            for(int k = 0; k < maxn; k++)
                table[i][j][k] = -1;

    for(int i = 0; i < 2; i++)
        for(int j = 0; j < maxn; j++)
            if(!trie[j].veg && !trie[trie[j].t[i]].veg)
                table[i][j][trie[j].t[i]] = 1;

    Megold(v);

    for(int i = 2; i < g; i++)
    {
        long long legK = -1;
        for(int j = 0; j < maxn; j++)
            if(table[i][0][j] != -1 && (legK == -1 || table[i][0][j] < legK))
                legK = table[i][0][j];

        if(legK == -1)
            cout<<"YES\n";
        else
            cout<<"NO "<<legK<<"\n";
    }

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 105;
const int MAXM = 55;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
namespace ACAutomaton {
	const int MAXN = 55;
	bool key[MAXN]; int fail[MAXN];
	int size, root, child[MAXN][2];
	void insert(int len, int *s) {
		int now = root;
		for (int i = 1; i <= len; i++) {
			if (!child[now][s[i]]) child[now][s[i]] = ++size;
			now = child[now][s[i]];
		}
		key[now] = true;
	}
	void build() {
		static int q[MAXN];
		int l = 0, r = 0;
		while (l <= r) {
			int pos = q[l++];
			for (int i = 0; i <= 1; i++)
				if (child[pos][i]) q[++r] = child[pos][i];
		}
		for (int i = 1; i <= r; i++) {
			int pos = q[i];
			key[pos] |= key[fail[pos]];
			for (int j = 0; j <= 1; j++)
				if (child[pos][j]) fail[child[pos][j]] = child[fail[pos]][j];
				else child[pos][j] = child[fail[pos]][j];
		}
	}
}
int n, m, s, t[MAXN];
vector <int> a[MAXN];
ull dp[MAXN][MAXM][MAXM];
void init() {
	using namespace ACAutomaton; s = size;
	for (int i = 0; i <= n - 1; i++) {
		for (int j = 0; j <= s; j++)
		for (int k = 0; k <= s; k++)
			dp[i][j][k] = -1;
	}
	for (int i = 0; i <= 1; i++)
	for (int j = 0; j <= s; j++)
		if (!key[child[j][i]] && !key[j]) dp[i][j][child[j][i]] = 1;
}
int main() {
	read(n), read(m), read(s);
	for (int i = 1; i <= m; i++) {
		int cnt; read(t[i]), read(cnt);
		for (int j = 1; j <= cnt; j++) {
			int x; read(x);
			a[i].push_back(x);
		}
	}
	for (int i = 1; i <= s; i++) {
		static int t[MAXN];
		int len; read(len);
		for (int j = 1; j <= len; j++)
			read(t[j]);
		ACAutomaton :: insert(len, t);
	}
	ACAutomaton :: build(), init();
	bool changed = true;
	while (changed) {
		changed = false;
		for (int p = 1; p <= m; p++) {
			static ull cur[MAXM][MAXM];
			for (int i = 0; i <= s; i++)
			for (int j = 0; j <= s; j++)
				cur[i][j] = (i == j) ? 0 : -1;
			for (auto x : a[p]) {
				static ull tmp[MAXM][MAXM];
				for (int i = 0; i <= s; i++)
				for (int j = 0; j <= s; j++)
					tmp[i][j] = -1;
				for (int i = 0; i <= s; i++)
				for (int j = 0; j <= s; j++)
					if (cur[i][j] != -1) {
						for (int k = 0; k <= s; k++)
							if (dp[x][j][k] != -1)
								chkmin(tmp[i][k], cur[i][j] + dp[x][j][k]);
					}
				memcpy(cur, tmp, sizeof(tmp));
			}
			for (int i = 0; i <= s; i++)
			for (int j = 0; j <= s; j++)
				if (cur[i][j] < dp[t[p]][i][j]) {
					changed = true;
					dp[t[p]][i][j] = cur[i][j];
				}
		}
	}
	for (int i = 2; i <= n - 1; i++) {
		ull ans = -1;
		for (int j = 0; j <= s; j++)
			chkmin(ans, dp[i][0][j]);
		if (ans == -1) puts("YES");
		else printf("NO %llu\n", ans);
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
#define mp make_pair
#define PI pair<int,int>
#define poly vector<ll>
#define data pair<int,pair<int,int> >
#define mem(a) memset((a),0,sizeof(a))
#define For(i,l,r) for(int i=(int)(l);i<=(int)(r);i++)
#define Rep(i,r,l) for(int i=(int)(r);i>=(int)(l);i--)
#define pb push_back
#define fi first
#define se second
#define SZ(x) ((int)(x.size()))
#define re resize
inline char gc(){
    static char buf[100000],*p1=buf,*p2=buf;
    return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline ll read(){
	ll x = 0; char ch = gc(); bool positive = 1;
	for (; !isdigit(ch); ch = gc())	if (ch == '-')	positive = 0;
	for (; isdigit(ch); ch = gc())	x = x * 10 + ch - '0';
	return positive ? x : -x;
}
inline void write(ll a){
    if(a<0){
    	a=-a; putchar('-');
	}
    if(a>=10)write(a/10);
    putchar('0'+a%10);
}
inline void writeln(ll a){write(a); puts("");}
inline void wri(ll a){write(a); putchar(' ');}
ll rnd(){
	ull ans=0;
	For(i,0,4)ans=ans<<15^rand();
	return ans%((ull)1<<63);
}
const int N=105,M=52;
const ull inf=(ull)1<<63;
int a[N],go[M][2],vis[M],tot=1;
vector<int> v[N];
ull dis[N][M][M],dd[M],ee[M];
int q[M],fail[M];
void buildfail(){
    int l=0,r=1; q[0]=1; fail[1]=0; go[0][1]=go[0][0]=1;
    while(l<r){
    	int now=q[l++]; vis[now]|=vis[fail[now]];
    	For(i,0,1)if(!go[now][i])go[now][i]=go[fail[now]][i];
    	else fail[q[r++]=go[now][i]]=go[fail[now]][i];
	}
}
int main(){
	#ifdef Brollan
		//freopen("1.in","r",stdin);
	#endif
	int g=read()-1,n=read(),m=read();
	For(i,1,n){
		a[i]=read();
		int k=read();
		while(k--)v[i].pb(read());
		//for(auto j:v[i])cx[i][j]=1;
	}
	For(i,1,m){
		int len=read(),p=1;
		For(j,1,len){
			int t=read();
			if(!go[p][t])go[p][t]=++tot;
			p=go[p][t];
		}
		vis[p]=1;
	}
	buildfail();
	For(i,0,g)For(j,1,tot)For(k,1,tot)dis[i][j][k]=inf;
	//priority_queue<data> q;
	For(i,0,1)For(j,1,tot)if(!vis[go[j][i]])dis[i][j][go[j][i]]=1;
	//For(i,1,tot)cout<<i<<" "<<go[i][0]<<" "<<go[i][1]<<endl;
	int f=1;
	while(f){
		f=0;
		For(i,1,n){
			For(o,1,tot)if(!vis[o]){
				For(j,1,tot)dd[j]=inf;
				dd[o]=0;
				for(auto k:v[i]){
					For(j,1,tot)ee[j]=inf;
					For(j,1,tot)if(dd[j]<inf)For(o,1,tot)ee[o]=min(ee[o],dd[j]+dis[k][j][o]);
					memcpy(dd,ee,sizeof(ee));
				}
				For(j,1,tot)if(ee[j]<dis[a[i]][o][j]){
					assert(!vis[j]);
					//if(i==3&&o==1)cout<<i<<" "<<o<<" "<<j<<" "<<ee[j]<<endl;
					dis[a[i]][o][j]=ee[j]; f=1;
				}
			}
		}
	}
	For(o,2,g){
		ull ans=inf;
		For(i,1,tot)ans=min(ans,dis[o][1][i]);
		if(ans==inf)puts("YES"); else cout<<"NO "<<ans<<endl;
	}
}

// M
#include<bits/stdc++.h>
//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("O3")
using namespace std;
typedef long double ld;
typedef unsigned long long ll;
const ll INF = (1LL << 63) + 504;
const int N = 109, MXA = 53, SGM = 2;
int ts, C[MXA][SGM], CC[MXA][SGM], AC[MXA], Suf[MXA];
int n, m, k, A[N];
ll dp[N][MXA][MXA], dpt[2][MXA];
vector < int > B[N];
bool M[N], M2[N], Mark[MXA];
inline void AhoCorasick()
{
	memcpy(CC, C, sizeof(CC));
	queue < int > qu;
	for (int i = 0; i < SGM; i ++)
		if (C[0][i]) qu.push(C[0][i]);
	while (qu.size())
	{
		int id = qu.front(); qu.pop();
		for (int j = 0; j < SGM; j ++)
		{
			if (C[id][j])
				Suf[C[id][j]] = C[Suf[id]][j], qu.push(C[id][j]);
			else
				C[id][j] = C[Suf[id]][j];
		}
		AC[id] |= AC[Suf[id]];
	}
}
void DFS(int v)
{
	if (Mark[v])
		return ;
	Mark[v] = 1; AC[v] = 1;
	if (CC[v][0]) DFS(CC[v][0]);
	if (CC[v][1]) DFS(CC[v][1]);
}
inline bool Relax(int i)
{
	M2[i] = 1;
	int nw = A[i];
	bool rlx = 0;
	for (int j = 0; j <= ts; j ++)
		if (!AC[j])
		{
			for (int h = 0; h <= ts; h ++)
				dpt[0][h] = dpt[1][h] = INF;
			dpt[0][j] = 0;
			int w = 0;
			for (int b : B[i])
			{
				w ^= 1;
				for (int h = 0; h <= ts; h ++)
					dpt[w][h] = INF;
				for (int h = 0; h <= ts; h ++)
					if (!AC[h] && dpt[!w][h] < INF)
					{
						if (b <= 1)
						{
							int nxt = C[h][b];
							if (AC[nxt])
								continue;
							dpt[w][nxt] = min(dpt[w][nxt], dpt[!w][h] + 1);
							continue;
						}
						for (int tobe = 0; tobe <= ts; tobe ++)
							if (!AC[tobe])
							{
								ld val = (ld)dpt[!w][h] + (ld)dp[b][h][tobe];
								if (val < INF && dpt[w][tobe] > val)
									dpt[w][tobe] = (ll)val;
							}
					}
			}
			for (int h = 0; h <= ts; h ++)
				if (!AC[h] && dp[nw][j][h] > dpt[w][h])
					dp[nw][j][h] = dpt[w][h], rlx = 1;
		}
	if (rlx)
		M[nw] = 1;
	return rlx;
}
int main()
{
	scanf("%d%d%d", &k, &n, &m);
	for (int i = 0; i < n; i ++)
	{
		int len;
		scanf("%d%d", &A[i], &len);
		B[i].resize(len);
		for (int j = 0; j < len; j ++)
			scanf("%d", &B[i][j]);
	}
	vector < vector < int > > V;
	for (int i = 0; i < m; i ++)
	{
		int len, a;
		scanf("%d", &len);
		vector < int > vec;
		for (int j = 0; j < len; j ++)
			scanf("%d", &a), vec.push_back(a);
		V.push_back(vec);
	}
	sort(V.begin(), V.end(), [&](auto X, auto Y){return X.size() < Y.size();});
	V.resize(unique(V.begin(), V.end()) - V.begin());
	for (auto vec : V)
	{
		int id = 0;
		for (int a : vec)
		{
			if (!C[id][a])
				C[id][a] = ++ ts;
			id = C[id][a];
			if (AC[id])
				break;
		}
		AC[id] = 1;
	}
	for (int i = 0; i <= ts; i ++)
		if (AC[i])
			assert(!C[i][0] && !C[i][1]);
	AhoCorasick();
	for (int i = 0; i <= ts; i ++)
		if (AC[i]) DFS(i);
	for (int i = 0; i < k; i ++)
		for (int j = 0; j < MXA; j ++)
			for (int h = 0; h < MXA; h ++)
				dp[i][j][h] = INF;
	M2[0] = M2[1] = 1;
	while (true)
	{
		bool Fail = 1;
		memset(M, 0, sizeof(M));
		for (int i = 0; i < n; i ++)
		{
			bool ff = 0;
			for (int b : B[i])
				if (M2[b])
					ff = 1;
			if (ff)
				if (Relax(i))
					Fail = 0;
		}
		if (Fail)
			break;
		memcpy(M2, M, sizeof(M2));
	}
	for (int i = 2; i < k; i ++)
	{
		ll res = INF;
		for (int j = 0; j <= ts; j ++)
			for (int h = 0; h <= ts; h ++)
			{
				if (!AC[h])
					res = min(res, dp[i][j][h]);
			}
		if (res >= INF)
			printf("YES\n");
		else
			printf("NO %llu\n", res);
	}
	return 0;
}