#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


typedef vector<int> V;
typedef vector<V> MATRIX;

int N;
int table[26][12][12];
char equation[1001];

MATRIX calc(MATRIX left,MATRIX right){

	MATRIX ret(N,V(N));

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++)ret[i][k] = 0;
	}

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			for(int a = 0; a < N; a++){
				ret[row][col] += left[row][a]*right[a][col];
			}
		}
	}

	return ret;

}

//MULTのT乗を計算する
MATRIX pow(MATRIX MULT,int count){

	MATRIX ret(N,V(N));

	for(int row = 0; row < N; row++){
		for(int col = 0; col < N; col++){
			if(row == col)ret[row][col] = 1;
			else{
				ret[row][col] = 0;
			}
		}
	}

	while(count > 0){
		if(count%2 == 1)ret = calc(ret,MULT);
		MULT = calc(MULT,MULT);
		count /= 2;
	}

	return ret;
}

MATRIX recursive(int left,int right){

	bool is_First = true;
	MATRIX RET(N,V(N)),CALC(N,V(N));
	int num;

	for(int i = left; i <= right; ){

		if(equation[i] >= '0' && equation[i] <= '9'){
			num = 0;
			while(equation[i] >= '0' && equation[i] <= '9'){
				num = 10*num+equation[i]-'0';
				i++;
			}

			if(equation[i] == '('){
				int depth = 0,close_pos;

				for(int k = i; ; k++){
					if(equation[k] == '(')depth++;
					else if(equation[k] == ')'){
						depth--;
						if(depth == 0){
							close_pos = k;
							break;
						}
					}
				}

				CALC = recursive(i+1,close_pos-1);

				CALC = pow(CALC,num);

				if(is_First){ //計算区間で、まだ行列が登場していない場合
					RET = CALC;
					is_First = false;
				}else{ //既に行列が登場している場合は、+で連結されているはず
					RET = calc(RET,CALC);
				}

				i = close_pos+1;

			}else{ //右に単項

				CALC = recursive(i,i);
				CALC = pow(CALC,num);

				if(is_First){ //計算区間で、まだ行列が登場していない場合
					RET = CALC;
					is_First = false;
				}else{ //既に行列が登場している場合は、+で連結されているはず
					RET = calc(RET,CALC);
				}
				i += 1;
			}

		}else if(equation[i] >= 'A' && equation[i] <= 'Z'){
			if(is_First){ //行列が初登場の場合

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						RET[row][col] = table[equation[i]-'A'][row][col];
					}
				}
				is_First = false;

			}else{ // ...+Xの形

				for(int row = 0; row < N; row++){
					for(int col = 0; col < N; col++){
						CALC[row][col] = table[equation[i]-'A'][row][col];
					}
				}

				RET = calc(RET,CALC);

			}
			i++;
		}else{ //equation[i] == '+'
			i++;
		}
	}
	return RET;
}



int main(){

	int K;

	scanf("%d %d",&N,&K);

	for(int i = 0; i < 26; i++){
		for(int k = 0; k < N; k++){
			for(int p = 0; p < N; p++)table[i][k][p] = 0;
		}
	}

	int height,work[N],tmp;
	char buf[2];

	for(int loop = 0; loop < K; loop++){
		scanf("%s %d",buf,&height);

		for(int i = 0; i < N; i++)work[i] = i;

		//あみだくじの情報を計算
		for(int k = 0; k < height-1; k++){
			for(int loc = 0; loc < N-1; loc++){
				scanf("%d",&tmp);
				if(tmp == 1){
					swap(work[loc],work[loc+1]);
				}
			}
		}
		//遷移先を記録
		for(int i = 0; i < N; i++){
			table[buf[0]-'A'][work[i]][i] = 1;
		}
	}

	MATRIX RET(N,V(N));
	int E;
	scanf("%d",&E);

	int length,ans[N];

	for(int loop = 0; loop < E; loop++){
		scanf("%s",equation);

		for(length = 0; equation[length] != '\0'; length++);

		RET = recursive(0,length-1);

		for(int i = 0; i < N; i++){
			for(int k = 0; k < N; k++){
				if(RET[i][k] == 1){
					ans[k] = i;
					break;
				}
			}
		}

		for(int i = 0; i < N-1; i++){
			printf("%d ",ans[i]+1);
		}
		printf("%d\n",ans[N-1]+1);
	}

	return 0;
}




Measured memory_bytes: 3368