#include using namespace std; using lli = long long int; using ld = long double; vector> directions = {{0, 1},{0, -1},{1, 0},{-1, 0}}; int main() { int r, c; cin >> r >> c; vector> v(r, vector(c)); // + - 1 for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { cin >> v[i][j]; } } vector> prev(r, vector(c, 0)); vector> visitedFirst(r, vector(c, false)); vector> w(r, vector(c)); // + - 1 queue> q; for (int i = 0; i < r; i++) { for (int j = 0; j < c; j++) { cin >> w[i][j]; if (w[i][j] == '*') { prev[i][j] = -1; visitedFirst[i][j] = true; q.push({i,j}); } } } bool trouve = false; int x1; int x2; while (!q.empty()) { auto current = q.front(); q.pop(); x1 = current.first; x2 = current.second; if (v[x1][x2] == '*') { trouve = true; break; } for (int dir = 0; dir < 4; dir++) { auto curDir = directions[dir]; auto y1 = x1 + curDir.first; auto y2 = x2 + curDir.second; if (y1 >= 0 && y1 < r && y2 >= 0 && y2 < c && !visitedFirst[y1][y2] && v[y1][y2] != 'X') { visitedFirst[y1][y2] = true; q.push({y1, y2}); prev[y1][y2] = dir; } } } if (!trouve) { cout << "NO\n"; return 0; } vector> visitedSecond(r, vector(c, false)); q = queue>(); auto qEnlev = deque>(); q.push({x1, x2}); visitedSecond[x1][x2] = true; while (!q.empty()) { auto top = q.front(); q.pop(); auto z1 = top.first; auto z2 = top.second; if (w[z1][z2] == '.') { qEnlev.push_front(top); } for (int dir = 0; dir < 4; dir++) { auto curDir = directions[dir]; auto y1 = z1 + curDir.first; auto y2 = z2 + curDir.second; if (y1 >= 0 && y1 < r && y2 >= 0 && y2 < c && !visitedSecond[y1][y2] && v[y1][y2] == '*') { visitedSecond[y1][y2] = true; q.push({y1, y2}); } } } vector, pair>> solution; while (w[x1][x2] != '*') { auto dback = directions[prev[x1][x2]]; x1 -= dback.first; x2 -= dback.second; solution.push_back({qEnlev.front(), {x1, x2}}); v[qEnlev.front().first][qEnlev.front().second] = '.'; v[x1][x2] = '*'; qEnlev.pop_front(); if (w[x1][x2] == '.') { qEnlev.push_back({x1, x2}); } } q = queue>(); vector> visitedThird(r, vector(c, false)); q.push({x1,x2}); visitedThird[x1][x2] = true; while (!q.empty()) { auto current = q.front(); q.pop(); x1 = current.first; x2 = current.second; if (v[x1][x2] != '*') { solution.push_back({qEnlev.front(), {x1, x2}}); v[qEnlev.front().first][qEnlev.front().second] = '.'; v[x1][x2] = '*'; qEnlev.pop_front(); } for (int dir = 0; dir < 4; dir++) { auto curDir = directions[dir]; auto y1 = x1 + curDir.first; auto y2 = x2 + curDir.second; if (y1 >= 0 && y1 < r && y2 >= 0 && y2 < c && !visitedThird[y1][y2] && w[y1][y2] == '*') { visitedThird[y1][y2] = true; q.push({y1, y2}); } } } cout << "YES\n"; cout << solution.size() << "\n"; for (auto& part : solution) { cout << part.first.first + 1 << " " << part.first.second + 1 << " " << part.second.first + 1 << " " << part.second.second + 1 << "\n"; } // + - 1 return 0; }