#include <map>
#include <iostream>
#include <queue>
#include <sstream>
#include <cstdio>
#define REP(i,n) for(int i=0; i<(int)(n); i++)

using namespace std;

enum{
  BINARY_OPERATOR = 0,
  UNARY_OPERATOR  = 1,
  VALUE           = 2
};

struct Tree{
  int type;

  // Identifier, Value or Operator
  string s;

  struct Tree *left;
  struct Tree *right;

  Tree(int t, const string &v, Tree *l = NULL, Tree *r = NULL)
    : type(t), s(v), left(l), right(r) {}

  Tree(int t, char v, Tree *l = NULL, Tree *r = NULL)
    : type(t), left(l), right(r) {
    stringstream ss; ss << v;
    s = ss.str();
  }

  void debug(){
    cout << "(";
    switch(type){
    case BINARY_OPERATOR:
      left->debug();
      cout << s;
      right->debug();
      break;
    case UNARY_OPERATOR:
      cout << s;
      left->debug();
      break;
    case VALUE:
      cout << s;
      break;
    }
    cout << ")";
  }
};

struct Parser{
  const string bop1;
  const string bop2;
  const string uop;

  Parser(const string &b1 = "+-",
         const string &b2 = "*/",
         const string &u = "-")
    : bop1(b1), bop2(b2), uop(u) {}

  typedef pair<Tree *, const char *> P;

  P parseExpr(const char *p) const{
    P r = parseTerm(p);
    while( *r.second != '\0' && bop1.find(*r.second) != string::npos ){
      char op   = *r.second;
      Tree *tmp = r.first;
      r = parseTerm(r.second + 1);
      r.first = new Tree(BINARY_OPERATOR, op, tmp, r.first);
    }
    return r;
  }

  P parseTerm(const char *p) const{
    P r = parseFact(p);
    while( *r.second != '\0' && bop2.find(*r.second) != string::npos ){
      char op   = *r.second;
      Tree *tmp = r.first;
      r = parseFact(r.second + 1);
      r.first = new Tree(BINARY_OPERATOR, op, tmp, r.first);
    }
    return r;
  }

  P parseFact(const char *p) const{
    if(uop.find(*p) != string::npos){
      P r = parseFact(p + 1);
      return P(new Tree(UNARY_OPERATOR, *p, r.first), r.second);
    }else if(*p == '('){
      P r = parseExpr(p + 1);
      if(*r.second != ')') throw make_pair("fact1", p);
      return P(r.first, r.second + 1);
    }else{
      // identifier or value
      int i = 0;
      char buff[256];
      while(*p != '\0' &&
            bop1.find(*p) == string::npos &&
            bop2.find(*p) == string::npos &&
            uop.find(*p)  == string::npos &&
            *p != '(' && *p != ')'){
        buff[i++] = *p++;
      }
      buff[i] = '\0';
      if(i == 0) throw make_pair("fact2", p);
      return P(new Tree(VALUE, string(buff)), p);
    }
  }

  Tree *parse(const string &str) const{
    return parseExpr(str.c_str()).first;
  }
};

int n, m, p;
int d[10][10];
map<string, int> var;

vector<int> check(Tree *t){
  vector<int> ret(n);

  if(t->type == BINARY_OPERATOR){
    vector<int> l = check(t->left);
    vector<int> r = check(t->right);

    if(t->s == "+" || t->s == "-"){
      REP(i,n) if(l[i] != r[i]) throw 0;
      ret = l;
    }else if(t->s == "*"){
      REP(i,n) ret[i] = l[i] + r[i];
    }else if(t->s == "/"){
      REP(i,n) ret[i] = l[i] - r[i];
    }else{
      while(true);
    }

  }else if(t->type == UNARY_OPERATOR){
    ret = check(t->left);
  }else{
    while(var.count(t->s) == 0);
    int id = var[t->s];
    REP(i,n) ret[i] = d[id][i];
  }

  return ret;
}

void f(Tree *t){
  if(t){
    if(t->left) f(t->left);
    if(t->left) f(t->right);
    delete t;
  }
}

int main(){
  while(cin >> n >> m >> p, n + m + p){
    map<string, int> idm;
    vector<string> deriv(m);

    REP(i,m){
      cin >> deriv[i];
      idm[deriv[i]] = i;
      REP(j,n) cin >> d[i][j];
    }

    string formula; cin >> formula;
    Tree *t = Parser().parse(formula);

    var.clear();
    REP(i,p){
      string a, b; cin >> a >> b;
      var[a] = idm[b];
    }

    try{
      vector<int> ret = check(t);

      for(int i = m - 1; i >= 0; i--){
        bool ok = true;
        REP(j,n) if(ret[j] != d[i][j])
          ok = false;
        if(ok){
          cout << deriv[i] << endl;
          goto end;
        }
      }

      cout << "undefined" << endl;
    end:;
    }catch(...){
      cout << "error" << endl;
    }

    f(t);
  }
  return 0;
}

Measured memory_bytes: 0