/*
    题意:对于DFA,F(u,c)表示u在输入c后跳到状态F(u,c)
           该DFA有K个状态,给出起点S,还有T个终点和状态转移函数F(u,c)
           问S到T路径长度为N的路径条数        
           不过F(u,c)有些特殊,如果边G[u,c]=1表示从u转到F(u,c)后,
           接下来要用的字母还是c,不是下一个字母

           对于普通的DFA,求从起点到终点的路径条数可以用DP
           dp[n,pos]表示长度为n,从起点到pos的路径条数
           dp[n,pos]+=dp[n-1,pos'] , pos'->pos
           初始dp[0,1]=1
           
           先用dfs处理掉那些特殊边,然后就是普通的DFA了
           在某点沿某条边出发,如果有G(u,c)=1的环,说明永远不会accept,
           否则我们就将这条边指向第一个G(u,c)=0处(E[pos][ch]=dfs(E[pos][ch]))
*/

#include
<cstdio>
#include
<cstring>

typedef 
long long LL;
const int ml=100,base=100000000,nd=8;
int n,m,k,i,j;
struct bignint len,s[ml]; };
void print(bign &bi){
    printf(
"%d",bi.s[bi.len]);
    
for(int i=bi.len-1;i;i--)printf("%08d",bi.s[i]);
}

void fixlen(bign &bi)while(bi.len>1 && !bi.s[bi.len])bi.len--; }
void init(bign &bi){ bi.len=1; memset(bi.s,0,sizeof(bi.s)); }
void init(bign &bi,int a){
    init(bi);
    
while(a){ bi.s[bi.len++]=a%base; a/=base; }
    bi.len
--;
}

int cmp(bign &a,bign &b){
    
if( a.len != b.len ) return a.len-b.len;
    
for(int i=a.len;i;i--)if(a.s[i] != b.s[i]) return a.s[i]-b.s[i];
    
return 0;
}

bign 
operator+(bign &a,bign &b){
    bign c; 
int i; init(c);
    
for(i=1;i<=a.len || i<=b.len || c.s[i];i++){
        c.s[i]
+=a.s[i]+b.s[i];
        c.s[i
+1]=c.s[i]/base; c.s[i]%=base;
    }

    
if(i>1)c.len=i-1;else c.len=1;
    
return c;
}


bool G[1001][27];
int F[1001][27],E[1001][27];//F原来的  E新建的
int Ta[1001];
int K,N,Z,S,TNum;
bign dp[
2][1001],ZERO;

/*dfs是抄的*/
int dfs(int pos,int ch)//check char  for all pos     -1 for cycle , 0 for not check
{
    
if(E[pos][ch]!=-1)
    
{
        
if(!G[pos][ch])//ok
            E[pos][ch]=F[pos][ch];
        
else
        
{
            E[pos][ch]
=-1;
            E[pos][ch]
=dfs(F[pos][ch],ch);//
        }

    }

    
return E[pos][ch];
}


int main()
{
//    freopen("in","r",stdin);
    init(ZERO);
    
int T;
    scanf(
"%d",&T);
    
while(T--)
    
{
        
char str[30];
        scanf(
"%s",str);Z=strlen(str);
        scanf(
"%d%d%d",&K,&S,&TNum);
        
for(int i=0;i<TNum;i++)scanf("%d",&Ta[i]);
        
for(int i=1;i<=K;i++)
            
for(int j=1;j<=Z;j++)
                scanf(
"%d",&F[i][j]);
        memset(E,
0,sizeof(E));//新边,0表示还未定
        for(int i=1;i<=K;i++)
            
for(int j=1;j<=Z;j++)
                scanf(
"%d",&G[i][j]);
        
for(int j=1;j<=Z;j++)        
            
for(int i=1;i<=K;i++)
                
if(!E[i][j])dfs(i,j);
        scanf(
"%d",&N);
        
for(int i=1;i<=K;i++)init(dp[0][i]);
        init(dp[
0][S],1);//S not 1
        for(int n=1;n<=N;n++)
        
{
            
for(int i=1;i<=K;i++)init(dp[n&1][i]);
            
for(int i=1;i<=K;i++)
            
{
                
if(cmp(dp[(n-1)&1][i],ZERO)==0)continue;
                
for(int j=1;j<=Z;j++)
                    
if(E[i][j]>0)dp[n&1][E[i][j]]=dp[n&1][E[i][j]]+dp[(n-1)&1][i];
            }

        }

        bign ans;
        init(ans);
        
for(int i=0;i<TNum;i++)
            ans
=ans+dp[N&1][Ta[i]];
        print(ans);
        puts(
"");
        
if(T)puts("");
    }

    
return 0;
}