#include <algorithm>
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <set>
using namespace std;
constexpr int dx[] = {1,0,-1,0}, dy[] = {0,1,0,-1}, dx_[] = {1,1,-1,-1}, dy_[] = {1,-1,1,-1};

bool in_range(int a, int b){
  return a >= 0 && a < b;
}

struct UnionFind{
private:
  vector<int> data;
public:
  int N;
  UnionFind(int n) : data(n, -1), N(n){}
  bool unite(int x, int y){
    x = find(x);
    y = find(y);
    if(x == y) return false;
    --N;
    if(data[y] < data[x]) swap(x,y);
    data[x] += data[y];
    data[y] = x;
    return x != y;
  }
  bool same(int x, int y){ return find(x) == find(y); }
  int find(int x){
    if(data[x] < 0) return x;
    return data[x] = find(data[x]);
  }
  int size(int x){ return -data[find(x)]; }
};

string to_string(const vector<set<int>> &G, int v, int prev){
  vector<string> S;
  for(auto v_ : G[v]){
    if(v_ == prev) continue;
    S.push_back(to_string(G,v_,v));
  }
  sort(S.begin(), S.end());
  string ret = "(";
  for(auto s : S) ret += s;
  ret += ")";
  return ret;
}

int main(){
  int h, w;
  while(cin >> h >> w, h){
    auto makeTree = [](int h, int w){
                      vector<string> P(h+2,string(w+2,'.'));
                      for(int i = 0; i < h; ++i)
                        for(int j = 0; j < w; ++j)
                          scanf(" %c",&P[i+1][j+1]);
                      h += 2;
                      w += 2;
                      UnionFind uf(h*w);
                      //for(int i = 0; i < h; ++i) cerr << P[i] << endl;
                      for(int i = 0; i < h; ++i){
                        for(int j = 0; j < w; ++j){
                          int v = i*w+j;
                          for(int k = 0; k < 4; ++k){
                            int i_ = i + dx[k], j_ = j + dy[k];
                            if((not in_range(i_,h)) or (not in_range(j_,w))) continue;
                            int v_ = i_*w+j_;
                            if(P[i][j] == P[i_][j_]) uf.unite(v,v_);
                          }
                          if(P[i][j] == '.') continue;
                          for(int k = 0; k < 4; ++k){
                            int i_ = i + dx_[k], j_ = j + dy_[k];
                            if((not in_range(i_,h)) or (not in_range(j_,w))) continue;
                            int v_ = i_*w+j_;
                            if(P[i][j] == P[i_][j_]) uf.unite(v,v_);
                          }
                        }
                      }
                      int C = 0;
                      map<int,int> M;
                      for(int i = 0; i < h*w; ++i){
                        int p = uf.find(i);
                        if(p != i) continue;
                        if(M[p]) continue;
                        M[p] = ++C;
                      }
                      //vector<vector<int>> G(C);
                      vector<set<int>> G(C);
                      for(int i = 0; i < h; ++i){
                        for(int j = 0; j < w; ++j){
                          int v = i*w+j;
                          for(int k = 0; k < 4; ++k){
                            int i_ = i + dx[k], j_ = j + dy[k];
                            if((not in_range(i_,h)) or (not in_range(j_,w))) continue;
                            int v_ = i_*w+j_;
                            if(P[i][j] != P[i_][j_]){
                              int a = M[uf.find(v)] - 1;
                              int b = M[uf.find(v_)] - 1;
                              // G[a].push_back(b);
                              // G[b].push_back(a);
                              G[a].insert(b);
                              G[b].insert(a);
                            }
                          }
                          for(int k = 0; k < 4; ++k){
                            int i_ = i + dx_[k], j_ = j + dy_[k];
                            if((not in_range(i_,h)) or (not in_range(j_,w))) continue;
                            int v_ = i_*w+j_;
                            if(P[i][j] != P[i_][j_]){
                              int a = M[uf.find(v)] - 1;
                              int b = M[uf.find(v_)] - 1;
                              // G[a].push_back(b);
                              // G[b].push_back(a);
                              G[a].insert(b);
                              G[b].insert(a);
                            }
                          }
                        }
                      }
                      return G;
                    };
    auto S = makeTree(h,w);
    cin >> h >> w;
    auto T = makeTree(h,w);
    string s = to_string(S,0,-1), t = to_string(T,0,-1);
    // cerr << "S" << endl;
    // for(int i = 0; i < S.size(); ++i){
    //   for(auto v : S[i]) cerr << v << " ";
    //   cerr << endl;
    // }
    // cerr << endl;
    // cerr << "T" << endl;
    // for(int i = 0; i < T.size(); ++i){
    //   for(auto v : T[i]) cerr << v << " ";
    //   cerr << endl;
    // }
    // cerr << endl;
    if(s == t) cout << "yes" << endl;
    else cout << "no" << endl;
  }
}



Measured memory_bytes: 3408