#include <bits/stdc++.h>
using namespace std;
const long long N = 41 * 81 * 300 + 2;
enum ttp { reserved, number, word, no };
struct Trie {
  struct node {
    map<char, long long> nxt;
    ttp final_type = no;
  };
  vector<node> t;
  Trie() { t.resize(1); }
  void add_string(const string& s, ttp type) {
    long long v = 0;
    for (auto c : (s)) {
      if (!t[v].nxt.count(c)) {
        t[v].nxt[c] = t.size();
        t.push_back(node());
      }
      v = t[v].nxt[c];
    }
    t[v].final_type = type;
  }
};
set<string> tok;
Trie all_tokens;
vector<string> lines;
string curr_rep = "a";
ttp token_type[N];
map<string, string> raw_words;
string token_string[N];
long long sz = 0;
Trie res_trie;
long long dp[N];
bool can[N];
string gen_next(string s) {
  long long pos = s.length();
  --pos;
  while (pos >= 0 && s[pos] == 'z') --pos;
  if (pos == -1) {
    string t = "";
    for (auto i = (0); i < (s.length() + 1); i++) t += 'a';
    return t;
  }
  ++s[pos];
  for (auto i = (pos + 1); i < (s.length()); i++) s[i] = 'a';
  return s;
}
bool is_reserved(string s) {
  long long v = 0;
  for (auto c : (s)) {
    if (!res_trie.t[v].nxt.count(c)) return 0;
    v = res_trie.t[v].nxt[c];
  }
  return res_trie.t[v].final_type == reserved;
}
string next_string(string& s) {
  string old = s;
  while (is_reserved(old)) {
    old = gen_next(old);
    s = old;
  }
  do {
    s = gen_next(s);
  } while (is_reserved(s));
  return old;
}
inline bool isnumchar(char c) { return c >= '0' && c <= '9'; }
inline bool iswordchar(char c) {
  return isnumchar(c) || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
         c == '$' || c == '_';
}
string get_word(string s) {
  if (raw_words.count(s))
    return raw_words[s];
  else
    return raw_words[s] = next_string(curr_rep);
}
void first_parse(string s) {
  size_t pos = 0;
  while (pos < s.length()) {
    long long v = 0;
    bool is_word;
    if (s[pos] >= '0' && s[pos] <= '9')
      is_word = false;
    else
      is_word = true;
    long long rpa = 0, wpa = 0;
    if (!is_word) {
      while (pos + wpa < s.length()) {
        if (!isnumchar(s[pos + wpa])) break;
        ++wpa;
      }
    } else {
      while (pos + wpa < s.length()) {
        if (!iswordchar(s[pos + wpa])) break;
        ++wpa;
      }
    }
    long long cu = 0;
    while (pos + cu < s.length()) {
      char c = s[pos + cu];
      if (!res_trie.t[v].nxt.count(c)) break;
      v = res_trie.t[v].nxt[c];
      if (res_trie.t[v].final_type == reserved) rpa = max(rpa, cu + 1);
      ++cu;
    }
    long long len = max(wpa, rpa);
    string token = s.substr(pos, len);
    if (is_word && wpa > rpa) {
      token = get_word(token);
    }
    token_string[sz] = token;
    token_type[sz] = wpa > rpa ? is_word ? word : number : reserved;
    ++sz;
    pos += len;
  }
}
long long from[N];
void upd_dp(long long x, long long y) {
  if (dp[x] == -1 || dp[x] > dp[y] + 1) {
    dp[x] = dp[y] + 1;
    from[x] = y;
  }
}
string sup;
size_t startpos[N];
size_t endpos[N];
vector<long long> can_parse[N];
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  long long n_tokens;
  cin >> n_tokens;
  for (auto i = (0); i < (n_tokens); i++) {
    string s;
    cin >> s;
    for (auto c : (s)) assert(c >= 33);
    tok.insert(s);
    res_trie.add_string(s, reserved);
  }
  string s;
  getline(cin, s);
  for (auto c : (s)) assert(c < 33);
  long long n_lines;
  cin >> n_lines;
  getline(cin, s);
  for (auto i = (0); i < (n_lines); i++) {
    getline(cin, s);
    size_t pos = s.find_first_of('#');
    if (pos != string::npos) s = s.substr(0, pos);
    if (s.empty()) continue;
    lines.push_back(s);
    long long L = s.length();
    vector<string> raw;
    string la = "";
    for (auto j = (0); j < (L); j++) {
      assert(s[j] >= 32);
      if (s[j] == ' ') {
        if (!la.empty()) raw.push_back(la);
        la = "";
      } else
        la += s[j];
    }
    if (!la.empty()) raw.push_back(la);
    for (auto t : (raw)) {
      first_parse(t);
    }
  }
  all_tokens = res_trie;
  for (auto i = (0); i < (sz); i++) {
    startpos[i] = sup.length();
    sup += token_string[i];
  }
  fill(dp + 1, dp + 3 + sz, -1);
  dp[0] = 0;
  long long L = sup.length();
  for (auto i = (L - 1); i >= (0); i--) {
    long long add = 0;
    long long v = 0;
    bool num = 1, wrd = 1;
    if (isnumchar(sup[i])) wrd = 0;
    while (i + add < L) {
      if (!iswordchar(sup[i + add])) wrd = 0;
      if (!isnumchar(sup[i + add])) num = 0;
      if (v != -1 && !all_tokens.t[v].nxt.count(sup[i + add])) v = -1;
      if (v != -1) v = all_tokens.t[v].nxt[sup[i + add]];
      if (wrd || num || (v != -1 && all_tokens.t[v].final_type != no))
        can_parse[i].push_back(i + add + 1);
      ++add;
    }
  }
  endpos[0] = 0;
  for (auto i = (1); i < (sz + 1); i++)
    endpos[i] = startpos[i - 1] + token_string[i - 1].length();
  for (auto i = (0); i < (sz); i++) {
    assert(dp[i] != -1);
    if (dp[i] == -1) continue;
    long long up = (long long)1e9;
    for (auto j = (i + 1); j < (sz + 1); j++) {
      if (up <= endpos[j]) break;
      auto it = upper_bound((can_parse[endpos[j - 1]]).begin(),
                            (can_parse[endpos[j - 1]]).end(), endpos[j]) -
                can_parse[endpos[j - 1]].begin();
      if (it != can_parse[endpos[j - 1]].size()) {
        up = min(up, can_parse[endpos[j - 1]][it]);
      }
      upd_dp(j, i);
    }
  }
  vector<long long> must_space;
  long long v = sz;
  while (v) {
    if (v != sz) must_space.push_back(endpos[v]);
    v = from[v];
  }
  long long ptr = 0;
  reverse((must_space).begin(), (must_space).end());
  for (auto i = (0); i < (L); i++) {
    if (ptr < (long long)must_space.size() && must_space[ptr] == i) {
      cout << ' ';
      ++ptr;
    }
    cout << sup[i];
  }
  return 0;
}
