/* 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<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>

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';
      }
   }
}

// 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;
}

// 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>
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>
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>
#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;
}

#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";
		}
	}
}

#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"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;
}

#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;

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 <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;
}

#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;
}

#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>
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 <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 <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 <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");
                }
        }
}

#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;
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 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
*/

#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;
  }
}

/*
    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();
}

// 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 <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';
    }
}

/**
    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);
        }
    }
}

#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;
#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;
}

/**
    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<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;
	}
}

#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;
}