#include using namespace std; using ll=long long; //#define int ll #define rep(i,a,b) for(int i=a;i<(b);i++) #define sz(x) (int)(x).size() #define all(x) begin(x), end(x) using pii=pair; using vi=vector; #define fi first #define se second #define pb push_back vector> dirs { {1, 0}, {-1, 0}, {0, -1}, {0, 1} }; signed main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); int r, c, C1 = 0, C2 = 0; cin >> r >> c; vector> blocked(r, vector(c)); auto start = blocked, finish = blocked, vis = blocked, stable = blocked; array dfs_start; for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { char x; cin >> x; if(x == '*') start[i][j] = 1, dfs_start = {i, j}, C1++; if(x == 'X') blocked[i][j] = 1; } } for(int i = 0; i < r; i++) { for(int j = 0; j < c; j++) { char x; cin >> x; if(x == '*') finish[i][j] = 1, C2++; if(x == 'X') blocked[i][j] = 1; } } vector> path; auto dfs = [&](auto self, int x, int y) -> bool {//todo: check disconnected if(vis[x][y] || blocked[x][y]) return false; vis[x][y] = 1; path.push_back({x, y}); if(finish[x][y]) return 1; for(auto [dx, dy] : dirs) { int tx = x + dx, ty = y + dy; if(min(tx, ty) < 0 || tx >= r || ty >= c) continue; if(self(self, tx, ty)) { return true; } } path.pop_back(); return false; }; if(C1 != C2 || !dfs(dfs, dfs_start[0], dfs_start[1])) { cout << "NO\n"; return 0; } cout << "YES\n"; for(auto &i : vis) fill(all(i), 0); queue> q; auto add = [&](int x, int y) { if(!finish[x][y] || vis[x][y]) return; q.push({x, y}); vis[x][y] = 1; }; add(path.back()[0], path.back()[1]); int _iters = 0; while(!q.empty()) { _iters++; auto [x, y] = q.front(); path.push_back({x, y}); q.pop(); for(auto [dx, dy] : dirs) { int tx = x + dx, ty = y + dy; if(min(tx, ty) < 0 || tx >= r || ty >= c) continue; add(tx, ty); } } assert(_iters == C1); array last = path[0]; vector> ops; auto insert = [&](int x, int y) { if(start[x][y]) { stable[x][y] = finish[x][y]; last = {x, y}; return; } for(auto &i : vis) fill(all(i), 0); stable[x][y] = 1; array rem = {0, 0}; int _iters = 0; queue> q[2]; for(int stage = 0; stage < 2; stage++) { auto add = [&](int x, int y) { if (!start[x][y] || vis[x][y]) return; int st = stage; if(stage == 0 && stable[x][y] == 0 && (last[0] != x || last[1] != y)) st = 1; q[st].push({x, y}); vis[x][y] = 1; }; if(stage == 0) add(last[0], last[1]); while (!q[stage].empty()) { _iters++; auto [x, y] = q[stage].front(); rem = q[stage].front(); q[stage].pop(); for (auto [dx, dy]: dirs) { int tx = x + dx, ty = y + dy; if (min(tx, ty) < 0 || tx >= r || ty >= c) continue; add(tx, ty); } } } //std::cout << _iters << " " << rem[0] << " " << rem[1] << " " << last[0] << " " << last[1] << endl; start[rem[0]][rem[1]] = 0; start[x][y] = 1; stable[x][y] = finish[x][y]; last = {x, y}; ops.push_back({rem[0], rem[1], x, y}); }; for(auto i : path) { insert(i[0], i[1]); } std::cout << ops.size() << '\n'; for(auto i : ops) { for(auto j : i) cout << 1 + j << " "; cout << '\n'; } }