#include <bits/stdc++.h>
using namespace std;
const long long LINF = 1e18 + 7;
const int N = 1e3 + 7;
const int INF = 1e9 + 7;
const int MOD = 1e9 + 7;
const double PI = acos(-1.0);
const double EPS = 1e-8;
const string var[] = {"T", "int", "string", "double"};
int n, m, k;
struct Node {
  int val;
  string name;
  Node() {}
  Node(int _v, string _n) { val = _v, name = _n; }
  bool operator<(const Node &p) const { return name < p.name; }
} a[N];
int l[N], r[N];
vector<string> S;
map<string, int> V;
void trim(string &s) {
  s.erase(0, s.find_first_not_of(' '));
  s.erase(s.find_last_not_of(' ') + 1);
}
int get(const string &str) {
  for (int i = (0); i < (4); ++i)
    if (str == var[i]) return (i > 0) << (i - 1);
  return 0;
}
vector<string> split(const string &str, string S) {
  vector<string> ret;
  for (int i = 0, j; i < str.length(); i = j) {
    j = i + 1;
    if (!~S.find(str[i])) {
      stringstream ss;
      ss << str[i];
      while (j < str.length() && !~S.find(str[j])) ss << str[j++];
      ret.push_back(ss.str());
    }
  }
  return ret;
}
void rPro(const string &str, Node &nd) {
  vector<string> ret = split(str, " ,()");
  nd.name = ret[1], nd.val = 0;
  for (int i = (2); i < (((int)(ret).size())); ++i)
    nd.val = (nd.val << 3) | get(ret[i]);
  nd.val |= 1 << (((int)(ret).size()) - 3) << 15;
}
void rVar(const string &str) {
  vector<string> ret = split(str, " ");
  V[ret[1]] = get(ret[0]);
}
void rCal(const string &str, Node &nd) {
  vector<string> ret = split(str, " ,()");
  nd.name = ret[0], nd.val = 0;
  for (int i = (1); i < (((int)(ret).size())); ++i)
    nd.val = (nd.val << 3) | V[ret[i]];
  nd.val |= 1 << (((int)(ret).size()) - 2) << 15;
}
int main() {
  string str;
  (cin >> n).get();
  for (int i = (0); i < (n); ++i) {
    getline(cin, str);
    rPro(str, a[i]);
    S.push_back(a[i].name);
  }
  sort(a, a + n);
  sort(S.begin(), S.end());
  S.erase(unique(S.begin(), S.end()), S.end());
  int last = -1;
  for (int i = (0); i < (((int)(S).size())); ++i) {
    l[i] = r[i] = last + 1;
    while (r[i] + 1 < n && a[r[i] + 1].name == S[i]) ++r[i];
    last = r[i];
  }
  (cin >> m).get();
  for (int i = (0); i < (m); ++i) {
    getline(cin, str);
    rVar(str);
  }
  (cin >> k).get();
  for (int _k = (0); _k < (k); ++_k) {
    Node nd;
    getline(cin, str);
    rCal(str, nd);
    int ans = 0, p = lower_bound(S.begin(), S.end(), nd.name) - S.begin();
    if (0 <= p && p < ((int)(S).size()) && S[p] == nd.name)
      for (int i = (l[p]); i < (r[p] + 1); ++i)
        ans += ((a[i].val | nd.val) == nd.val);
    cout << ans << endl;
  }
  return 0;
}
