#include #include #include #include #include #include #include #include using namespace std; using namespace std::tr1; char buf[123456]; char cr[2][123]; char sub(char a, char b) { int v = (a-'A')-(b-'A')-1; while (v < 0) v+=26; return 'A'+v; } typedef long long ll; ll mod = 1000000009; ll q = 65537; void decrypt(char *b, char *c, int K, set >& out) { int lb = strlen(b); int lc = strlen(c); for (int i = 0; i < lb-lc+1; i++) { char kk[123]; for (int j = 0; j < lc; j++) { kk[j] = sub(b[i+j], c[j]); } ll hh[123]; hh[0] = 0; ll moc[123]; moc[0] = 1; for (int j = 0; j < 123; j++) { hh[j+1] = (q*hh[j]+kk[j])%mod; moc[j+1] = (q*moc[j])%mod; } bool bad[123]; for (int j = 0; j < 123; j++) bad[j] = false; for (int j = 1; j <= K; j++) { if (bad[j]) continue; bool ok = true; /*ll hash = hh[j]; for (int x = j; x < lc; x+=j) { if (x+j <= lc) { ll sub = (hh[x]*moc[j])%mod; ll exp = hh[x+j]-sub; while (exp < 0) exp+=mod; if (exp != hash) { ok = false; break; } } else { ll sub = (hh[x]*(moc[lc-x]))%mod; ll exp = hh[lc]-sub; while (exp < 0) exp+=mod; if (exp != hh[lc%j]) { ok = false; break; } } }*/ for (int x = j; x < lc; x+=j) { if (kk[x]!=kk[x-j]) { ok = false; break; } } if (ok) { for (int k = j; k < 123; k+=j) bad[k] = true; char kkk[123]; int shift = i%j; kkk[j] = 0; for (int k = 0; k < j; k++) { int pp = k-shift; while(pp < 0) pp+=j; kkk[k] = kk[pp]; } out.insert(make_pair(kkk, i)); } } } } void go(int K) { scanf("%s %s %s", cr[0], cr[1], buf); set > key[2]; decrypt(buf, cr[0], K,key[0]); decrypt(buf, cr[1], K,key[1]); unordered_set keys; int l[2]; l[0] = strlen(cr[0]); l[1] = strlen(cr[1]); /* for (unordered_set::iterator it = key[1].begin(); it != key[1].end(); ++it) { printf("%s\n", it->c_str()); } printf("druhe\n"); for (unordered_set::iterator it = key[0].begin(); it != key[0].end(); ++it) { printf("%s\n", it->c_str()); if (key[1].count(*it)) { if (keys.size() == 1) { printf("ambiguous\n"); return; } keys.insert(*it); } }*/ for (set >::iterator it = key[0].begin(); it != key[0].end(); ++it) { pair ff = make_pair(it->first, it->second+l[0]); set >::iterator it2 = key[1].lower_bound(ff); if (it2 == key[1].end()) continue; if (it2->first == it->first) { if (keys.size() == 1) { printf("ambiguous\n"); return; } keys.insert(it->first); } } for (set >::iterator it = key[1].begin(); it != key[1].end(); ++it) { pair ff = make_pair(it->first, it->second+l[1]); set >::iterator it2 = key[0].lower_bound(ff); if (it2 == key[0].end()) continue; if (it2->first == it->first) { if (keys.size() == 1) { printf("ambiguous\n"); return; } keys.insert(it->first); } } if (keys.size() == 0) { printf("impossible\n"); return; } for (int i = 0; buf[i]; i++) { string key = *keys.begin(); printf("%c", sub(buf[i], key[i%(key.length())])); } printf("\n"); } int main() { while(true) { int K; scanf("%d", &K); if (K == 0) break; go(K); } }