#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
#include <cmath>
#include <bitset>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <deque>
#include <algorithm>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#include <random>
#include <cassert>
#include <fstream>
#include <utility>
#include <functional>
#include <time.h>
#include <stack>
#include <array>
#define popcount __builtin_popcount
using namespace std;
typedef long long int ll;
typedef pair<int, int> P;
int dx[8]={1, 0, -1, 0, 1, 1, -1, -1}, dy[8]={0, 1, 0, -1, 1, -1, 1, -1};
vector<vector<int>> maketree(vector<string> s){
	int h=s.size(), w=s[0].size();
	vector<vector<int>> comp(h, vector<int>(w, -1));
	int c=0;
	for(int i=0; i<h; i++){
		for(int j=0; j<w; j++){
			if(comp[i][j]>=0) continue;
			int k=4;
			if(s[i][j]=='#') k=8;
			queue<P> que;
			que.push({i, j}); comp[i][j]=c;
			while(!que.empty()){
				P p=que.front(); que.pop();
				int x=p.first, y=p.second;
				for(int l=0; l<k; l++){
					int x1=x+dx[l], y1=y+dy[l];
					if(x1<0 || x1>=h || y1<0 || y1>=w) continue;
					if(s[x1][y1]!=s[i][j]) continue;
					if(comp[x1][y1]>=0) continue;
					comp[x1][y1]=c;
					que.push({x1, y1});
				}
			}
			c++;
		}
	}
	vector<vector<int>> g(c);
	set<P> st;
	for(int i=0; i<h; i++){
		for(int j=0; j<w; j++){
			for(int l=0; l<4; l++){
				int x1=i+dx[l], y1=j+dy[l];
				if(x1<0 || x1>=h || y1<0 || y1>=w) continue;
				if(comp[i][j]!=comp[x1][y1]){
					st.insert({comp[i][j], comp[x1][y1]});
				}
			}
		}
	}
	for(auto e:st) g[e.first].push_back(e.second);
	return g;
}
bool rooted_tree_isom(const vector<vector<int>> &g1, const vector<vector<int>> &g2, const int &r1, const int &r2){
	if(g1.size()!=g2.size()) return false;
	int n=g1.size();
	vector<int> d1(n, -1), d2(n, -1);
	d1[r1]=d2[r2]=0;
	vector<vector<int>> v1(n), v2(n);
	auto dfs1=[&](auto dfs1, int x)->void{
		v1[d1[x]].push_back(x);
		for(auto y:g1[x]){
			if(d1[y]!=-1) continue;
			d1[y]=d1[x]+1;
			dfs1(dfs1, y);
		}
	};
	dfs1(dfs1, r1);
	auto dfs2=[&](auto dfs2, int x)->void{
		v2[d2[x]].push_back(x);
		for(auto y:g2[x]){
			if(d2[y]!=-1) continue;
			d2[y]=d2[x]+1;
			dfs2(dfs2, y);
		}
	};
	dfs2(dfs2, r2);
	for(int i=0; i<n; i++) if(v1[i].size()!=v2[i].size()) return false;
	struct vec{
		vector<int> v;
		vec(){}
		vec(vector<int> v):v(v){}
		bool operator<(const vec &w) const{
			for(int i=0; i<min(v.size(), w.v.size()); i++){
				if(v[i]!=w.v[i]){
					return v[i]<w.v[i];
				}
			}
			return v.size()<w.v.size();
		}
		bool operator==(const vec &w) const{
			if(v.size()!=w.v.size()) return false;
			for(int i=0; i<v.size(); i++){
				if(v[i]!=w.v[i]){
					return false;
				}
			}
			return true;
		}
	};
	vector<int> h1(n), h2(n);
	for(int i=n-1; i>=0; i--){
		if(v1[i].empty()) continue;
		vector<vec> w;
		vector<vec> vh1(v1[i].size()), vh2(v1[i].size());
		for(int j=0; j<v1[i].size(); j++){
			vector<int> v;
			int x=v1[i][j];
			for(auto y:g1[x]){
				if(d1[y]<d1[x]) continue;
				v.push_back(h1[y]);
			}
			sort(v.begin(), v.end());
			vh1[j]=vec(v);
			w.push_back(vh1[j]);
		}
		for(int j=0; j<v2[i].size(); j++){
			vector<int> v;
			int x=v2[i][j];
			for(auto y:g2[x]){
				if(d2[y]<d2[x]) continue;
				v.push_back(h2[y]);
			}
			sort(v.begin(), v.end());
			vh2[j]=vec(v);
			w.push_back(vh2[j]);
		}
		sort(w.begin(), w.end());
		w.erase(unique(w.begin(), w.end()), w.end());
		vector<int> h11(v1[i].size()), h12(v1[i].size());
		for(int j=0; j<v1[i].size(); j++){
			h11[j]=lower_bound(w.begin(), w.end(), vh1[j])-w.begin();
			h12[j]=lower_bound(w.begin(), w.end(), vh2[j])-w.begin();
		}
		for(int j=0; j<v1[i].size(); j++){
			h1[v1[i][j]]=h11[j];
			h2[v2[i][j]]=h12[j];
		}
		sort(h11.begin(), h11.end());
		sort(h12.begin(), h12.end());
		for(int j=0; j<h11.size(); j++) if(h11[j]!=h12[j]) return false;
	}
	return true;
}
int main()
{
	while(1){
		int h1, w1, h2, w2;
		cin>>h1>>w1;
		if(h1==0) return 0;
		vector<string> s1(h1+2);
		for(int i=0; i<h1+2; i++){
			for(int j=0; j<w1+2; j++) s1[i]+='.';
		}
		for(int i=0; i<h1; i++){
			string si; cin>>si;
			for(int j=0; j<w1; j++) s1[i+1][j+1]=si[j];
		}
		vector<vector<int>> g1=maketree(s1);
		cin>>h2>>w2;
		vector<string> s2(h2+2);
		for(int i=0; i<h2+2; i++){
			for(int j=0; j<w2+2; j++) s2[i]+='.';
		}
		for(int i=0; i<h2; i++){
			string si; cin>>si;
			for(int j=0; j<w2; j++) s2[i+1][j+1]=si[j];
		}
		vector<vector<int>> g2=maketree(s2);
		if(rooted_tree_isom(g1, g2, 0, 0)) cout<<"yes"<<endl;
		else cout<<"no"<<endl;
	}
	return 0;
}


Measured memory_bytes: 3260