#include <bits/stdc++.h>
using namespace std;
map<string, int> table;
map<string, int> var;
struct TPL {
  string pname;
  int n;
  int typ[5];
  TPL(const string n = "a") : pname(n) {}
};
bool comp(TPL t1, TPL t2) {
  if (t1.pname != t2.pname) return t1.pname < t2.pname;
  return t1.n < t2.n;
}
TPL t[1005];
int n;
string ps[5];
int parse(string s) {
  stringstream ss(s);
  int i = 0;
  while (getline(ss, s, ',')) {
    stringstream ss2(s);
    ss2 >> ps[i++];
  }
  return i;
}
void processProcedure(char line[105], int k) {
  string s(line);
  size_t f = s.find("void");
  int i = (int)f + 4;
  while (s[i] == ' ') i++;
  s = s.substr(i);
  i = 0;
  while (isalnum(s[i])) i++;
  t[k] = TPL(s.substr(0, i));
  int i1 = (int)s.find('('), i2 = (int)s.find(')');
  s = s.substr(i1 + 1, i2 - i1 - 1);
  t[k].n = parse(s);
  for (i = 0; i < t[k].n; ++i) t[k].typ[i] = table[ps[i]];
}
bool check(int k) {
  for (int i = 0; i < t[k].n; ++i) {
    if (t[k].typ[i] != 0 && t[k].typ[i] != var[ps[i]]) return false;
  }
  return true;
}
int myLowerBound(string s, int k) {
  int cnt = n, first = 0, step, mid;
  while (cnt > 0) {
    step = cnt / 2;
    mid = first + step;
    if (t[mid].pname < s) {
      cnt -= (step + 1);
      first = mid + 1;
    } else
      cnt = step;
  }
  int low = first;
  if (t[low].pname != s) return 0;
  first = low;
  cnt = n - low;
  while (cnt > 0) {
    step = cnt / 2;
    mid = first + step;
    if (t[mid].pname <= s) {
      cnt -= (step + 1);
      first = mid + 1;
    } else
      cnt = step;
  }
  int high = first - 1;
  cnt = high - low + 1;
  first = low;
  while (cnt > 0) {
    step = cnt / 2;
    mid = first + step;
    if (t[mid].n < k) {
      cnt -= (step + 1);
      first = mid + 1;
    } else
      cnt = step;
  }
  return first;
}
int processCall(char line[105]) {
  string s(line);
  int i = 0;
  while (s[i] == ' ') ++i;
  int start = i;
  while (isalnum(s[i])) i++;
  string name = s.substr(start, i - start);
  int i1 = s.find('('), i2 = s.find(')');
  s = s.substr(i1 + 1, i2 - i1 - 1);
  int k = parse(s);
  int idx = myLowerBound(name, k);
  if (idx == n || t[idx].pname != name || t[idx].n != k) return 0;
  int cnt = 0;
  for (; idx < n && t[idx].pname == name && t[idx].n == k; ++idx) {
    if (check(idx)) cnt++;
  }
  return cnt;
}
int main() {
  table["T"] = 0;
  table["int"] = 1;
  table["string"] = 2;
  table["double"] = 3;
  scanf("%d", &n);
  getchar();
  char line[105];
  int i;
  for (i = 0; i < n; ++i) {
    gets(line);
    processProcedure(line, i);
  }
  sort(t, t + n, comp);
  int m;
  scanf("%d", &m);
  char a[15], b[15];
  for (i = 0; i < m; ++i) {
    scanf("%s %s", a, b);
    var[string(b)] = table[string(a)];
  }
  int k;
  scanf("%d", &k);
  getchar();
  for (i = 0; i < k; ++i) {
    gets(line);
    printf("%d\n", processCall(line));
  }
  return 0;
}
