Problem: The dimension of quantity is a concept that ignores concrete numerical values ​​from the relational expressions between different quantities and focuses only on the type of quantity and its power. Specifically, the relational expression of the dimension is expressed as an equation ignoring the constant coefficient. That is, if the dimension of the quantity q is expressed as [q], the following relational expressions of several dimensions can be exemplified.

* [Area] = [Length] 2
* [Volume] = [Length] 3
* [Speed] = [Length] [Time] -1
* [Acceleration] = [Length] [Time] -2
* [Force] = [Mass] [Length] [Time] -2
* [Work] = [Mass] [Length] 2 [Time] -2



(Excerpt from Wikipedia "Quantity" URL http://ja.wikipedia.org/wiki/%E9%87%8F)

The amount is classified into the basic amount and the assembled amount. In this problem, n basic quantities and m assembly quantities are given. The dimensions of a given m assembly can all be represented by the product of n base unit dimensions. Also, when two dimensions are represented by the product of the dimensions of the basic quantities, it can be said that the two dimensions are equal if all the indices of the basic quantities match.

Given information about the quantity of expressions and variables and the dimension of the quantity, analyze the equation and output the name of the quantity represented by that dimension. If the name is not defined, output undefined. In addition, an operation that adds or subtracts two different dimensions in the calculation process is defined as an "illegal operation". If there is an "illegal operation", output error. The given equation satisfies:

1. All variables are assigned to the assembly dimension.
2. The expression contains only four arithmetic operations +,-, /, *, parentheses () and variables.
3. The four arithmetic operations are well known and shall be described correctly. Strictly speaking, it follows the following BNF. Also, unary operators are not used. There is no such thing as (x * (-a)).




<formula> :: = <term> | <formula> + <term> | <formula>-<term>
<term> :: = <factor> | <term> * <factor> | <term> / <factor>
<factor> :: = <variable> | (<formula>)
<variable> :: = <string>
<string> :: = <char> | <string> <char>
<char> :: = a ~ z | A ~ Z
<formula> represents an expression and <variable> represents a variable name.




Input

The input consists of multiple datasets. The number of datasets does not exceed 1,000. The dataset is given in the following format.


n m p
derived1
d1,1 d1,2 d1,3 .... d1, n
derived2
d2,1 d2,2 d2,3 .... d2, n
...
derivedm
dm, 1 dm, 2 dm, 3 .... dm, n
formula
v1 D1
v2 D2
...
vp Dp


n (1 ≤ n ≤ 5) is the number of basic quantities m (1 ≤ m ≤ 10) is the number of assemblies p (1 ≤ p ≤ 15) is the number of variable types. derivedi is the name of the i-th assembly. It is composed of uppercase and lowercase letters and does not exceed 20 characters in length. di, j (-10 ≤ di, j ≤ 10) represents the dimension of the j-th basic quantity of the i-th assembly (1 ≤ i ≤ m, 1 ≤ j ≤ n). The name of the same assembly does not appear multiple times. The assembly quantity of the same dimension may appear multiple times, in which case the last defined name will be the name of the assembly quantity. formula represents the formula to be analyzed. The length does not exceed 100 characters. vi represents a variable name. It is composed of uppercase and lowercase letters and does not exceed 20 characters in length. Di represents the name of the dimension of vi. It is guaranteed to be the name of the assembly already given. The numbers you are typing (n, m, p, d) are all integers. The end of the input is indicated by a line where each of the three 0s is separated by a single character space.

Output

Analyze the formula in one line and output the name of the dimension. If the name is not defined, output undefined. Also, if an invalid operation is included, output error.

Example

Input

2 3 2
length
1 0
time
0 1
speed
1 -1
a/b
a length
b time
2 3 3
length
1 0
time
0 1
speed
1 -1
a/b+c
a length
b time
c speed
2 3 3
length
1 0
time
0 1
speed
1 -1
a/b+c
a length
b time
c time
2 3 2
length
1 0
time
0 1
speed
1 -1
a/b/b
a length
b time
3 6 6
speed
1 -1 0
acceleration
1 -2 0
force
1 -2 1
length
1 0 0
time
0 1 0
weight
0 0 1
((v+l/t)+a*t)/(t*t)*w*t+f+w*a
v speed
l length
a acceleration
t time
w weight
f force
0 0 0


Output

speed
speed
error
undefined
force

Solution (in CPP):

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


struct Info{
	char name[21];
	int table[5];
};

struct Data{
	char name[21];
	int info_index;
};

int num_base,num_assembly,num_variable;
char formula[101];
Info info[10];
Data data[15];
bool error_FLG;


bool is_alpha(char ch){

	if(ch >= 'a' && ch <= 'z')return true;
	if(ch >= 'A' && ch <= 'Z')return true;

	return false;
}

//baseとcompが等しいか比べる関数
bool strCmp(char* base, char* comp){
	int length1,length2;
	for(length1=0;base[length1] != '\0';length1++);
	for(length2=0;comp[length2] != '\0';length2++);
	if(length1 != length2)return false;

	for(int i=0;base[i] != '\0'; i++){
		if(base[i] != comp[i])return false;
	}
	return true;
}

void strcpy(char* to,char* str){
	for(int i=0;str[i] != '\0';i++){
		to[i] = str[i];
		to[i+1] = '\0';
	}
}

vector<int> calc_Formula(int,int);

vector<int> calc_string(int left,int right){

	char work[21];
	int index = 0;

	for(int i = left; i <= right; i++){
		work[index++] = formula[i];
	}
	work[index] = '\0';

	vector<int> ret;

	//該当する変数があるか調べる
	for(int i = 0; i < num_variable; i++){
		if(strCmp(work,data[i].name)){
			for(int k = 0; k < num_base; k++){
				ret.push_back(info[data[i].info_index].table[k]);
			}
			return ret;
		}
	}

	//該当する変数がないならエラー
	error_FLG = true;
	return ret;
}

vector<int> calc_variable(int left,int right){
	return calc_string(left,right);
}

vector<int> calc_Factor(int left,int right){

	if(formula[left] == '('){
		return calc_Formula(left+1,right-1);
	}

	return calc_variable(left,right);
}

vector<int> calc_Term(int left,int right){

	int depth = 0;
	queue<int> Q;

	//深さ0の*,/を探す
	for(int i = left; i <= right; i++){

		if(formula[i] == '('){
			depth++;
		}else if(formula[i] == ')'){
			depth--;
		}else if(depth == 0 && (formula[i] == '*' || formula[i] == '/')){
			Q.push(i);
		}
	}

	if(Q.size() == 0){
		return calc_Factor(left,right);
	}

	vector<int> ret,tmp;

	ret = calc_Term(left,Q.front()-1);
	if(error_FLG)return ret;


	while(!Q.empty()){

		int loc = Q.front();
		Q.pop();

		if(Q.empty()){
			tmp = calc_Factor(loc+1,right);
		}else{
			tmp = calc_Factor(loc+1,Q.front()-1);
		}

		if(error_FLG)return ret;

		//次元の計算を行う(指数の加減算)
		if(formula[loc] == '*'){

			for(int i = 0; i < num_base; i++){
				ret[i] += tmp[i];
			}

		}else{ //割り算

			for(int i = 0; i < num_base; i++){

				ret[i] -= tmp[i];
			}
		}
	}

	return ret;

}

vector<int> calc_Formula(int left,int right){

	int depth = 0;
	queue<int> Q;

	//深さ0の+,-を探す
	for(int i = left; i <= right; ){

		if(formula[i] == '('){
			depth++;
		}else if(formula[i] == ')'){
			depth--;
		}

		if(depth != 0){
			i++;
		}else if(formula[i] != '+' && formula[i] != '-'){
			i++;
		}else{
			if(formula[i] == '+'){
				Q.push(i);
				i++;
			}else{ //line[i] == '-'
				if((i != left) && (is_alpha(formula[i-1]) == true || formula[i-1] == ')')){ //-は、depthが0でもnegの場合あり
					Q.push(i);
				}
				while(i <=right && formula[i] == '-')i++; //negの-が続いている場合があるので、読み飛ばす
			}
		}

	}

	if(Q.size() == 0){
		return calc_Term(left,right);
	}

	vector<int> ret,tmp;

	ret = calc_Formula(left,Q.front()-1);
	if(error_FLG)return ret;


	while(!Q.empty()){

		int loc = Q.front();
		Q.pop();

		if(Q.empty()){
			tmp = calc_Term(loc+1,right);
		}else{
			tmp = calc_Term(loc+1,Q.front()-1);
		}

		if(error_FLG)return ret;

		//2つの次元が違うなら終了
		for(int i = 0; i < num_base; i++){
			if(ret[i] != tmp[i]){
				error_FLG = true;
				return ret;
			}
		}
		//★係数は無視するので演算は行わない★
	}

	return ret;
}

void func(){

	//組み立て量の取得
	for(int i = 0; i < num_assembly; i++){

		scanf("%s",info[i].name);
		for(int k = 0; k < num_base; k++){
			scanf("%d",&info[i].table[k]);
		}
	}

	int length;

	scanf("%s",formula);

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

	char buf[21];

	for(int i = 0; i < num_variable; i++){

		scanf("%s %s",data[i].name,buf);
		for(int k = 0; k < num_assembly; k++){ //組み立て量を探す
			if(strCmp(buf,info[k].name)){
				data[i].info_index = k;
				break;
			}
		}
	}

	error_FLG = false;

	vector<int> ret = calc_Formula(0,length-1);

	if(error_FLG){
		printf("error\n");
		return;
	}

	bool FLG;
	//該当する次元があるか探す
	for(int i = num_assembly-1; i >= 0; i--){
		FLG = true;
		for(int k = 0; k < num_base; k++){
			if(ret[k] != info[i].table[k]){
				FLG = false;
				break;
			}
		}
		if(FLG){
			printf("%s\n",info[i].name);
			return;
		}
	}

	printf("undefined\n");
}

int main(){

	while(true){

		scanf("%d %d %d",&num_base,&num_assembly,&num_variable);
		if(num_base == 0 && num_assembly == 0 && num_variable == 0)break;

		func();
	}

	return 0;
}