#include <bits/stdc++.h>
using namespace std;
using ll = long long;

const ll mod = 1e9 + 7;

const int dx1[] = { 0, 1, 0, -1 };
const int dy1[] = { 1, 0, -1, 0 };

const int dx2[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
const int dy2[] = { 1, 1, 0, -1, -1, -1, 0, 1 };

struct quick_find {
	vector<int> rt;
	vector<vector<int>> vs;
	quick_find(int n) : rt(n), vs(n) {
		for (int i = 0; i < n; i++) rt[i] = i, vs[i].push_back(i);
	}
	bool same(int a, int b) {
		return rt[a] == rt[b];
	}
	void unite(int a, int b) {
		a = rt[a], b = rt[b];
		if (a == b) return;
		if (vs[a].size() < vs[b].size()) swap(a, b);
		for (auto& v : vs[b]) rt[v] = a;
		copy(vs[b].begin(), vs[b].end(), back_inserter(vs[a]));
	}
	int size(int a) {
		return vs[rt[a]].size();
	}
};

const int MAX = 2e4;

ll hs1[MAX], hs2[MAX];

void init() {
	mt19937 mt(random_device{}());
	for (int i = 0; i < MAX; i++) {
		hs1[i] = mt() % mod;
	}
	for (int i = 0; i < MAX; i++) {
		hs2[i] = mt() % mod;
	}
}

ll dfs1(int v, const vector<vector<int>>& G, int d = 0) {
	ll res = 1;
	for (auto to : G[v]) {
		res = res * (hs1[d] + dfs1(to, G, d + 1)) % mod;
	}
	return res;
}

ll dfs2(int v, const vector<vector<int>>& G, int d = 0) {
	ll res = 1;
	for (auto to : G[v]) {
		res = res * (hs2[d] + dfs2(to, G, d + 1)) % mod;
	}
	return res;
}

int main()
{
	ios::sync_with_stdio(false), cin.tie(0);
	init();
	int h, w;
	while (cin >> h >> w, h | w) {
		pair<ll, ll> cha[2];
		for (int gazo = 0; gazo < 2; gazo++) {
			if (gazo) cin >> h >> w;
			h += 2, w += 2;
			vector<vector<bool>> p(h, vector<bool>(w));
			for (int i = 1; i < h - 1; i++) {
				string s;
				cin >> s;
				for (int j = 1; j < w - 1; j++) {
					p[i][j] = s[j - 1] == '#';
				}
			}
			quick_find uf(h * w + 1);
			int back = h * w;
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) if (i == 0 || i == h - 1 || j == 0 || j == w - 1) {
					if (!p[i][j]) {
						uf.unite(i * w + j, back);
					}
				}
			}
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					int v = i * w + j;
					if (p[i][j]) {
						for (int k = 0; k < 8; k++) {
							int x = i + dx2[k], y = j + dy2[k], id = x * w + y;
							if (0 <= x && x < h && 0 <= y && y < w && p[x][y]) {
								uf.unite(v, id);
							}
						}
					}
					else {
						for (int k = 0; k < 4; k++) {
							int x = i + dx1[k], y = j + dy1[k], id = x * w + y;
							if (0 <= x && x < h && 0 <= y && y < w && !p[x][y]) {
								uf.unite(v, id);
							}
						}
					}
				}
			}
			int it = 0;
			map<int, int> f;
			f[uf.rt[back]] = it++;
			for (int i = 0; i < h; i++) {
				for (int j = 0; j < w; j++) {
					int v = i * w + j;
					if (f.count(uf.rt[v]) == 0) f[uf.rt[v]] = it++;
				}
			}
			int n = it;
			vector<vector<int>> G(n);
			vector<int> used(h * w + 1);
			used[uf.rt[back]] = true;
			queue<int> q({ uf.rt[back] });
			while (!q.empty()) {
				auto rr = q.front(); q.pop();
				for (auto v : uf.vs[rr]) {
					if (v == back) continue;
					int x = v / w, y = v % w;
					if (p[x][y]) {
						for (int k = 0; k < 8; k++) {
							int tx = x + dx2[k], ty = y + dy2[k];
							if (0 <= tx && tx < h && 0 <= ty && ty < w) {
								int id = uf.rt[tx * w + ty];
								if (used[id]) continue;
								used[id] = true;
								q.push(id);
								G[f[rr]].push_back(f[id]);
							}
						}
					}
					else {
						for (int k = 0; k < 4; k++) {
							int tx = x + dx1[k], ty = y + dy1[k];
							if (0 <= tx && tx < h && 0 <= ty && ty < w) {
								int id = uf.rt[tx * w + ty];
								if (used[id]) continue;
								used[id] = true;
								q.push(id);
								G[f[rr]].push_back(f[id]);
							}
						}
					}
				}
			}
			cha[gazo] = make_pair(dfs1(0, G), dfs2(0, G));
		}
		puts(cha[0] == cha[1] ? "yes" : "no");
	}
	return 0;
}



Measured memory_bytes: 4088