program a;

const

  KMAX = 1000;
  WLEN = 20;
  NMAX = 1000;
  QSIZE = WLEN*100;  (* размер массива состояний (с запасом) *)

type

  TWord = String[20];

  PNode = ^TNode;
  TNode = packed record
    c: char;
    right_sibling: PNode;
    first_child: PNode;
    w_num: Word;          (* номер слова в словаре или 0, если состояние не является концом слова *)
  end;

  TState = record
    t: PNode;
    w: Word;
    f: boolean;
  end;

  TMemArray = array[0..60000] of Byte;

var

  (* исходные данные *)
  K,N: Integer;
  words: array[1..KMAX] of TWord;

  (* луч *)
  root: PNode;

  (* вспомогательные переменные для поиска в луче *)
  q1,q2: array[1..QSIZE] of TState;
  qN1, qN2: Integer;
  ws: array[1..KMAX] of boolean;
  exact_word_found: boolean;
  any_word_found: boolean;

  (* всяко-разное *)
  i,j,l,str_word_num: Integer;
  w: TWord;
  s: String;

var
 p: ^TMemArray;
 pind: Word;

procedure mygetmem(var pt: PNode; size:Word);
begin
  if p=nil then begin
    new(p);
    pind := 0;
  end 
  else
  if pind+size>60000 then begin
    new(p);
    pind := 0;
  end;
 Pt := @p^[pind];
 pind := pind + size;
end;

procedure AddToTrie(const w: String; word_num: Integer);
var
  p,q: PNode;
  i: Integer;
begin
  p := root;
  for i:=1 to length(w) do
  begin
    q := p^.first_child;
    while q<>nil do if q^.c = w[i] then break else q:=q^.right_sibling;
    if q<>nil then
      p:=q
    else
    begin
      MyGetMem(q,sizeof(TNode));
      q^.c := w[i];
      q^.first_child := nil;
      q^.right_sibling := p^.first_child;
      p^.first_child := q;
      q^.w_num := 0;
      p:=q;
    end;
  end;
  p^.w_num := word_num;
end;

function NextTriePos(t:PNode; ch:char): PNode;
var
  q: PNode;
begin
  q := t^.first_child;
  while q<>nil do if q^.c = ch then break else q:=q^.right_sibling;
  NextTriePos := q;
end;

procedure DoWord(const wrd: TWord);
var
  w: TWord;
  i: Integer;
  q,qq: PNode;
begin
  Fillchar(ws,sizeof(ws),0); exact_word_found := false; any_word_found := false;
  w := wrd;
  for i:=1 to length(w) do
    if w[i] in ['A'..'Z'] then w[i] := chr(ord('a')+ord(w[i])-ord('A'));

  qN2 := 1;
  q2[qN2].t := root;
  q2[qN2].w := 1;
  q2[qN2].f := false;

  while qN2>0 do begin

    q1 := q2;
    qN1 := qN2;
    qN2 := 0;

    for i:=1 to qN1 do
    begin

      (*проверяем, не найдено ли уже что-нибудь*)
      if(q1[i].w=length(w)+1)then
      begin
        if q1[i].t^.w_num > 0 then
        begin
          if not q1[i].f then begin
            exact_word_found := true;
            exit;
          end;
          any_word_found := true;
          ws[q1[i].t^.w_num] := true;
          continue;
        end;
      end;

      (*если состояние с ошибкой, то просто ищем следующее состояние в луче по очередному символу*)
      if q1[i].f then
      begin
        if q1[i].w<=length(w) then
        begin
         q := NextTriePos(q1[i].t,w[q1[i].w]);
         if q<>nil then begin
           inc(qN2);
           q2[qN2].t := q;
           q2[qN2].w := q1[i].w+1;
           q2[qN2].f := true;
         end;
        end;
        continue;
      end;

      (*а если состояние не с ошибкой, то пробуем делать всевозможные ошибки*)

      (*ошибка типа "вставка символа"*)
      if q1[i].w<=length(w) then
      begin
        inc(qN2);
        q2[qN2] := q1[i];
        inc(q2[qN2].w);
        q2[qN2].f := true;
      end;  

      (*ошибка типа "перестановка соседних символов"*)
      if q1[i].w<length(w) then
      begin
        q:=NextTriePos(q1[i].t,w[q1[i].w+1]);
        if q<>nil then
        begin
          qq:=NextTriePos(q,w[q1[i].w]);
          if qq<>nil then
          begin
            inc(qN2);
            q2[qN2].t := qq;
            q2[qN2].w := q1[i].w+2;
            q2[qN2].f := true;
          end;
        end;
      end;

      (*ошибки типа "замена символа"*)
      if q1[i].w<=length(w) then
      begin
        q := q1[i].t^.first_child;
        while(q<>nil) do
        begin
          (*ошибка типа "замена символа"*)
          inc(qN2);
          q2[qN2].t := q;
          q2[qN2].w := q1[i].w+1;
          if w[q1[i].w]=q^.c then q2[qN2].f := false else q2[qN2].f := true;
          q:=q^.right_sibling;
        end;
      end;

      (*ошибки типа "пропуск символа"*)
      q := q1[i].t^.first_child;
      while(q<>nil) do
      begin
        (*ошибка типа "пропуск символа"*)
        inc(qN2);
        q2[qN2].t := q;
        q2[qN2].w := q1[i].w;
        q2[qN2].f := true;
        q:=q^.right_sibling;
      end;

    end;

  end;

end;

begin

  pind := 0;
  p:=nil;

  assign(input,'input.txt');
  reset(input);
  assign(output,'output.txt');
  rewrite(output);

  MyGetMem(root,sizeof(TNode));
  fillchar(root^,sizeof(TNode),0);
  readln(K);
  for i:=1 to K do begin
    readln(words[i]);
    AddToTrie(words[i],i);
  end;

  readln(N);
  for i:=1 to N do begin
    readln(s);
    str_word_num := 0;
    j := 1;
    while j<=length(s) do
    begin
      while j<=length(s) do if not ( ((s[j]>='A')and(s[j]<='Z'))or((s[j]>='a')and(s[j]<='z')) ) then inc(j) else break;
      w := '';
      while j<=length(s) do
      begin
      if not ( ((s[j]>='A')and(s[j]<='Z'))or((s[j]>='a')and(s[j]<='z')) ) then break;
        w := w+s[j]; inc(j);
      end;
      if w='' then continue;
      inc(str_word_num);
      DoWord(w);
      if exact_word_found then continue;
      write(w,' ',i,' ',str_word_num);
      if not any_word_found then
      begin
        writeln(' NO VARIANTS');
        continue;
      end;
      for l:=1 to K do
        if ws[l] then write(' ',words[l]);
      writeln;
    end;
  end;

end.
