Problem:
Problem C:
Weaker than Planned
The committee members of the Kitoshima programming contest had decided to use crypto-graphic software for their secret communication. They had asked a company, Kodai Software,
to develop cryptographic software that employed a cipher based on highly sophisticated mathematics.
According to reports on IT projects, many projects are not delivered on time, on budget, with
required features and functions. This applied to this case. Kodai Software failed to implement
the cipher by the appointed date of delivery, and asked to use a simpler version that employed
a type of substitution cipher for the moment. The committee members got angry and strongly
requested to deliver the full specification product, but they unwillingly decided to use this inferior
product for the moment.
In what follows, we call the text before encryption, plaintext, and the text after encryption,
ciphertext
.
This simple cipher substitutes letters in the plaintext, and its substitution rule is specified with
a set of pairs. A pair consists of two letters and is unordered, that is, the order of the letters
in the pair does not matter. A pair (A, B) and a pair (B, A) have the same meaning. In one
substitution rule, one letter can appear in at most one single pair. When a letter in a pair
appears in the plaintext, the letter is replaced with the other letter in the pair. Letters not
specified in any pairs are left as they are.
For example, by substituting the plaintext
ABCDEFGHIJKLMNOPQRSTUVWXYZ
with the substitution rule {(A, Z), (B, Y)} results in the following ciphertext.
ZYCDEFGHIJKLMNOPQRSTUVWXBA
This may be a big chance for us, because the substitution rule seems weak against cracking.
We may be able to know communications between committee members. The mission here is to
develop a deciphering program that finds the plaintext messages from given ciphertext messages.
A ciphertext message is composed of one or more ciphertext words. A ciphertext word is
generated from a plaintext word with a substitution rule. You have a list of candidate words 
containing the words that can appear in the plaintext; no other words may appear. Some words
in the list may not actually be used in the plaintext.
There always exists at least one sequence of candidate words from which the given ciphertext
is obtained by some substitution rule. There may be cases where it is impossible to uniquely
identify the plaintext from a given ciphertext and the list of candidate words.
Input
The input consists of multiple datasets, each of which contains a ciphertext message and a list
of candidate words in the following format.
n
word
1
.
.
.
word
n
sequence
n
in the first line is a positive integer, representing the number of candidate words. Each of the
next
n
lines represents one of the candidate words. The last line, sequence, is a sequence of one
or more ciphertext words separated by a single space and terminated with a period.
You may assume the number of characters in each
sequ
...(truncated)

Submitted solutions:

code_snippet: #ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
template <class T = int>
using V = vector<T>;


#define repname(a, b, c, d, ...) d
#define rep(...)                 repname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i, l, r)            for(int i = (l); i < (r); i++)
#define REP1(i, x)               REP2(i, 0, x)
#define REP0(x)                  REP1(SPJ, x)
#define all(v)                   (v).begin(), (v).end()
#define sz(v)                    (int)(v).size()

constexpr int inf = 1e9;
constexpr ll INF = 1e18;

template <class T>
bool chmin(T &a, const T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
bool chmax(T &a, const T b) {
	return a < b ? a = b, 1 : 0;
}

void solve(int n) {
	vector<string> w(n), c;
	rep(i, n) {
		cin >> w[i];
	}
	while(1) {
		string s;
		cin >> s;
		c.push_back(s);
		if(c.back().back() == '.') {
			c.back().pop_back();
			break;
		}
	}
	int m = sz(c);
	vector<vector<string>> lef(21), rig(21);
	rep(i, n) lef[sz(w[i])].push_back(w[i]);
	rep(i, m) rig[sz(c[i])].push_back(c[i]);


	vector<vi> res;
	auto dfs = [&](auto dfs, vi &used, vi &f) -> void {
		if(sz(res) > 1) return;
		int mx = -1, nx = -1;
		rep(i, m) {
			if(used[i]) continue;
			set<char> st;
			rep(j, sz(c[i])) {
				if(f[c[i][j] - 'A'] == -1) {
					st.insert(c[i][j]);
				}
			}
			if(chmax(mx, sz(st))) {
				nx = i;
			}
		}
		if(nx == -1) {
			res.push_back(f);
			return;
		}
		auto str = c[nx];
		rep(j, sz(lef[sz(str)])) {
			if(sz(res) > 1) return;
			bool ok = 1;
			auto nf = f;
			rep(k, sz(str)) {
				auto L = lef[sz(str)][j][k] - 'A';
				auto R = str[k] - 'A';
				if(nf[L] != -1 and nf[L] != R) {
					ok = 0;
					break;
				}
				if(nf[R] != -1 and nf[R] != L) {
					ok = 0;
					break;
				}
				nf[R] = L;
				nf[L] = R;
			}
			if(ok) {
				auto nu = used;
				nu[nx] = 1;
				dfs(dfs, nu, nf);
			}
		}
		return;
	};

	vi f(26, -1), used(m);

	dfs(dfs, used, f);

	if(sz(res) > 1) {
		cout << "-.\n";
		return;
	}
	f = res[0];
	rep(i, m) {
		rep(j, sz(c[i])) {
			auto C = c[i][j] - 'A';
			c[i][j] = 'A' + f[C];
		}
		cout << c[i];
		if(i != m - 1)
			cout << ' ';
		else
			cout << ".\n";
	}
}

int main() {
	int n;
	while(cin >> n, n) solve(n);
}
accuracy: 1
time_ms: 7740
memory_kb: 3320
final_rank: 19

code_snippet: #ifdef LOCAL
#define _GLIBCXX_DEBUG
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
template <class T = int>
using V = vector<T>;


#define repname(a, b, c, d, ...) d
#define rep(...)                 repname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i, l, r)            for(int i = (l); i < (r); i++)
#define REP1(i, x)               REP2(i, 0, x)
#define REP0(x)                  REP1(SPJ, x)
#define all(v)                   (v).begin(), (v).end()
#define sz(v)                    (int)(v).size()

constexpr int inf = 1e9;
constexpr ll INF = 1e18;

template <class T>
bool chmin(T &a, const T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
bool chmax(T &a, const T b) {
	return a < b ? a = b, 1 : 0;
}

void solve(int n) {
	vector<string> w(n), c;
	rep(i, n) {
		cin >> w[i];
	}
	while(1) {
		string s;
		cin >> s;
		c.push_back(s);
		if(c.back().back() == '.') {
			c.back().pop_back();
			break;
		}
	}
	int m = sz(c);
	vector<vector<string>> lef(21), rig(21);
	rep(i, n) lef[sz(w[i])].push_back(w[i]);
	rep(i, m) rig[sz(c[i])].push_back(c[i]);


	vector<vi> res;
	auto dfs = [&](auto dfs, vi &used, vi &f) -> void {
		if(sz(res) > 1) return;
		int mx = -1, nx = -1;
		rep(i, m) {
			if(used[i]) continue;
			set<char> st;
			rep(j, sz(c[i])) {
				if(f[c[i][j] - 'A'] == -1) {
					st.insert(c[i][j]);
				}
			}
			if(chmax(mx, sz(st))) {
				nx = i;
			}
		}
		if(nx == -1) {
			res.push_back(f);
			return;
		}
		auto str = c[nx];
		rep(j, sz(lef[sz(str)])) {
			if(sz(res) > 1) return;
			bool ok = 1;
			auto nf = f;
			rep(k, sz(str)) {
				auto L = lef[sz(str)][j][k] - 'A';
				auto R = str[k] - 'A';
				if(nf[L] != -1 and nf[L] != R) {
					ok = 0;
					break;
				}
				if(nf[R] != -1 and nf[R] != L) {
					ok = 0;
					break;
				}
				nf[R] = L;
				nf[L] = R;
			}
			if(ok) {
				auto nu = used;
				nu[nx] = 1;
				dfs(dfs, nu, nf);
			}
		}
		return;
	};

	vi f(26, -1), used(m);

	dfs(dfs, used, f);

	if(sz(res) > 1) {
		cout << "-.\n";
		return;
	}
	f = res[0];
	rep(i, m) {
		rep(j, sz(c[i])) {
			auto C = c[i][j] - 'A';
			c[i][j] = 'A' + f[C];
		}
		cout << c[i];
		if(i != m - 1)
			cout << ' ';
		else
			cout << ".\n";
	}
}

int main() {
	int n;
	while(cin >> n, n) solve(n);
}
accuracy: 1
time_ms: 7700
memory_kb: 3392
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=998244353,MAX=65;
const ll INF=1LL<<62;

vector<string> S,T,use;
vector<int> syuS,syuT;
vector<int> pos[MAX];
vector<string> now,ans;
map<char,char> dic;
bool two=false;
int rem;

void solve(int u){
    if(two) return;
    
    if(si(S)-u<rem) return;
    
    if(u==si(S)){
        for(auto a:now){
            if(si(a)==0) return;
        }
        if(si(ans)){
            two=true;
        }else{
            ans=now;
        }
        
        return;
    }
    
    for(int i=0;i<si(use);i++){
        if(syuS[u]<syuT[i]&&si(now[pos[i][0]])==0) return;
    }
    
    for(int i=0;i<si(use);i++){
        if(si(S[u])!=si(use[i])) continue;
        if(syuS[u]!=syuT[i]) continue;
        if(si(now[pos[i][0]])) continue;
        map<char,char> MA;
        bool ok=true;
        for(int j=0;j<si(S[u]);j++){
            if(MA.count(S[u][j])){
                if(MA[S[u][j]]!=use[i][j]) ok=false;
            }
            if(dic.count(S[u][j])){
                if(dic[S[u][j]]!=use[i][j]) ok=false;
            }else{
                MA[S[u][j]]=use[i][j];
            }
            
            if(MA.count(use[i][j])){
                if(MA[use[i][j]]!=S[u][j]) ok=false;
            }
            if(dic.count(use[i][j])){
                if(dic[use[i][j]]!=S[u][j]) ok=false;
            }else{
                MA[use[i][j]]=S[u][j];
            }
            
            if(!ok) break;
        }
        if(!ok) continue;
        
        //cout<<u<<" "<<i<<endl;
        
        for(auto x:MA){
            assert(!dic.count(x.fi));
            dic[x.fi]=x.se;
            //cout<<x.fi<<" "<<x.se<<endl;
        }
        
        for(int k:pos[i]){
            now[k]=S[u];
        }
        rem--;
        solve(u+1);
        rem++;
        for(int k:pos[i]){
            now[k]="";
        }
        
        for(auto x:MA){
            dic.erase(x.fi);
        }
    }
    
    solve(u+1);
}

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        int N;cin>>N;
        if(N==0) break;
        S.clear();S.resize(N);
        for(int i=0;i<N;i++) cin>>S[i];
        cin.ignore();
        string U;
        getline(cin,U);
        T.clear();T.push_back("");
        for(char c:U){
            if(c==' '){
                T.push_back("");
            }else if('A'<=c&&c<='Z'){
                T.back()+=c;
            }
        }
        
        use=T;
        sort(all(use));
        use.erase(unique(all(use)),use.end());
        
        for(int i=0;i<MAX;i++) pos[i].clear();
        for(int i=0;i<si(T);i++){
            for(int j=0;j<si(use);j++){
                if(T[i]==use[j]) pos[j].push_back(i);
            }
        }
        
        rem=si(use);
        
        sort(all(S),[](auto a,auto b){
            set<char> c1,c2;
            for(char c:a) c1.insert(c);
            for(char c:b) c2.insert(c);
            return si(c1)>si(c2);
        });
        
        two=false;
        ans.clear();
        now.clear();now.resize(si(T));
        dic.clear();
        
        syuS.clear();
        syuT.clear();
        for(int i=0;i<si(S);i++){
            set<char> c1;
            for(char c:S[i]) c1.insert(c);
            syuS.push_back(si(c1));
        }
        for(int i=0;i<si(use);i++){
            set<char> c1;
            for(char c:use[i]) c1.insert(c);
            syuT.push_back(si(c1));
        }
        
        solve(0);
        
        if(two) cout<<"-.\n";
        else{
            for(int i=0;i<si(ans);i++){
                if(i) cout<<" ";
                cout<<ans[i];
            }
            cout<<".\n";
        }
        
        /*
        for(auto a:S) cout<<a<<" ";
        cout<<endl;
        for(auto a:use) cout<<a<<" ";
        cout<<endl;
        for(auto a:T) cout<<a<<" ";
        cout<<endl;
        for(int a:syuS) cout<<a<<" ";
        cout<<endl;
        for(int a:syuT) cout<<a<<" ";
        cout<<endl;
        for(int i=0;i<si(use);i++){
            for(int a:pos[i]) cout<<a<<" ";
            cout<<endl;
        }
         */
    }
}
accuracy: 1
time_ms: 150
memory_kb: 3332
final_rank: 14

code_snippet: #include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<vector>
#include<cmath>
#include<algorithm>
#include<map>
#include<queue>
#include<deque>
#include<iomanip>
#include<tuple>
#include<cassert>
#include<set>
#include<complex>
#include<numeric>
#include<functional>
#include<unordered_map>
#include<unordered_set>
using namespace std;
typedef long long int LL;
typedef pair<int,int> P;
typedef pair<LL,LL> LP;
const int INF=1<<30;
const LL MAX=1e9+7;

void array_show(int *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%d%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(LL *array,int array_n,char middle=' '){
    for(int i=0;i<array_n;i++)printf("%lld%c",array[i],(i!=array_n-1?middle:'\n'));
}
void array_show(vector<int> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%d%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
void array_show(vector<LL> &vec_s,int vec_n=-1,char middle=' '){
    if(vec_n==-1)vec_n=vec_s.size();
    for(int i=0;i<vec_n;i++)printf("%lld%c",vec_s[i],(i!=vec_n-1?middle:'\n'));
}
template<typename T> ostream& operator<<(ostream& os,const vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++){
        if(i)os<<" ";
        os<<v1[i];
    }
    return os;
}
template<typename T1,typename T2> ostream& operator<<(ostream& os,const pair<T1,T2>& p){
    os<<p.first<<" "<<p.second;
    return os;
}
template<typename T> istream& operator>>(istream& is,vector<T>& v1){
    int n=v1.size();
    for(int i=0;i<n;i++)is>>v1[i];
    return is;
}
template<typename T1,typename T2> istream& operator>>(istream& is,pair<T1,T2>& p){
    is>>p.first>>p.second;
    return is;
}

namespace sol{
    const int N=26;
    vector<int> vt;
    vector<string> v1,v2;
    vector<char> used;
    vector<int> used2;

    bool check(string sa,string sb,int p){
        if(sa.size()!=sb.size())return false;
        for(int i=0;i<sa.size();i++){
            int a=sa[i]-'A',b=sb[i]-'A';
            if(vt[a]==-1 && vt[b]==-1){
                vt[a]=b,vt[b]=a;
                used2[a]=p,used2[b]=p;
            }
            if(vt[a]!=b || vt[b]!=a)return false;
        }
        return true;
    }

    void check_rev(int p){
        for(int i=0;i<N;i++){
            if(used2[i]==p)used2[i]=-1,vt[i]=-1;
        }
    }

    int dfs(int pos,int max_cnt){
        if(pos==v2.size())return 1;
        int s=0;
        for(int i=0;i<v1.size();i++){
            if(used[i])continue;
            if(!check(v1[i],v2[pos],pos)){
                check_rev(pos);
                continue;
            }
            s+=dfs(pos+1,max_cnt);
            if(s>=max_cnt)return s;
            check_rev(pos);
        }
        return s;
    }

    void solve(){
        int n,m;
        int i,j,k;
        int a,b,c;
        while(cin>>n){
            if(n==0)return;
            v1.resize(n);
            cin>>v1;
            string sa,sb;
            vector<int> va;
            vector<string> vs;
            bool flag=false;
            v2.clear();
            while(cin>>sa){
                if(sa.back()=='.'){
                    sa.pop_back();
                    flag=true;
                }
                vs.push_back(sa);
                for(j=0;j<v2.size();j++){
                    if(v2[j]==sa){
                        break;
                    }
                }
                if(j==v2.size())v2.push_back(sa);
                if(flag)break;
            }
            auto cnt=[](string s1){
                vector<char> v(N,0);
                int s=0;
                for(int i=0;i<s1.size();i++){
                    int a=s1[i]-'A';
                    if(!v[a])v[a]=1,s++;
                }
                return s;
            };
            sort(v2.begin(),v2.end(),[&](string s1,string s2){
                return cnt(s1)>cnt(s2);
            });
            used.assign(v1.size(),0);
            used2.assign(N,-1);
            vt.assign(N,-1);
            a=dfs(0,2);
            if(a>=2){
                cout<<"-."<<endl;
                continue;
            }
            dfs(0,1);
            for(auto& s:vs){
                for(auto& ca:s){
                    a=ca-'A';
                    ca='A'+vt[a];
                }
            }
            cout<<vs<<"."<<endl;
        }
    }
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    sol::solve();
}
accuracy: 1
time_ms: 10
memory_kb: 3392
final_rank: 13

code_snippet: #pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#include<iostream>
#include<string>
#include<cstdio>
#include<vector>
#include<cmath>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<queue>
#include<ciso646>
#include<random>
#include<map>
#include<set>
#include<bitset>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<utility>
#include<cassert>
#include<complex>
#include<numeric>
#include<array>
using namespace std;

//#define int long long
typedef long long ll;

typedef unsigned long long ul;
typedef unsigned int ui;
constexpr ll mod = 1000000007;
const ll INF = mod * mod;
typedef pair<int, int>P;
#define stop char nyaa;cin>>nyaa;
#define rep(i,n) for(int i=0;i<n;i++)
#define per(i,n) for(int i=n-1;i>=0;i--)
#define Rep(i,sta,n) for(int i=sta;i<n;i++)
#define rep1(i,n) for(int i=1;i<=n;i++)
#define per1(i,n) for(int i=n;i>=1;i--)
#define Rep1(i,sta,n) for(int i=sta;i<=n;i++)
#define all(v) (v).begin(),(v).end()
typedef pair<ll, ll> LP;
typedef long double ld;
typedef pair<ld, ld> LDP;
const ld eps = 1e-12;
const ld pi = acosl(-1.0);

ll mod_pow(ll x, ll n, ll m = mod) {
	if (n < 0) {
		ll res = mod_pow(x, -n, m);
		return mod_pow(res, m - 2, m);
	}
	if (abs(x) >= m)x %= m;
	if (x < 0)x += m;
	ll res = 1;
	while (n) {
		if (n & 1)res = res * x % m;
		x = x * x % m; n >>= 1;
	}
	return res;
}
struct modint {
	ll n;
	modint() :n(0) { ; }
	modint(ll m) :n(m) {
		if (n >= mod)n %= mod;
		else if (n < 0)n = (n % mod + mod) % mod;
	}
	operator int() { return n; }
};
bool operator==(modint a, modint b) { return a.n == b.n; }
modint operator+=(modint& a, modint b) { a.n += b.n; if (a.n >= mod)a.n -= mod; return a; }
modint operator-=(modint& a, modint b) { a.n -= b.n; if (a.n < 0)a.n += mod; return a; }
modint operator*=(modint& a, modint b) { a.n = ((ll)a.n * b.n) % mod; return a; }
modint operator+(modint a, modint b) { return a += b; }
modint operator-(modint a, modint b) { return a -= b; }
modint operator*(modint a, modint b) { return a *= b; }
modint operator^(modint a, ll n) {
	if (n == 0)return modint(1);
	modint res = (a * a) ^ (n / 2);
	if (n % 2)res = res * a;
	return res;
}

ll inv(ll a, ll p) {
	return (a == 1 ? 1 : (1 - p * inv(p % a, a)) / a + p);
}
modint operator/(modint a, modint b) { return a * modint(inv(b, mod)); }
modint operator/=(modint& a, modint b) { a = a / b; return a; }
const int max_n = 1 << 1;
modint fact[max_n], factinv[max_n];
void init_f() {
	fact[0] = modint(1);
	for (int i = 0; i < max_n - 1; i++) {
		fact[i + 1] = fact[i] * modint(i + 1);
	}
	factinv[max_n - 1] = modint(1) / fact[max_n - 1];
	for (int i = max_n - 2; i >= 0; i--) {
		factinv[i] = factinv[i + 1] * modint(i + 1);
	}
}
modint comb(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[b] * factinv[a - b];
}
modint combP(int a, int b) {
	if (a < 0 || b < 0 || a < b)return 0;
	return fact[a] * factinv[a - b];
}

int n;
void solve() {
	vector<string> s(n);
	rep(i, n)cin >> s[i];
	vector<string> t;
	while (true) {
		string x; cin >> x;
		if (x.back() == '.') {
			x.pop_back();
			t.push_back(x); break;
		}
		t.push_back(x);
	}
	auto calc = [&](int i, int j)->vector<int> {
		vector<int> res(26, -1);
		rep(c, s[j].size()) {
			res[s[j][c] - 'A'] = t[i][c] - 'A';
			res[t[i][c] - 'A'] = s[j][c] - 'A';
		}
		return res;
	};
	int m = t.size();
	vector<vector<vector<int>>> b;
	b.resize(m);
	rep(i, m) {
		b[i].resize(n);
		rep(j, n) {
			b[i][j].resize(m);
			if (s[j].size() != t[i].size())continue;
			rep(k, m) {
				rep(l, n) {
					bool valid = true;
					if (t[k].size() != s[l].size())valid = false;
					else {
						vector<int> vl = calc(i, j);
						vector<int> vr = calc(k, l);
						rep(c, 26) {
							if (vl[c] >= 0 && vr[c] >= 0 && vl[c] != vr[c])valid = false;
						}
					}
					if (valid)b[i][j][k] |= (1 << l);
				}
			}
		}
	}
	vector<int> ori(m);
	rep(i, m)rep(j, n) {
		bool valid = true;
		if (t[i].size() != s[j].size())valid = false;
		else {
			int alf[26]; rep(c, 26)alf[c] = -1;
			rep(c, t[i].size()) {
				int a = s[j][c] - 'A';
				int b = t[i][c] - 'A';
				if (alf[a] >= 0 && alf[a] != b)valid = false;
				if (alf[b] >= 0 && alf[b] != a)valid = false;
				alf[a] = b; alf[b] = a;
			}
		}
		if (valid)ori[i] |= (1 << j);
	}
	vector<int> cur;
	string ans;
	function<bool(vector<int>, int)> dfs = [&](vector<int> vs, int dep)->bool {
		if (dep == m) {
			if (ans.empty()) {
				rep(i, m) {
					if (i > 0)ans.push_back(' ');
					ans += s[cur[i]];
					if (i == m - 1)ans.push_back('.');
				}
				return false;
			}
			else {
				ans = "-.";
				return true;
			}
		}
		else {
			rep(i, n) {
				if (vs[dep] & (1 << i)) {
					vector<int> cop = vs;
					bool valid = true;
					for (int j = dep + 1; j < m; j++) {
						cop[j] &= b[dep][i][j];
						if (cop[j] == 0)valid = false;
					}
					if (valid) {
						cur.push_back(i);
						if (dfs(cop, dep + 1))return true;
						cur.pop_back();
					}
				}
			}
		}
		return false;
	};
	dfs(ori, 0);
	//cout << "ans is ";
	cout << ans << "\n";
}


signed main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	//cout << fixed << setprecision(12);
	//init_f();
	//init();
	//expr();
	//int t; cin >> t;rep(i,t)
	while (cin >> n, n) {
		solve();
	}
	return 0;
}
accuracy: 1
time_ms: 220
memory_kb: 3632
final_rank: 15

code_snippet: #include<iostream>
#include<string>
#include<set>
#include<algorithm>
using namespace std;

int n, m;
string words[20], words2[40], words3[40], ans;
bool same[40], selected[20];
char r[26];

int dfs(int x) {
  if (x == m) {
    ans = "";
    for (int i = 0; i < m; i++) {
      for (char c : words3[i]) ans += r[c-'A'];
      if (i == m-1) ans += ".";
      else ans += " ";
    }
    return 1;
  }
  if (same[x]) return dfs(x+1);
  char copy[26];
  for (int i = 0; i < 26; i++) copy[i] = r[i];
  int counter = 0;
  for (int i = 0; i < n; i++) if (words[i].length() == words2[x].length()) {
    bool ok = true;
    for (int j = 0; j < words[i].length(); j++) {
      if (r[words[i][j]-'A'] != 0 && r[words[i][j]-'A'] != words2[x][j]) {
        ok = false;
        break;
      }
      if (r[words2[x][j]-'A'] != 0 && r[words2[x][j]-'A'] != words[i][j]) {
        ok = false;
        break;
      }
      r[words[i][j]-'A'] = words2[x][j];
      r[words2[x][j]-'A'] = words[i][j];
    }
    if (ok) {
      selected[i] = true;
      if (x >= 2) {
        for (int p = x+1; p < m; p++) {
          bool ok2 = true;
          for (int k = 0; k < n; k++) if (!selected[k] && words[k].length() == words2[p].length()) {
            bool tmp = true;
            for (int j = 0; j < words[k].length(); j++) {
              if (r[words[k][j]-'A'] != 0 && r[words[k][j]-'A'] != words2[p][j]) {
                tmp = false;
                break;
              }
              if (r[words2[p][j]-'A'] != 0 && r[words2[p][j]-'A'] != words[k][j]) {
                tmp = false;
                break;
              }
            }
            if (tmp) {
              ok2 = true;
              break;
            }
          }
          if (!ok2) {
            ok = false;
            break;
          }
        }
      }
      counter += dfs(x+1);
      if (counter >= 2) break;
      selected[i] = false;
    }
    for (int j = 0; j < 26; j++) r[j] = copy[j];
  }
  for (int j = 0; j < 26; j++) r[j] = copy[j];
  return counter;
}

bool comp(const string& a, const string& b) {
  set<char> as, bs;
  for (char x : a) as.insert(x);
  for (char x : b) bs.insert(x);
  return as.size() > bs.size();
}

int main() {
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) cin >> words[i];
    for (m = 0;; m++) {
      cin >> words2[m];
      if (words2[m][words2[m].length() - 1] == '.') {
        words2[m] = words2[m].substr(0, words2[m].length() - 1);
        m++;
        break;
      }
    }
    for (int i = 0; i < m; i++) words3[i] = words2[i];
    sort(words2, words2 + m, comp);
    for (int i = 0; i < m; i++) {
      same[i] = false;
      for (int j = 0; j < i; j++) if (words2[i] == words2[j]) {
        same[i] = true;
        break;
      }
    }
    if (dfs(0) >= 2) cout << "-." << endl;
    else cout << ans << endl;
  }
}
accuracy: 1
time_ms: 10
memory_kb: 3000
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;

int main() {
    int n;
    while(cin >> n, n) {
        vector<string> ws(n);
        for(auto& w : ws) cin >> w;
        vector<string> ss = {""};
        while(cin >> ss.back()) {
            if(ss.back().back() == '.') break;
            ss.push_back("");
        }
        ss.back().pop_back(); // period
        const int ss_sz = [&] () { // unique
            set<string> sss(ss.begin(), ss.end());
            return sss.size();
        }();

        // long string has strong constraints
        sort(begin(ws), end(ws), [] (string s1, string s2) {
                set<char> ss1(begin(s1), end(s1));
                set<char> ss2(begin(s2), end(s2));
                return make_pair(s1.size(), ss1.size()) > make_pair(s2.size(), ss2.size());
            });

        vector<char> m(26, '*'); // map
        vector<int> mcnt(26);
        auto conv = [&] (string s) {
            for(auto& c : s) {
                c = m[c - 'A'];
            }
            return s;
        };
        string ans;
        function<void(int, int)> dfs = [&] (int i, int remain) {
            if(ans == "-.") return;
            if(i == n) {
                string tans = conv(ss[0]);
                for(int j = 1; j < (int)ss.size(); ++j) {
                    tans += " " + conv(ss[j]);
                }
                tans += ".";
                if(tans.find('*') != string::npos) {
                    return;
                } else if(!ans.empty() && ans != tans) {
                    ans = "-.";
                } else {
                    ans = tans;
                }
                return;
            }
            if(n - i - 1 >= remain) {
                dfs(i + 1, remain); // no use
            }
            const auto& w = ws[i];
            for(auto const& s : ss) {
                if(s.size() != w.size()) continue;
                int it = 0;
                for(; it < (int)w.size(); ++it) {
                    if((m[s[it] - 'A'] == w[it] && m[w[it] - 'A'] == s[it]) || (m[s[it] - 'A'] == '*' && m[w[it] - 'A'] == '*')) {
                        m[s[it] - 'A'] = w[it];
                        m[w[it] - 'A'] = s[it];
                        ++mcnt[s[it] - 'A'];
                        ++mcnt[w[it] - 'A'];
                    } else {
                        break;
                    }
                }
                if(it == (int)w.size()) { // ok
                    dfs(i + 1, remain - 1);
                }
                for(int j = 0; j < it; ++j) { // restore
                    --mcnt[s[j] - 'A'];
                    --mcnt[w[j] - 'A'];
                    if(mcnt[s[j] - 'A'] == 0) {
                        m[s[j] - 'A'] = m[w[j] - 'A'] = '*';
                    }
                }
            }
        };
        dfs(0, ss_sz);

        cout << ans << endl;
    }
}
accuracy: 1
time_ms: 1010
memory_kb: 3228
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef pair<char, char> P;

#define fi first
#define se second
#define repl(i,a,b) for(ll i=(ll)(a);i<(ll)(b);i++)
#define rep(i,n) repl(i,0,n)
#define all(x) (x).begin(),(x).end()
#define dbg(x) cout<<#x"="<<x<<endl
#define mmax(x,y) (x>y?x:y)
#define mmin(x,y) (x<y?x:y)
#define maxch(x,y) x=mmax(x,y)
#define minch(x,y) x=mmin(x,y)
#define uni(x) x.erase(unique(all(x)),x.end())
#define exist(x,y) (find(all(x),y)!=x.end())
#define bcnt __builtin_popcountll

#define INF 1e16
#define mod 1000000007

int n,m;
string w[20];
vector<string> s;
vector<int> ord;
int res=0;
set<P> role[2];
bool used[26];
int ccnt[100];

void dfs(int i){
  if(i==m){
    res++;
    if(res<2){
      role[res]=role[res-1];
    }
    return ;
  }
  int j=ord[i];
  rep(k,n){
    if(w[k].size()>s[j].size())break;
    if(s[j].size()!=w[k].size())continue;
    bool ok=true;
    vector<P> add;
    rep(l,s[j].size()){
      char c1=s[j][l],c2=w[k][l];
      if(used[c1-'A']!=used[c2-'A']){
        ok=false; break;
      }
      if(used[c1-'A']&&used[c2-'A']&&role[res].find(P(c1,c2))==role[res].end()){
        ok=false; break;
      }
      if(role[res].find(P(c1,c2))==role[res].end()){
        role[res].insert(P(c1,c2)); role[res].insert(P(c2,c1));
        used[c1-'A']=used[c2-'A']=true;
        add.push_back(P(c1,c2));
      }
    }
    if(!ok){
      rep(l,add.size()){
        role[res].erase(P(add[l].fi,add[l].se));
        role[res].erase(P(add[l].se,add[l].fi));
        used[add[l].fi-'A']=false; used[add[l].se-'A']=false;
      }
      continue;
    }
    dfs(i+1);
    if(res==2)return;
    rep(l,add.size()){
      role[res].erase(P(add[l].fi,add[l].se));
      role[res].erase(P(add[l].se,add[l].fi));
      used[add[l].fi-'A']=false; used[add[l].se-'A']=false;
    }
  }
}

int main(){
  cin.tie(0);
  ios::sync_with_stdio(false);
  while(1){
    cin>>n;
    if(n==0)break;
    s.clear();
    m=0; ord.clear();
    rep(i,n)cin>>w[i];
    sort(w,w+n,[](const string& a,const string& b){ return a.size() < b.size(); });
    while(1){
      ord.push_back(m++);
      string tmp;
      cin>>tmp;
      if(tmp[tmp.size()-1]=='.'){
        s.push_back(tmp.substr(0,tmp.size()-1));
        break;
      }
      s.push_back(tmp);
    }
    rep(i,m){
      set<char> st;
      rep(j,s[i].size())st.insert(s[i][j]);
      ccnt[i]=st.size();
    }
    sort(all(ord),[=](const int& a,const int& b){ return ccnt[a] > ccnt[b]; });
    res=0;
    rep(i,2)role[i].clear();
    memset(used,0,sizeof(used));
    dfs(0);
    if(res==2)cout<<"-."<<endl;
    else{
      string ans=s[0];
      repl(i,1,m)ans+=" "+s[i];
      ans+=".";
      rep(i,ans.size()){
        for(P p : role[0]){
          if(ans[i]==p.fi){
            ans[i]=p.se;
            break;
          }
        }
      }
      cout<<ans<<endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3176
final_rank: 10

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
vector<string> w,v;
vector<string> xyz[30];
string s;
vector<char> vc,ans;
typedef pair<int,int> P;
vector<P> vp;
vector<int> used;
int valid;
vector<int> wc1,wc2;
void dfs(){
  for(int i=0;i<(int)v.size();i++){
    string& t=v[i];
    bool flg=0;
    for(int j=0;j<(int)xyz[t.size()].size();j++){
      string& u=xyz[t.size()][j];
      bool ok=1;
      for(int k=0;k<(int)t.size();k++){
    if(!used[t[k]-'A']) continue;
    if(!used[u[k]-'A']){
      ok=0;
      break;
    }
    ok&=vc[t[k]-'A']==u[k]-'A';
    if(!ok) break;
      }
      //cout<<t<<" "<<u<<":"<<ok<<endl;
      if(ok){
    flg=1;
    break;
      }
    }
    if(!flg) return;
  }
  int cnt=0;
  for(int i=0;i<26;i++) if(used[vp[i].second]) cnt++;
  //cout<<cnt<<endl;
  //if(cnt>1) return;
  if(cnt==26){
    valid++;
    ans=vc;
    return;
  }
  int x=0;
  while(used[vp[x].second]) x++;
  //cout<<x<<endl;
  if(vp[x].first){
    for(int k=0;k<26;k++){
      if(used[vp[k].second]) continue;
      used[vp[x].second]=used[vp[k].second]=1;
      vc[vp[x].second]=vp[k].second;
      vc[vp[k].second]=vp[x].second;
      //cout<<x<<" "<<k<<endl;
      //cout<<(char)(vp[x].second+'A')<<"<->"<<(char)(vp[k].second+'A')<<endl;
      dfs();
      if(valid>1) return; 
      used[vp[x].second]=used[vp[k].second]=0;
      vc[vp[x].second]=vc[vp[k].second]=0;   
    }
  }else{
    used[vp[x].second]=1;
    vc[vp[x].second]=vp[x].second;
    dfs();
    used[vp[x].second]=0;
    vc[vp[x].second]=0;
  }
}
signed main(){
  while(cin>>n,n){
    for(int i=0;i<30;i++) xyz[i].clear(); 
    w.resize(n);
    for(int i=0;i<n;i++) cin>>w[i],xyz[w[i].size()].push_back(w[i]);
    cin.ignore();
    getline(cin,s);
    assert(s.back()=='.');
    s.pop_back();
    v.clear();
    for(int i=0;i<(int)s.size();i++){
      string t;
      while(i<(int)s.size()&&s[i]!=' ') t+=s[i++];
      //cout<<t<<endl;
      v.push_back(t);
    }
    vc.clear();
    vc.resize(26,0);
    wc2.clear();
    wc2.resize(26,0);
    for(int i=0;i<(int)v.size();i++)
      for(int j=0;j<(int)v[i].size();j++)
    wc2[v[i][j]-'A']++;
    vp.resize(26);
    for(int i=0;i<26;i++) vp[i]=P(wc2[i],i);
    sort(vp.rbegin(),vp.rend());
    used.clear();
    used.resize(26,0);
    valid=0;
    dfs();
    //cout<<valid<<endl;
    if(valid!=1){
      cout<<"-."<<endl;
      continue;
    }
    //puts("found");
    for(int i=0;i<(int)v.size();i++){
      if(i) cout<<" ";
      for(int j=0;j<(int)v[i].size();j++){
    //cout<<v[i][j]-'A'<<endl;
    cout<<(char)(ans[v[i][j]-'A']+'A');
      }
    }
    cout<<"."<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3164
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long
int n;
vector<string> w,v;
vector<string> xyz[30];
string s;
vector<char> vc,ans;
typedef pair<int,int> P;
vector<P> vp;
vector<int> used;
int valid;
vector<int> wc1,wc2;
void dfs(){
  for(int i=0;i<(int)v.size();i++){
    string& t=v[i];
    bool flg=0;
    for(int j=0;j<(int)xyz[t.size()].size();j++){
      string& u=xyz[t.size()][j];
      bool ok=1;
      for(int k=0;k<(int)t.size();k++){
	if(!used[t[k]-'A']) continue;
	if(!used[u[k]-'A']){
	  ok=0;
	  break;
	}
	ok&=vc[t[k]-'A']==u[k]-'A';
	if(!ok) break;
      }
      //cout<<t<<" "<<u<<":"<<ok<<endl;
      if(ok){
	flg=1;
	break;
      }
    }
    if(!flg) return;
  }
  int cnt=0;
  for(int i=0;i<26;i++) if(used[vp[i].second]) cnt++;
  //cout<<cnt<<endl;
  //if(cnt>1) return;
  if(cnt==26){
    valid++;
    ans=vc;
    return;
  }
  int x=0;
  while(used[vp[x].second]) x++;
  //cout<<x<<endl;
  if(vp[x].first){
    for(int k=0;k<26;k++){
      if(used[vp[k].second]) continue;
      used[vp[x].second]=used[vp[k].second]=1;
      vc[vp[x].second]=vp[k].second;
      vc[vp[k].second]=vp[x].second;
      //cout<<x<<" "<<k<<endl;
      //cout<<(char)(vp[x].second+'A')<<"<->"<<(char)(vp[k].second+'A')<<endl;
      dfs();
      if(valid>1) return; 
      used[vp[x].second]=used[vp[k].second]=0;
      vc[vp[x].second]=vc[vp[k].second]=0;   
    }
  }else{
    used[vp[x].second]=1;
    vc[vp[x].second]=vp[x].second;
    dfs();
    used[vp[x].second]=0;
    vc[vp[x].second]=0;
  }
}
signed main(){
  while(cin>>n,n){
    for(int i=0;i<30;i++) xyz[i].clear(); 
    w.resize(n);
    for(int i=0;i<n;i++) cin>>w[i],xyz[w[i].size()].push_back(w[i]);
    cin.ignore();
    getline(cin,s);
    assert(s.back()=='.');
    s.pop_back();
    v.clear();
    for(int i=0;i<(int)s.size();i++){
      string t;
      while(i<(int)s.size()&&s[i]!=' ') t+=s[i++];
      //cout<<t<<endl;
      v.push_back(t);
    }
    vc.clear();
    vc.resize(26,0);
    wc2.clear();
    wc2.resize(26,0);
    for(int i=0;i<(int)v.size();i++)
      for(int j=0;j<(int)v[i].size();j++)
	wc2[v[i][j]-'A']++;
    vp.resize(26);
    for(int i=0;i<26;i++) vp[i]=P(wc2[i],i);
    sort(vp.rbegin(),vp.rend());
    used.clear();
    used.resize(26,0);
    valid=0;
    dfs();
    //cout<<valid<<endl;
    if(valid!=1){
      cout<<"-."<<endl;
      continue;
    }
    //puts("found");
    for(int i=0;i<(int)v.size();i++){
      if(i) cout<<" ";
      for(int j=0;j<(int)v[i].size();j++){
	//cout<<v[i][j]-'A'<<endl;
	cout<<(char)(ans[v[i][j]-'A']+'A');
      }
    }
    cout<<"."<<endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3180
final_rank: 11

code_snippet: #include<bits/stdc++.h>
using namespace std;
#define int long long

#define rep(i, n) for(int i = 0; i < (int)(n); i++)

int n;
vector<string> word;
vector<string> seq;
map<char, int> mp;
map<char, char> conv;
vector< pair<int, char> > ord;
string ans;
int num;

bool check() {
  rep(i, seq.size()) {
    bool flag = false;
    rep(j, word.size()) {
      if(word[j].size() != seq[i].size()) continue;
      bool flag2 = true;
      rep(k, seq[i].size()) {
	if(conv[seq[i][k]] == '$') continue;
	if(conv[seq[i][k]] != word[j][k]) flag2 = false;
      }
      if(flag2) flag = true;
    }
    if(!flag) return false;
  }
  return true;
}

void dfs(int idx) {
  //for(auto p : conv) {
    //cout << p.first << " " << p.second << endl;
  //}
  //cout << check() << endl;  
  if(!check()) return;
  if(idx == ord.size()) {
    string tmp = "";
    rep(i, seq.size()) {
      if(i) tmp += " ";
      rep(j, seq[i].size()) {
	tmp += conv[seq[i][j]];
      }
    }
    ans = tmp;
    num++;
    return;
  }
  if(conv[ord[idx].second] != '$') {
    dfs(idx+1);
    return;
  }
  ///cout << ord[idx].second << endl;
  rep(i, 26) {
    if(conv[(char)('A'+i)] != '$') continue;
    conv[ord[idx].second] = (char)('A'+i);
    conv[(char)('A'+i)] = ord[idx].second;
    dfs(idx+1);
    if(num > 1) return;
    conv[ord[idx].second] = '$';
    conv[(char)('A'+i)] = '$';
  }
}

signed main(){
  while(cin >> n, n) {
    word.clear();
    word.resize(n);
    rep(i, n) cin >> word[i];
    seq.clear();
    while(1) {
      string s;
      cin >> s;
      seq.push_back(s);
      if(s.back() == '.') {
	seq[seq.size()-1].pop_back();
	break;
      }
    }
    ord.clear();
    mp.clear();
    conv.clear();
    rep(i, seq.size()) rep(j, seq[i].size()) {
      if(seq[i][j] == '.') continue;
      mp[seq[i][j]]++;
    }
    for(auto p : mp) {
      ord.push_back(make_pair(p.second, p.first));
    }
    sort(ord.begin(), ord.end(), greater<pair<int, int> >());
    ans = "-";    
    rep(i, 26) conv[(char)('A'+i)] = '$';
    conv['.'] = '.';
    num = 0;
    dfs(0);
    //cout << num << endl;
    if(num != 1) ans = "-";
    cout << ans + "." << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 80
memory_kb: 3196
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,string> PP;

set<string> se;
map<string,int> m;
vector<PP> a;
vector<string> v;
int ans[26],u[26],uu[100],n,c;

void dfs(int k) {
  if(k==a.size()||c>1) {
    for(int i=0; i<26; i++) {
      if(u[i]==-1) continue;
      if(u[u[i]]!=i) return;
    }
    c++;
    for(int i=0; i<26; i++) ans[i]=u[i];
    return;
  }
  string r=a[k].second;
  for(int i=0; i<n; i++) {
    string t=v[i];
    if(uu[i]||r.size()!=t.size()) continue;
    for(int j=0; j<t.size(); j++) {
      if(u[t[j]-'A']!=-1&&u[t[j]-'A']!=r[j]-'A') goto next;
      if(u[r[j]-'A']!=-1&&u[r[j]-'A']!=t[j]-'A') goto next;
    }
    int u2[26];
    for(int j=0; j<26; j++) u2[j]=u[j];
    for(int j=0; j<t.size(); j++) {
      u[t[j]-'A']=r[j]-'A';
      u[r[j]-'A']=t[j]-'A';
    }
    uu[i]=1;
    dfs(k+1);
    uu[i]=0;
    for(int j=0; j<26; j++) u[j]=u2[j];
  next:;
  }
}
string s;

int main() {
  while(cin >> n && n) {
    se.clear();a.clear();m.clear();v.clear();
    for(int i=0; i<n; i++) {
      cin >> s;
      v.push_back(s);
      se.insert(s);
    }
    getline(cin,s);
    getline(cin,s);
    stringstream ss;
    ss << s;
    string r;
    while(ss>>r) {
      if(r[r.size()-1]=='.') r=r.substr(0,r.size()-1);
      m[r]++;
    }
    for(map<string,int>::iterator it=m.begin();it!=m.end();it++) {
      int d[26],cnt=0;memset(d,0,sizeof(d));
      r=it->first;
      for(int i=0; i<r.size(); i++) d[r[i]-'A']++;
      for(int i=0; i<26; i++) if(d[i]) cnt++;
      a.push_back(PP(cnt,it->first));
    }
    sort(a.begin(),a.end(),greater<PP>());
    memset(u,-1,sizeof(u));
    memset(uu,0,sizeof(uu));
    c=0;
    dfs(0);
    if(c==1) {
      for(int i=0; i<s.size(); i++) {
        if(isalpha(s[i])) cout << (char)(ans[s[i]-'A']+'A');
        else cout << s[i];
      }
      cout << endl;
    } else cout << "-." << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 3144
final_rank: 8

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<utility>
#include<algorithm>

using namespace std;

int ord(char c){
  return c-'A';
}

vector<pair<char,char> > rec(vector<string> seq,vector<string> word,vector<pair<char,char> > rules,int u){
  if(seq.empty())return rules;
  int mx=-1,x;
  for(int i=0;i<seq.size();i++){
    int t=u;
    int cu=0;
    for(auto e:seq[i]){
      int xx=e-'A';
      if(!(t>>xx&1)){
	cu++;
	t|=1<<xx;
      }
    }
    if(cu>mx){
      mx=cu;
      x=i;
    }
  }
  vector<pair<char,char> > res;
  for(int j=0;j<word.size();j++){
    auto e=word[j];
    if(seq[x].size()!=e.size())continue;
    vector<pair<char,char> > nr=rules;
    int nu=u;
    for(int i=0;i<e.size();i++){
      int sr=nu>>ord(seq[x][i])&1;
      int wr=nu>>ord(e[i])&1;
      if(sr^wr)goto next;
      if(!sr){
	nu|=1<<ord(seq[x][i])|1<<ord(e[i]);
	char l=seq[x][i],h=e[i];
	if(h<l){
	  swap(l,h);
	}
	nr.emplace_back(l,h);
      }else{
	char l=min(seq[x][i],e[i]);
	char h=max(seq[x][i],e[i]);
	if(find(begin(nr),end(nr),make_pair(l,h))==end(nr))goto next;
      }
    }
    {
      vector<string> nseq(begin(seq),begin(seq)+x),nword(begin(word),begin(word)+j);
      nseq.insert(end(nseq),begin(seq)+x+1,end(seq));
      nword.insert(end(nword),begin(word)+j+1,end(word));
      auto r=rec(nseq,nword,nr,nu);
      if(!res.empty()&&!r.empty())throw 0;
      if(!r.empty()){
	res=r;
      }
    }
  next:
    ;
  }
  return res;
}

int main(){
  for(int n;cin>>n,n;){
    vector<string> word(n);
    for(int i=0;i<n;i++){
      cin>>word[i];
    }
    vector<string> seq;
    for(string s;;){
      cin>>s;
      if(s.back()!='.'){
	seq.push_back(s);
      }else{
	seq.push_back(s.substr(0,s.size()-1));
	break;
      }
    }
    vector<string> useq=seq,uword=word;
    sort(begin(useq),end(useq));
    sort(begin(uword),end(uword));
    useq.erase(unique(begin(useq),end(useq)),end(useq));
    uword.erase(unique(begin(uword),end(uword)),end(uword));
    try{
      auto r=rec(useq,word,{},0);
      char table[256];
      for(auto e:r){
	table[e.first]=e.second;
	table[e.second]=e.first;
      }
      bool ns=false;
      for(auto e:seq){
	if(ns++){
	  cout<<' ';
	}
	for(auto f:e){
	  cout<<table[f];
	}
      }
      cout<<'.'<<endl;
    }catch(...){
      cout<<"-."<<endl;
    }
  }
}
accuracy: 1
time_ms: 5600
memory_kb: 1332
final_rank: 17

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for(int i=0;i<(int)(n);++i)
#define rep1(i,n) for(int i=1;i<=(n);++i)
#define all(c) (c).begin(),(c).end()
#define fs first
#define sc second
#define pb push_back
#define show(x) cout << #x << " " << x << endl
typedef pair<string,int> Psi;
typedef vector<int> Vi;
int N;
vector<string> ss,words[21];
vector<Psi> vpsi;
Vi ans;
bool app[26];
void init(){
	ans.clear();
	ss.clear();
	rep(i,21) words[i].clear();
	vpsi.clear();
	rep(i,26) app[i]=0;
}
const bool lencomp(Psi x,Psi y){
	string s=x.fs,t=y.fs;
	bool a[26]={},b[26]={};
	rep(i,s.size()) a[s[i]-'A']=1;
	rep(i,t.size()) b[t[i]-'A']=1;
	int c=0,d=0;
	rep(i,26) if(a[i]) c++;
	rep(i,26) if(b[i]) d++;
	return c>d;
}
inline bool eq(Vi& a,Vi& b){
	rep(i,26) if(app[i]&&a[i]!=b[i]) return 0;
	return 1;
}
bool dfs(int x,Vi vi){
	if(x==ss.size()){
		if(!ans.empty()&&!eq(ans,vi)) return false;
		ans=vi;
		return true;
	}
	string s=ss[x];
	int L=s.size();
	for(string w:words[L]){
		Vi nvi=vi;
		bool ok=1;
		rep(i,L){
			if(nvi[s[i]-'A']>=0&&nvi[s[i]-'A']+'A'!=w[i]){
				ok=0;
				break;
			}
			if(nvi[w[i]-'A']>=0&&nvi[w[i]-'A']+'A'!=s[i]){
				ok=0;
				break;
			}
			nvi[s[i]-'A']=w[i]-'A';
			nvi[w[i]-'A']=s[i]-'A';
		}
		if(!ok) continue;
		if(!dfs(x+1,nvi)) return false;
	}
	return true;
}
int main(){
	while(true){
		cin>>N;
		if(N==0) break;
		init();
		rep(i,N){
			string s;
			cin>>s;
			words[s.size()].pb(s);
		}
		int I=0;
		while(true){
			string s;
			cin>>s;
			rep(i,s.size()) if(s[i]!='.') app[s[i]-'A']=1;
			if(s.back()=='.'){
				vpsi.pb(Psi(s.substr(0,s.size()-1),I++));
				break;
			}
			vpsi.pb(Psi(s,I++));
		}
		sort(all(vpsi),lencomp);
		for(Psi psi:vpsi) ss.pb(psi.fs);
		if(dfs(0,Vi(26,-1))&&!ans.empty()){
			vector<string> vst(ss.size());
			rep(i,ss.size()) vst[vpsi[i].sc]=ss[i];
			rep(i,vst.size()){
				rep(j,vst[i].size()){
					cout<<(char)(ans[vst[i][j]-'A']+'A');
				}
				cout<<(i+1==vst.size()?".\n":" ");
			}
		}else{
			puts("-.");
		}
	}
}
accuracy: 1
time_ms: 20
memory_kb: 1240
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;

const int MAXN = 21;
int N;
string word[MAXN];
string line;
vector<string> V;
vector<int> F;
map<char, char> ans;

bool ok(const string &x, const string &w, map<char, char> m) {
  if(x.size() != w.size()) return false;
  for(int i = 0; i < x.size(); ++i) {
    if(m.count(x[i]) && m[x[i]] != w[i]) return false;
    if(m.count(w[i]) && m[w[i]] != x[i]) return false;
    m[x[i]] = w[i];
    m[w[i]] = x[i];
  }
  return true;
}

void reg(const string &x, const string &w, map<char, char> &m) {
  for(int i = 0; i < x.size(); ++i) {
    m[x[i]] = w[i];
    m[w[i]] = x[i];
  }
}

bool update(int k, map<char, char> m) {
  F = vector<int>(V.size());
  for(int i = k; i < V.size(); ++i) {
    for(int j = 0; j < N; ++j) {
      if(ok(V[i], word[j], m)) {
        F[i] |= 1 << j;
      }
    }
    if(!F[i]) return false;
  }
  return true;
}

void rec(int k, map<char, char> m) {
  if(k == V.size()) {
    if(ans.size()) throw 0;
    ans = m;
    return;
  }
  for(int i = 0; i < N; ++i) {
    if(F[k] >> i & 1); else continue;
    map<char, char> nm = m;
    reg(V[k], word[i], nm);
    vector<int> undo = F;
    if(update(k+1, nm)) {
      rec(k+1, nm);
    }
    F = undo;
  }
}

int main() {
  while(cin >> N && N) {
    for(int i = 0; i < N; ++i) {
      cin >> word[i];
    }
    cin.ignore();
    getline(cin, line);
    stringstream ss(line.substr(0, line.size()-1));
    set<string> ws;
    for(string s; ss >> s; ) ws.insert(s);
    V.clear();
    for(set<string>::iterator it = ws.begin();
        it != ws.end(); ++it) {
      V.push_back(*it);
    }
    update(0, map<char, char>());
    ans = map<char, char>();
    try {
      rec(0, map<char, char>());
      if(ans.empty()) throw 0;
      for(int i = 0; i < line.size(); ++i) {
        if(isalpha(line[i])) cout << ans[line[i]];
        else cout << line[i];
      }
      cout << endl;
    } catch(...) {
      cout << "-." << endl;
    }
  }
  return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 1368
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a); i<(b); ++i)
#define REP(i,n) FOR(i,0,n)

vs dfs(vs &words,vs &c_words,map<char,char> &m,int cur,vs &orig_c_words){
  vs ret;
  if(cur==orig_c_words.size()){
    REP(i,orig_c_words.size()){
      string s;
      REP(j,orig_c_words[i].size()){
        s.push_back(m[orig_c_words[i][j]]);
      }
      ret.push_back(s);
    }
    return ret;
  }

  REP(i,words.size()){
    if(words[i].size()==c_words[cur].size()){
      map<char,char> nm(m);
      bool ok=true;
      REP(j,words[i].size()){
        map<char,char>::iterator it_i=nm.find(words[i][j]);
        map<char,char>::iterator it_c=nm.find(c_words[cur][j]);
        bool ei=it_i!=nm.end();
        bool ec=it_c!=nm.end();
        if(ei&&ec){
          if(it_i->second!=c_words[cur][j]||it_c->second!=words[i][j]){
            ok=false;
            break;
          }
        }else if(ei||ec){
          ok=false;
          break;
        }else{
          nm[words[i][j]]=c_words[cur][j];
          nm[c_words[cur][j]]=words[i][j];
        }
      }
      if(ok){
        //cerr<<"cur:"<<cur<<endl;
        vs res=dfs(words,c_words,nm,cur+1,orig_c_words);
        //cerr<<"res:"<<res.size()<<endl;
        if(res.size()>0){
          if(res.size()==100){
            return vs(100);
          }
          if(ret.size()){
            return vs(100);
          }else{
            ret=res;
          }
        }
      }
    }
  }
  return ret;

}
bool pred(const string &l,const string &r){
  if(l.size()==r.size()){
    return l>r;
  }else{
    return l.size()>r.size();
  }
}
int main(){
  int n;
  while(cin>>n,n){
    vs words(n);
    REP(i,n){
      cin>>words[i];
    }
    string sequence;
    getline(cin,sequence);
    getline(cin,sequence);
    vs c_words;
    int prev=0;
    REP(i,sequence.size()){
      switch(sequence[i]){
        case ' ':
        case '.':
          c_words.push_back(sequence.substr(prev,i-prev));
          prev=i+1;
          break;
      }
    }
    vs orig_c_words(c_words);
    sort(ALL(c_words),pred);
    map<char,char> m;
    vs res=dfs(words,c_words,m,0,orig_c_words);
    if(res.size()&&res.size()<100){
      REP(i,res.size()){
        cout<<res[i]<<(i<res.size()-1?" ":"");
      }
      cout<<"."<<endl;
    }else{
      cout<<"-."<<endl;
    }
  }
}
accuracy: 1
time_ms: 160
memory_kb: 1280
final_rank: 4

code_snippet: #include <algorithm>
#include <array>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <sstream>
#include <vector>
using namespace std;

constexpr int MAX_M = 50;
constexpr int MAX_LENGTH = 20;

int n, m;
string target;
vector<string> candidates[MAX_LENGTH + 1];
pair<int, string> words[MAX_M];
vector<char> assign(128, -1);

int cnt;

bool dfs(int idx = 0) {
	if(idx == m) {
		if(++cnt == 1) {
			for(auto &c : target) {
				if(c != ' ') c = assign[c];
			}
			return true;
		}
		else {
			return false;
		}
	}

	const auto &s = words[idx].second;

	for(const auto &t : candidates[s.size()]) {
		auto tmp(assign);

		for(int i = 0; i < static_cast<int>(s.size()); ++i) {
			if(!(tmp[s[i]] == t[i] || (tmp[s[i]] == -1 && tmp[t[i]] == -1))) {
				goto next;
			}

			tmp[s[i]] = t[i];
			tmp[t[i]] = s[i];
		}

		assign.swap(tmp);
		if(!dfs(idx + 1)) return false;
		assign = move(tmp);
		
	next:;
	}

	return true;
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	while(cin >> n && n) {
		for_each(begin(candidates), end(candidates), [](vector<string> &v) { v.clear(); });

		for(int i = 0; i < n; ++i) {
			string in;
			cin >> in;

			const int len = in.size();
			candidates[len].emplace_back(move(in));
		}

		cin.ignore();
		getline(cin, target);
		target = target.substr(0, target.size() - 1);

		{
			string in;
			istringstream iss(target);

			for(m = 0; iss >> in; ++m) {
				words[m].second = in;
				in.erase(unique(in.begin(), in.end()), in.end());
				words[m].first = in.size();
			}
		}

		sort(words, words + m, greater<pair<int, string>>());

		cnt = 0;
		fill(begin(assign), end(assign), -1);
		dfs();

		cout << (cnt == 1 ? target : "-") << ".\n";
	}

	return EXIT_SUCCESS;
}
accuracy: 1
time_ms: 20
memory_kb: 1260
final_rank: 2

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

const int IINF = INT_MAX;

int n,found,len;
vector<string> buf[30],seq;
string tmp,sequence,answer;
char transfer[26];

bool comp(const string& a,const string& b) {
  set<char> A,B;
  rep(i,a.size()) A.insert(a[i]);
  rep(i,b.size()) B.insert(b[i]);
  return A.size() > B.size();
}

void dfs(int cur){

  if( found >= 2 ) return;

  if( cur >= len ){
    ++found;
    rep(i,answer.size()) if( isupper(answer[i]) ) answer[i] = transfer[answer[i]-'A'];
    return;
  }

  int word_size = seq[cur].size();

  rep(i,(int)buf[word_size].size()){
    string word = buf[word_size][i];

    int *backtrack = new int[word_size+1];
    backtrack[0] = -1; // sentinel
    bool error = false;
    rep(j,word_size){
      if( transfer[word[j]-'A'] == '?' && transfer[seq[cur][j]-'A'] == '?' ) {
        backtrack[j] = 1, backtrack[j+1] = -1;
        transfer[word[j]-'A'] = seq[cur][j];
        transfer[seq[cur][j]-'A'] = word[j];
      } else if( transfer[word[j]-'A'] == seq[cur][j] && transfer[seq[cur][j]-'A'] == word[j] ) {
        backtrack[j] = 0;
      } else {
        backtrack[j] = -1;
        error = true;
        break;
      }
    }

    if( !error ) dfs( cur+1 );

    int j = 0;
    while( backtrack[j] != -1 && j < word_size) {
      if( backtrack[j] == 1 ) transfer[word[j]-'A'] = transfer[seq[cur][j]-'A'] = '?';
      ++j;
    }

  }

}

int main(){
  while( cin >> n, n ){
    seq.clear();
    rep(i,30) buf[i].clear();
    rep(i,n) {
      cin >> tmp;
      buf[(int)tmp.size()].push_back(tmp);
    }
    cin.ignore();
    getline(cin,sequence);
    stringstream ss(sequence.substr(0,(int)sequence.size()-1));
    while( !( ss >> tmp ).fail() ) seq.push_back(tmp);
    sort(seq.begin(),seq.end(),comp);

    answer = sequence;
    found = 0, len = (int)seq.size();
    rep(i,26) transfer[i] = '?';
    dfs(0);

    cout << ((found==1)?answer:"-.") << endl;

  }
  return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 8100
final_rank: 18

code_snippet: #include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

char w1[22][110];
char w2[44][110];
int w1_cnt, w2_cnt;
int cw[28];
int aw[28];
bool ok[44][22];
int ok_cnt[44];
bool vis[44];
int ans;

bool cal_ok(int i, int j) {
    if (strlen(w2[i]) != strlen(w1[j])) return false;
    int tw[28];
    memcpy(tw, cw, sizeof(tw));
    for (int k = 0; w2[i][k]; k++) {
        int c = w2[i][k] - 'A';
        int d = w1[j][k] - 'A';
        if (tw[c] != -1 && tw[c] != w1[j][k]) return false;
        if (tw[d] != -1 && tw[d] != w2[i][k]) return false;
        tw[c] = w1[j][k];
        tw[d] = w2[i][k];
    }
    return true;
}
void get_ok() {
    memset(ok, 0, sizeof(ok));
    for (int i = 0; i < w2_cnt; i++)
        for (int j = 0; j < w1_cnt; j++) {
            ok[i][j] = cal_ok(i, j);
            if (ok[i][j]) ok_cnt[i]++;
        }
}
void print_ok() {
	for (int i = 0; i < w2_cnt; i++) {
		for (int j = 0; j < w1_cnt; j++) {
			printf("%d ", ok[i][j]);
		}
		puts("");
	}
}

int find() {
    int p = -1;
    for (int i = 0; i < w2_cnt; i++) if (!vis[i])
        if (p == -1 || ok_cnt[i] < ok_cnt[p]) p = i;
    return p;
}

void dfs(int u) {
    if (ans > 1) return;
    if (u == -1) {
        ans++;
        memcpy(aw, cw, sizeof(aw));
        return;
    }
//    bool tmp[44][22];
//    int tmp_cnt[44];
    int tw[28];
//    memcpy(tmp, ok, sizeof(tmp));
//    memcpy(tmp_cnt, ok_cnt, sizeof(ok_cnt));
    memcpy(tw, cw, sizeof(tw));
    get_ok();
    for (int i = 0; i < w1_cnt; i++) if (ok[u][i]) {
        vis[u] = true;
        for (int j = 0; w2[u][j]; j++) {
            int c = w2[u][j] - 'A';
            int d = w1[i][j] - 'A';
            cw[c] = w1[i][j];
            cw[d] = w2[u][j];
        }
        dfs(find());
        memcpy(cw, tw, sizeof(tw));
        vis[u] = false;
        get_ok();
//        memcpy(ok_cnt, tmp_cnt, sizeof(tmp_cnt));
//        memcpy(ok, tmp, sizeof(tmp));
    }
}

void work() {
    for (int i = 0; i < w1_cnt; i++)
        scanf("%s", w1[i]);
    w2_cnt = 0;
    while (true) {
        char str[100];
        scanf("%s", str);
        int len = strlen(str);
        if (str[len - 1] == '.') {
            str[--len] = 0;
            strcpy(w2[w2_cnt], str);
            w2_cnt++;
            break;
        } else {
            strcpy(w2[w2_cnt], str);
            w2_cnt++;
        }
    }
//for (int i = 0; i < w2_cnt; i++) printf("%s ", w2[i]); puts(".....");
    memset(cw, -1, sizeof(cw));
    get_ok();
//print_ok();
    memset(vis, 0, sizeof(vis));
    int p = find();
//printf("%d\n", p);
    ans = 0;
    dfs(p);
    if (ans > 1) {
        puts("-.");
        return;
    }
//for (int i = 0; i < 26; i++) printf("%d ", aw[i]); puts("?");
    for (int i = 0; i < w2_cnt; i++) {
        for (int j = 0; w2[i][j]; j++) {
            int d = w2[i][j] - 'A';
            printf("%c", aw[d]);
        }
        if (i < w2_cnt - 1) printf(" ");
    }
    puts(".");
}

int main() {
    while (scanf("%d", &w1_cnt), w1_cnt) {
        work();
    }
    return 0;
}
accuracy: 1
time_ms: 810
memory_kb: 1044
final_rank: 6

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <cstring>
#include <sstream>
using namespace std;

int n, m;
string cand[22];
vector<string> words;

vector<int> match[82];
int matchBit[82];

vector<char> ansKey;
int ansFlg;

bool matches(string a, string b){
  if(a.size() != b.size()) return false;
  char trans[128];
  memset(trans, -1, sizeof(trans));
  for(int i = 0; i < a.size(); i++){
    if(trans[a[i]] != -1 && b[i] != trans[a[i]]) return false;
    if(trans[b[i]] != -1 && a[i] != trans[b[i]]) return false;
    trans[a[i]] = b[i];
    trans[b[i]] = a[i];
  }
  return true;
}

bool mycmp(const string &a, const string &b){
  set<char> st1;
  for(int i = 0; i < a.size(); i++) st1.insert(a[i]);
  set<char> st2;
  for(int i = 0; i < b.size(); i++) st2.insert(b[i]);

  return st1.size() > st2.size();
}

bool setKey(const string &a, const string &b, vector<char> &key){
  for(int i = 0; i < a.size(); i++){
    if(key[a[i]] != -1 && key[a[i]] != b[i] ||
       key[b[i]] != -1 && key[b[i]] != a[i]){
      return false;
    }
    key[a[i]] = b[i];
    key[b[i]] = a[i];
  }
  return true;
}

void dfs(int idx, int used, vector<char> key){
  if(idx == m){
    if(ansFlg == 1){
      ansFlg = -1;
    }
    else{
      ansFlg = 1;
      ansKey = key;
    }
    return;
  }

  for(int i = idx; i < m; i++){
    if((matchBit[i] & used) == matchBit[i]){
      return;
    }
  }

  for(int i = 0; i < match[idx].size(); i++){
    int j = match[idx][i];
    if(used & (1 << j)) continue;

    vector<char> nextKey = key;
    if(setKey(words[idx], cand[j], nextKey)){
      dfs(idx + 1, used | (1 << j), nextKey);
      if(ansFlg == -1) return;
    }
  }
}

void solve(){
  sort(words.begin(), words.end(), mycmp);

  for(int i = 0; i < m; i++){
    match[i].clear();
    matchBit[i] = 0;

    for(int j = 0; j < n; j++){
      if(matches(words[i], cand[j])){
        match[i].push_back(j);
        matchBit[i] |= (1 << j);
      }
    }
  }

  vector<char> key(128, -1);
  ansFlg = 0;
  dfs(0, 0, key);
}

int main(){
  while(cin >> n, n){
    for(int i = 0; i < n; i++){
      cin >> cand[i];

      for(int j = 0; j < i; j++){
        if(cand[j] == cand[i]){
          i--;
          n--;
          break;
        }
      }
    }

    string s;
    getline(cin, s);
    getline(cin, s);
    for(int i = 0; i < s.size(); i++) if(s[i] == '.') s[i] = ' ';

    vector<string> raw;
    stringstream ss(s);
    words.clear();

    while(ss >> s){
      raw.push_back(s);

      bool pushFlg = true;
      for(int i = 0; i < words.size(); i++){
        if(words[i] == s){
          pushFlg = false;
          break;
        }
      }
      if(pushFlg) words.push_back(s);
    }
    m = words.size();

    solve();

    if(ansFlg == 1){
      for(int i = 0; i < raw.size(); i++){
        if(i != 0) cout << " ";
        for(int j = 0; j < raw[i].size(); j++){
          cout << ansKey[raw[i][j]];
        }
      }
      cout << "." << endl;
    }
    else{
      cout << "-." << endl;
    }
  }
}
accuracy: 1
time_ms: 10
memory_kb: 1272
final_rank: 3