#include <cstdio>
#include <cstdlib>
#include <string>
#include <vector>
#include <cstring>
#include <algorithm>

using namespace std;

int n;
string sniz[101];
char ss[15];
vector <char> abcd[102],zauku;
int nextabcd;
char abeceda[300];
int abn;
char sta[300];
bool uskl;

void ubaci(int c1, int c2) {
	if (sta[c1]==c2) {
		uskl=true;
		return;
	};
	sta[c2]=c1;
	if (abn==0) {
		abeceda[0]=c1;
		abeceda[1]=c2;
		abn=2;
		return;
	};
	bool dal;
	for (int i=0;i<abn;i++) {
		if (abeceda[i]==c1) {
			dal=false;
			for (int j=i+1;j<abn;j++) {
				if (abeceda[j]==c2) dal=true;
			};
			if (!dal) {
				for (int j=abn;j>=i+2;j--) {
					abeceda[j]=abeceda[j-1];
				};
				abeceda[i+1]=c2;
			};
			break;
		};
		if (abeceda[i]==c2) {
			dal=false;
			for (int j=i+1;j<abn;j++) {
				if (abeceda[j]==c1) dal=true;
			};
			if (!dal) {
				for (int j=abn;j>=i+1;j--) {
					abeceda[j]=abeceda[j-1];
				};
				abeceda[i]=c1;
			} else {
				for (int j=i;j<abn;j++) {
					abeceda[j]=abeceda[j+1];
					if (abeceda[j+1]==c1) {
						abeceda[j+1]=c2;
						break;
					};
				};
			};
			break;
		};
	};
	abn++;
};

void rek(int x,int Od, int Do) {
	bool b=false;
	for (int i=Od;i<Do;i++) {
		if (sniz[i].size()>x) {
			b=true;
		};
	};
	if (!b) return;
	
	char zadnji=' ';
	for (int i=Od;i<Do;i++) {
		if (sniz[i].size()<=x) continue;
		if (sniz[i][x]!=zadnji) abcd[nextabcd].push_back(sniz[i][x]);
		zadnji=sniz[i][x];
	};
	nextabcd++;
	
	char tren=sniz[Od][x];
	int poc=Od;
	for (int i=Od+1;i<Do;i++) {
		if (sniz[i].size()<=x) {
			if (tren!=' ' && i-poc>1) rek(x+1,poc,i);
			poc=i;
			tren=' ';
			continue;
		};
		if (sniz[i][x]!=tren) {
			if (tren!=' ' && i-poc>1) rek(x+1,poc,i);
			poc=i;
			tren=sniz[i][x];
		};
	};
	if (tren!=' ' && Do-poc>1) rek(x+1,poc,Do);
};

int main(void) {
	scanf("%d",&n);
	for (int i=0;i<n;i++) {
		scanf("%s",ss);
		sniz[i]=ss;
		for (int j=0;j<sniz[i].size();j++) {
			zauku.push_back(sniz[i][j]);
		};
	};
	nextabcd=0;
	rek(0,0,n);
	
	/*for (int i=0;i<nextabcd;i++) {
		for (int j=0;j<abcd[i].size();j++) {
			printf("%c ",abcd[i][j]);
		};
		printf("\n");
	};*/
	
	bool vec=false;
	
	vector <int> zaposlije,pomm;
	for (int i=0;i<nextabcd;i++) zaposlije.push_back(i);
	
	int zadnja=-1;
	
	bool upit=false;
	uskl=false;
	while (zaposlije.size()>0) {
		if (zaposlije.size()==zadnja) {
			upit=true;
			break;
		};
		zadnja=zaposlije.size();
		pomm.clear();
		for (int bz=0;bz<zaposlije.size();bz++) {
			int i=zaposlije[bz];
			if (!vec && abcd[i].size()>1) {
				for (int k=0;k<abcd[i].size()-1;k++) {
					for (int j=k+1;j<abcd[i].size();j++) {
						ubaci(abcd[i][k],abcd[i][j]);
						if (uskl) break;
					};
					if (uskl) break;
				};
				vec=true;
				continue;
			}
			if (uskl) break;
			bool ok=false;
			for (int j=0;j<abcd[i].size();j++) {
				for (int k=0;k<abn;k++) {
					if (abeceda[k]==abcd[i][j]) {
						ok=true;
						break;
					}
				};
				if (ok) break;
			};
			if (!ok) {
				pomm.push_back(i);
			} else {
				for (int k=0;k<abcd[i].size()-1;k++) {
					for (int j=k+1;j<abcd[i].size();j++) {
						ubaci(abcd[i][k],abcd[i][j]);
						if (uskl) break;
					};
					if (uskl) break;
				};
				if (uskl) break;
			};
		};
		if (uskl) break;
		zaposlije=pomm;
	};
	
	if (uskl) {
		printf("!\n");
	} else {
		sort(zauku.begin(),zauku.end());
		int uku=unique(zauku.begin(),zauku.end())-zauku.begin();
		if (upit || uku>abn) {
			printf("?\n");
		} else {
			for (int i=0;i<abn;i++) {
				printf("%c",abeceda[i]);
			};
			printf("\n");
		}
	}
//	system("pause");
	return 0;
};
