Problem:
Rotate and Rewrite

Two sequences of integers
A: A1 A2 ... An and
B: B1 B2 ... Bm and
a set of rewriting rules of the form
"x1 x2 ... xk → y"
are given.
The following transformations on each of the sequences are allowed
an arbitrary number of times in an arbitrary order independently.

Rotate:
Moving the first element of a sequence to the last.
That is, transforming a sequence c1 c2 ... cp
to c2 ... cp c1.

Rewrite:
With a rewriting rule
"x1 x2 ... xk → y",
transforming a sequence
c1 c2 ... ci x1 x2 ... xk d1 d2 ... dj
to
c1 c2 ... ci y d1 d2 ... dj.

Your task is to determine whether it is possible to transform the two sequences A and B into the same sequence.
If possible, compute the length of the longest of the sequences after such a transformation.

Input

The input consists of multiple datasets. Each dataset has the following form.

n m r

A1 A2 ... An

B1 B2 ... Bm

R1

...

Rr

The first line of a dataset consists of three positive integers n, m, and r,
where
n (n ≤ 25) is the length of the sequence A,
m (m ≤ 25) is the length of the sequence B, and
r (r ≤ 60) is the number of rewriting rules.
The second line contains n integers representing the n elements of A.
The third line contains m integers representing the m elements of B.
Each of the last r lines describes a rewriting rule in the following form.

k x1 x2 ... xk y

The first k is an integer (2 ≤ k ≤ 10), which is the length of the left-hand side of the rule.
It is followed by k integers x1 x2 ... xk,
representing the left-hand side of the rule.
Finally comes an integer y, representing the right-hand side.

All of A1, .., An, B1, ..., Bm, x1, ..., xk, and y
are in the range between 1 and 30, inclusive.

A line "0 0 0" denotes the end of the input.

Output

For each dataset, if it is possible to transform A and B
to the same sequence, print the length of the longest of
the sequences after such a transformation.
Print -1 if it is impossible.

Sample Input

3 3 3
1 2 3
4 5 6
2 1 2 5
2 6 4 3
2 5 3 1
3 3 2
1 1 1
2 2 1
2 1 1 2
2 2 2 1
7 1 2
1 1 2 1 4 1 2
4
3 1 4 1 4
3 2 4 2 4
16 14 5
2 1 2 2 1 3 2 1 3 2 2 1 1 3 1 2
2 1 3 1 1 2 3 1 2 2 2 2 1 3
2 3 1 3
3 2 2 2 1
3 2 2 1 2
3 1 2 2 2
4 2 1 2 2 2
0 0 0

Output for the Sample Input

2
-1
1
9

Solution in C++ (judge verdict: Time Limit Exceeded)

#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define pb(a) push_back(a)
#define mp(a,b) make_pair(a,b)
#define ALL(a) (a).begin(),(a).end()
#define SZ(a) ((int)(a).size())
#define F first
#define S second
typedef pair<int,int> PI;

int n,m,r;
int a[100];
int b[100];

vector<int> xx[100];
int y[100];

bool become(int,int,int);
bool become2(int,int,int);

signed char eatmemo[55][55][60][11];
bool eat(int as,int at,int ridx,int s){
  if(as>=n){
    as -= n;
    at -= n;
  }
  
  signed char& ret=eatmemo[as][at][ridx][s];
  if(ret != -1)
    return ret;

  if(at-as < SZ(xx[ridx])-s-1)
    return ret = 0;
  
  if(as==at)
    return
      ret=(s==SZ(xx[ridx]));
  
  if(s==SZ(xx[ridx]))
    return
      ret=0;
  
  if(s==SZ(xx[ridx])-1)
    return
      ret=become(as,at,xx[ridx][s]);  
  
  //cout << "e " << as << " " << at << " " << ridx << " " << s << endl;
  
  for(int nas=as+1;nas<at;++nas)
    if(become(as,nas,xx[ridx][s]) && eat(nas,at,ridx,s+1)){
      //cout << "e " << as << " " << at << " " << ridx << " " << s << endl;
      return
        ret=1;
    }
  
  return
    ret=0;
}

signed char eatmemo2[55][55][60][11];
bool eat2(int as,int at,int ridx,int s){
  if(as>=m){
    as -= m;
    at -= m;
  }
  
  signed char& ret=eatmemo2[as][at][ridx][s];
  if(ret != -1) return ret;

  if(at-as < SZ(xx[ridx])-s-1)
    return ret = 0;
  
  if(as==at)
    return
      ret=(s==SZ(xx[ridx]));
  
  if(s==SZ(xx[ridx]))
    return
      ret=0;
  
  if(s==SZ(xx[ridx])-1)
    return
      ret=become2(as,at,xx[ridx][s]);
  
  for(int nas=as+1;nas<at;++nas)
    if(become2(as,nas,xx[ridx][s]) &&
       eat2(nas,at,ridx,s+1))
      return
        ret=1;
  
  return
    ret=0;
}

signed char becmemo[60][60][33];

bool become(int as,int at,int to){
  if(as>=n){
    as -= n;
    at -= n;
  }
  
  signed char& ret=becmemo[as][at][to];
  if(ret != -1) return ret;
  //ret = 0;  
  if(as+1 == at)
    return
      ret=(a[as]==to);
  //cout << "b " << as << " " << at << " " << to << endl;
  
  rep(i,r)
    if(y[i]==to && SZ(xx[i]) <= at-as && eat(as,at,i,0)){
      //cout << "b " << as << " " << at << " " << to << endl;      
      return
        ret=1;
    }
  return
    ret=0;
}

signed char becmemo2[60][60][33];

bool become2(int as,int at,int to){
  if(as>=m){
    as -= m;
    at -= m;
  }
    
  signed char& ret=becmemo2[as][at][to];
  
  if(ret != -1) return ret;
  //ret = 0;
  if(as+1 == at)
    return
      ret=(b[as]==to);
  
  rep(i,r)
    if(y[i]==to && SZ(xx[i]) <= at-as && 
       eat2(as,at,i,0)){
      //cout << "b2 " << as << " " << at << " " << to << endl;
      return
        ret=1;
    }
  
  return
    ret=0;
}

signed char tosmemo[51][51][51][51];

bool tosame(int as,int at,int bs,int bt){
  if(as>=n){
    as -= n;
    at -= n;
  }

  if(bs >= m){
    bs -= m;
    bt -= m;
  }
  
  signed char& ret=tosmemo[as][at][bs][bt];
  if(ret != -1) return ret;
  //cout << as << " " << at << " " << bs << " " << bt << " "  << endl;
  
  for(int i=1;i<=30;++i)
    if(become(as,at,i) && become2(bs,bt,i)){
      //cout << as << " " << at << " " << bs << " " << bt << " " << i << endl;
      return
        ret=1;
    }
  
  return
    ret=0;
}

int okmemo[51][51][51][51];
int okvis[51][51][51][51];


bool ok(int as,int at,int bs,int bt,int len){
  if(as>=n){
    as -= n;
    at -= n;
  }

  if(bs >= m){
    bs -= m;
    bt -= m;
  }

  
  if(as==at && bs==bt && len==0) return 1;
  int ret=(okmemo[as][at][bs][bt]>>len)&1;
  int vi=(okvis[as][at][bs][bt]>>len)&1;
  if(vi) return ret;
  okvis[as][at][bs][bt] |= 1 << len;
  //if(ret != -1) return ret;
  //cout << "fok" << endl;
  for(int nas=as+1;nas<=at;++nas){
    for(int nbs=bs+1;nbs<=bt;++nbs){
      if(tosame(as,nas,bs,nbs) &&
         ok(nas,at,nbs,bt,len-1)){
        okmemo[as][at][bs][bt] |= 1 << len;
        return 1;
      }
    }
  }
  
  return 0;
}

bool oklen(int as,int bs,int len){
  return ok(as,as+n,bs,bs+m,len);
}

int sol(int as,int bs,int cans){
  //cout << "fsol" << endl;
  for(int i=min(n,m);i>cans;--i)
    if(oklen(as,bs,i))
      return i;
  
  return -1;
}

void solve(){
  rep(i,n) cin >> a[i];
  rep(i,m) cin >> b[i];

  rep(i,n-1) a[i+n]=a[i];
  rep(i,m-1) b[i+m]=b[i];
  
  rep(i,r){
    int k;
    cin >> k;
    xx[i].resize(k);
    rep(j,k) cin >> xx[i][j];
    cin >> y[i];
  }
  
  int ans=-1;
#define m1(a) memset(a,-1,sizeof(a));
#define m0(a) memset(a,0,sizeof(a));
  m1(eatmemo);
  m1(eatmemo2);
  m1(becmemo);
  m1(becmemo2);
  m1(tosmemo);
  m0(okmemo);
  m0(okvis);
  
  
  for(int len=min(n,m);len>0;--len){
    rep(i,n)rep(j,m)if(oklen(i,j,len)){
      cout << len << endl;
      return;
    }
  }
  
  //rep(i,n)rep(j,m) ans = max(ans,sol(i,j,ans==-1?0:ans));
  
  cout << ans << endl;
}

int main(){
  while(cin >> n >> m >> r && n) solve();
}