어느 프로그래밍 대회의 운영진은 비공개 연락에 암호 소프트웨어를 쓰기로 하고, 고급 수학에 기반한 암호를 만들어 달라고 한 회사에 의뢰했습니다.
소프트웨어 프로젝트에서 흔히 그렇듯, 제품은 제때 납품되지 못했습니다. 회사는 마감까지 원래의 암호를 완성하지 못했고, 당분간 훨씬 단순한 치환 암호를 쓰자고 제안했습니다. 운영진은 못마땅했지만 마지못해 이 약한 제품을 당분간 쓰기로 했습니다.
암호화하기 전의 글을 평문, 암호화한 뒤의 글을 암호문이라고 부릅니다.
이 단순한 암호는 쌍들의 집합으로 주어지는 치환 규칙에 따라 평문의 글자를 바꿉니다. 하나의 쌍은 두 글자로 이루어지며 순서가 없어서, 쌍 (A, B)와 쌍 (B, A)는 완전히 같은 뜻입니다. 하나의 치환 규칙에서 각 글자는 최대 한 개의 쌍에만 나타날 수 있습니다. 어떤 쌍에 속한 글자가 평문에 나타나면 그 글자는 같은 쌍의 다른 글자로 바뀌고, 어떤 쌍에도 속하지 않은 글자는 그대로 남습니다.
예를 들어 규칙 {(A, Z), (B, Y)}를 평문
ABCDEFGHIJKLMNOPQRSTUVWXYZ
에 적용하면 다음 암호문이 됩니다.
ZYCDEFGHIJKLMNOPQRSTUVWXBA
이 치환 암호는 약하기 때문에 운영진의 메시지를 읽어낼 여지가 있습니다. 주어진 암호문에서 평문을 복원하는 프로그램을 작성하세요.
암호문 메시지는 하나 이상의 암호문 단어로 이루어집니다. 각 암호문 단어는 메시지 전체에 공통으로 적용되는 하나의 치환 규칙으로 어떤 평문 단어에서 만들어집니다. 또한 후보 단어 목록이 주어집니다. 모든 평문 단어는 반드시 이 목록에서 나와야 하며, 목록에 없는 단어는 나타날 수 없습니다. 목록의 어떤 단어는 실제로 쓰이지 않을 수도 있습니다.
주어진 암호문이 어떤 치환 규칙으로 만들어지는 후보 단어들의 수열이 적어도 하나 존재함이 보장됩니다. 다만 암호문과 후보 목록만으로 평문을 언제나 유일하게 정할 수 있는 것은 아닙니다.
입력은 여러 개의 데이터셋으로 이루어집니다. 각 데이터셋은 하나의 암호문 메시지와 후보 단어 목록을 다음 형식으로 담습니다.
n
word_1
...
word_n
sequence
첫 줄에는 후보 단어의 개수인 양의 정수 $n$이 있습니다. 이어지는 $n$개의 줄에는 각각 후보 단어가 하나씩 있습니다. 마지막 줄 sequence는 하나 이상의 암호문 단어를 한 칸 공백으로 구분하고 마침표로 끝낸 것입니다.
각 sequence 줄은 공백과 끝의 마침표를 포함해 $1$보다 크고 $80$ 이하의 문자를 가진다고 가정해도 됩니다. 후보 단어의 개수는 $1 \le n \le 20$을 만족합니다. 단어에는 $26$개의 대문자 A부터 Z까지만 쓰이며, 각 단어의 길이는 $1$ 이상 $20$ 이하입니다.
$0$ 하나만 있는 줄은 입력의 끝을 나타내며 어떤 데이터셋에도 포함되지 않습니다.
각 데이터셋에 대해 복원한 메시지를 한 줄에 출력하세요. 복원한 평문 단어들을 한 칸 공백으로 구분하고, 마지막 단어 바로 뒤에 (앞에 공백 없이) 마침표 하나를 붙입니다. 평문을 유일하게 정할 수 없으면 대신 하이픈 하나에 마침표를 붙인 -.를 출력하세요.