// very kuso problem

#include <cassert>// c
#include <iostream>// io
#include <iomanip>
#include <fstream>
#include <sstream>
#include <vector>// container
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <stack>
#include <algorithm>// other
#include <complex>
#include <numeric>
#include <functional>
#include <random>
#include <regex>
using namespace std;
typedef long long ll;typedef unsigned long long ull;typedef long double ld;

#define ALL(c) c.begin(),c.end()
#define IN(l,v,r) (l<=v && v < r)
template<class T> void UNIQUE(T& v){
	sort(ALL(v));
	v.erase(unique(ALL(v)),v.end());
}

#define DUMP(x) cerr << #x <<" = " << (x)
#define LINE() cerr<< " (L" << __LINE__ << ")"

#define range(i,l,r) for(int i=(int)l;i<(int)(r);i++)
// struct range{
// 	struct Iter{
// 		int v,step;
// 		Iter& operator++(){v+=step;return *this;}
// 		bool operator!=(Iter& itr){return v<itr.v;}
// 		int& operator*(){return v;}
// 	};
// 	Iter i, n;
// 	range(int i, int n,int step):i({i,step}), n({n,step}){}
// 	range(int i, int n):range(i,n,1){}
// 	range(int n):range(0,n){}
// 	Iter& begin(){return i;}
// 	Iter& end(){return n;}
// };

//input
template<typename T1,typename T2> istream& operator >> (istream& is,pair<T1,T2>& p){return is>>p.first>>p.second;}
template<typename T1> istream& operator >> (istream& is,tuple<T1>& t){return is >> get<0>(t);}
template<typename T1,typename T2> istream& operator >> (istream& is,tuple<T1,T2>& t){return is >> get<0>(t) >> get<1>(t);}
template<typename T1,typename T2,typename T3> istream& operator >> (istream& is,tuple<T1,T2,T3>& t){return is >>get<0>(t)>>get<1>(t)>>get<2>(t);}
template<typename T1,typename T2,typename T3,typename T4> istream& operator >> (istream& is,tuple<T1,T2,T3,T4>& t){return is >> get<0>(t)>>get<1>(t)>>get<2>(t)>>get<3>(t);}
template<typename T> istream& operator >> (istream& is,vector<T>& as){range(i,0,as.size())is >>as[i];return is;}
//output
template<typename T> ostream& operator << (ostream& os, const set<T>& ss){for(auto a:ss){if(a!=ss.begin())os<<" "; os<<a;}return os;}
template<typename T1,typename T2> ostream& operator << (ostream& os, const pair<T1,T2>& p){return os<<p.first<<" "<<p.second;}
template<typename K,typename V> ostream& operator << (ostream& os, const map<K,V>& m){bool isF=true;for(auto& p:m){if(!isF)os<<endl;os<<p;isF=false;}return os;}
template<typename T1> ostream& operator << (ostream& os, const tuple<T1>& t){return os << get<0>(t);}
template<typename T1,typename T2> ostream& operator << (ostream& os, const tuple<T1,T2>& t){return os << get<0>(t)<<" "<<get<1>(t);}
template<typename T1,typename T2,typename T3> ostream& operator << (ostream& os, const tuple<T1,T2,T3>& t){return os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t);}
template<typename T1,typename T2,typename T3,typename T4> ostream& operator << (ostream& os, const tuple<T1,T2,T3,T4>& t){return os << get<0>(t)<<" "<<get<1>(t)<<" "<<get<2>(t)<<" "<<get<3>(t);}
template<typename T> ostream& operator << (ostream& os, const vector<T>& as){range(i,0,as.size()){if(i!=0)os<<" "; os<<as[i];}return os;}
template<typename T> ostream& operator << (ostream& os, const vector<vector<T>>& as){range(i,0,as.size()){if(i!=0)os<<endl; os<<as[i];}return os;}

struct Edge{
	char c;int f,t;
};

class NFA{
public:
	static NFA ONE;
	int N;
	vector<Edge> es;
	vector<vector<int>> f_cache, t_cache;
	
	vector<vector<int>> reachable;
	vector<vector<vector<int>>> trans;

	int s,t;
	NFA(int N = 0):N(N),s(0),t(1){
		f_cache = t_cache = vector<vector<int>>(N);
	}
	void add_edge(char c,int f,int t){
		int eid = es.size();
		es.push_back({c,f,t});
		f_cache[f].push_back(eid);t_cache[t].push_back(eid);
	}
	static NFA *disjoint(NFA* a,NFA* b){
		// merge technique
		NFA *res = (a->es.size() < b->es.size()? b : a),*add = (a->es.size() < b->es.size()? a : b);
		res->f_cache.resize(res->N + add->N);res->t_cache.resize(res->N + add->N);
		int eid = res->es.size();
		for(Edge& e:add->es){
			e.f += res->N; e.t += res->N;
			res->es.push_back(e);
			res->f_cache[e.f].push_back(eid);res->t_cache[e.t].push_back(eid);eid++;
		}
		res->N += add->N;
		return res;
	}
	static NFA* Union(NFA* a,NFA* b){
		bool bl = a->es.size() < b->es.size();
		int as = (bl?b->N:0)+a->s,at = (bl?b->N:0)+a->t,bs = (!bl?a->N:0)+b->s,bt = (!bl?a->N:0)+b->t;
		int S = a->N+b->N,T = a->N+b->N+1;
		NFA* ab = disjoint(a,b),*ab1 = disjoint(ab,&ONE),*res = disjoint(ab1,&ONE);
		res->add_edge('-',S,as); res->add_edge('-',S,bs);res->add_edge('-',at,T); res->add_edge('-',bt,T);
		res->s = S; res->t = T;
		return res;
	}
	static NFA* Concat(NFA* a,NFA* b){
		bool bl = a->es.size() < b->es.size();
		int as = (bl?b->N:0)+a->s,at = (bl?b->N:0)+a->t,bs = (!bl?a->N:0)+b->s,bt = (!bl?a->N:0)+b->t;
		NFA* res = disjoint(a,b);
		res->add_edge('-',at,bs);
		res->s = as; res->t = bt;
		return res;
	}
	static NFA* Star(NFA* a){
		NFA* res = disjoint(a,&ONE);
		res->add_edge('-',res->N-1,a->s); res->add_edge('-',a->t,res->N-1);
		res->s = res->t = res->N-1;
		return res;
	}

	// step
	void create_reachable(){
		queue<pair<int,int>> que; que.push({t,0});

		reachable = vector<vector<int>>(N,vector<int>(4));
		reachable[t][0] = true;
		while(!que.empty()){
			int t,d;tie(t,d) = que.front();que.pop();
			//back
			for(int eid:t_cache[t]){
				Edge& e = es[eid];
				if(e.c=='-'){
					if(!reachable[e.f][d]){
						reachable[e.f][d] = true;
						que.push({e.f,d});
					}
				}else{
					if(d+1 <reachable[e.f].size() && !reachable[e.f][d+1]){
						reachable[e.f][d+1] = true;
						que.push({e.f,d+1});
					}
				}
			}
		}
	}

	void create_trans(){
		trans = vector<vector<vector<int>>>(N,vector<vector<int>>(27));
		// eps trans
		range(st,0,N){
			vector<bool> passed(N);
			passed[st] = true;
			queue<int> que;
			range(i,0,passed.size())if(passed[i])que.push(i);
			while(!que.empty()){
				int s = que.front();que.pop();
				for(int eid : f_cache[s])if(es[eid].c =='-' && !passed[es[eid].t]){
					passed[es[eid].t] = true;
					que.push(es[eid].t);
				}
			}
			range(i,0,N)if(passed[i]) trans[st][26].push_back(i);
		}
		range(st,0,N)range(c,'A','Z'+1){
			// eps trans
			vector<bool> passed(N);
			for(int s:trans[st][26])passed[s]=true;
			vector<bool> npassed(N);
			queue<int> que;
			range(i,0,passed.size())if(passed[i])que.push(i);
			while(!que.empty()){
				int s = que.front();que.pop();
				for(int eid : f_cache[s])if((es[eid].c == c || es[eid].c =='.') && !npassed[es[eid].t]){
					npassed[es[eid].t] = true;
					que.push(es[eid].t);
				}
			}
			// eps trans
			range(i,0,N)if(npassed[i])for(int s:trans[i][26]) npassed[s] = true;
			range(s,0,npassed.size())if(npassed[s]){
				bool alleps = true;
				for(int eid : f_cache[s])alleps &= es[eid].c=='-';
				// ???????????? ?? ????§???????????????´?????????????????? for ?????????
				if(alleps && t != s)continue; 
				trans[st][c-'A'].push_back(s);
			}
		}
	}
} NFA::ONE = NFA(1);

class REGtoNFA{
public:
	static NFA* pattern(string& s,int& i,int e){
		NFA* p = simple(s,i,e);
		while(i < e && s[i]=='|'){
			i++;// '|'
			NFA* q = simple(s,i,e);
			p = NFA::Union(p,q);
		}
		return p;
	}
	static NFA* simple(string& s,int& i,int e){
		NFA* p = basic(s,i,e);
		while(i < e && s[i]!='|'){
			NFA* q = basic(s,i,e);
			p = NFA::Concat(p,q);
		}
		return p;
	}
	static NFA* basic(string& s,int& i,int e){
		NFA* p = elementary(s,i,e);
		if(i < (int)s.size() && s[i]=='*'){
			i++;// *
			p = NFA::Star(p);
		}
		return p;
	}
	static NFA* elementary(string& s,int& i,int e){
		NFA* p;
		if(s[i]=='('){
			i++; // (
			int d=1;
			for(int j=i;j<e;j++){
				if(s[j]=='(') d++;
				if(s[j]==')') d--;
				if(d==0){
					e = j;break;
				}
			}
			p = pattern(s,i,e);
			i++; // )
		}else{
			p = new NFA(2);
			p->add_edge(s[i],p->s,p->t);
			i++;// c
		}
		return p;
	}
};


int rc = 0;
class Main{
	public:
	int h,w;
	vector<string> tmp,res;

	vector<NFA> NFAs;
	vector<vector<int>> stats;

	void dfs(int y,int x,int c){
		if(rc>1)return;
		if(y==h){
			rc+=c; 
			res = tmp;
			return;
		}
		// ????????????????????¶??????????????´????????????????????????????????¢?´¢
		vector<vector<vector<int>>> nstats(2,vector<vector<int>>(26));
		vector<int> nfai={y,h+x};
		range(ni,0,2)for(char nc = 'A';nc <= 'Z'; nc++){
			for(int s:stats[nfai[ni]])for(int t:NFAs[nfai[ni]].trans[s][nc-'A']) nstats[ni][nc-'A'].push_back(t);
			UNIQUE(nstats[ni][nc-'A']);
		}
		vector<int> gid(26);iota(ALL(gid),0);
		for(char c1='A'; c1 <= 'Z';c1++)for(char c2='A'; c2 < c1;c2++)if(gid[c2-'A']==c2-'A'){
			if(nstats[0][c1-'A'].size() == nstats[0][c2-'A'].size() && nstats[1][c1-'A'].size() == nstats[1][c2-'A'].size()){
				bool eq = true;
				range(ni,0,2){
					range(i,0,nstats[ni][c1-'A'].size()){
						eq &= nstats[ni][c1-'A'][i] == nstats[ni][c2-'A'][i];
						if(!eq)break;
					}
					if(!eq)break;
				}
				if(eq){
					gid[c1-'A'] = gid[c2-'A'];
					break;
				}
			}
		}
		vector<int> gc(26);
		range(i,0,26)gc[gid[i]]++;

		for(char c='A'; c <= 'Z';c++)if(gid[c-'A']==c-'A'){
			tmp[y][x] = c;
			bool tmpOK = true;
			// eda ??????????????? de ikerukana ?
			{
				bool ok = false;
				for(int s:nstats[0][c-'A'])ok |= NFAs[y].reachable[s][w-1-x];
				tmpOK &= ok;
			}
			{
				bool ok = false;
				for(int s:nstats[1][c-'A'])ok |= NFAs[h+x].reachable[s][h-1-y];
				tmpOK &= ok;
			}
			if(x == w-1){
				bool ok = false;
				for(int s:nstats[0][c-'A'])ok |= s == NFAs[y].t;
				tmpOK &= ok;
			}
			if(y == h-1){
				bool ok = false;
				for(int s:nstats[1][c-'A'])ok |= s == NFAs[h+x].t;
				tmpOK &= ok;
			}
			if(tmpOK){
				vector<int> tmpp = stats[y],tmpq = stats[h+x];
				stats[y] = nstats[0][c-'A']; stats[h+x] = nstats[1][c-'A'];
				if(x+1 < w) dfs(y,x+1,gc[c-'A']);
				else dfs(y+1,0,gc[c-'A']);
				stats[y] = tmpp; stats[h + x] = tmpq;
			}
		}
	}

	void run(){
		while(true){
			cin >> h >> w;
			if(h==0 && w==0)break;
			rc = 0;
			tmp = res = vector<string>(h,string(w,'-'));
			vector<string> ss(h+w);cin >> ss;
 			// h <= 4, w <= 4
			NFAs = vector<NFA>(h+w);
			range(i,0,h+w){
				string s = "";
				range(j,1,ss[i].size()-1) s+=ss[i][j];
				int cur = 0, e = s.size();
				NFAs[i] = *REGtoNFA::pattern(s,cur,e);
			}
			range(i,0,h+w){
				NFAs[i].create_reachable();
				NFAs[i].create_trans();
			}
			stats = vector<vector<int>>(h+w);
			range(i,0,h+w) stats[i].push_back(NFAs[i].s);

			dfs(0,0,1);
			if(rc > 1){
				cout << "ambiguous" <<endl; 
			}else if(rc == 0){
				cout << "none" <<endl;
			}else{
				range(i,0,h) cout << res[i] <<endl;
			}
		}
	}
};

int main(){
	cout <<fixed<<setprecision(20);
	cin.tie(0);
	ios::sync_with_stdio(false);
	Main().run();
	return 0;
}

Measured memory_bytes: 41044