#include using namespace std; #define ST first #define ND second #define PB push_back #define IDX(x, y) ((y)*N + (x)) #define X(i) (i) % N #define Y(i) (i) / N #define VALID(x) ((x) >= 0 && (x) < N) char board[101 * 101]; vector G[101 * 101]; vector> moves; int N, K; void edge(int x1, int y1, int x2, int y2) { if (y2 > y1 || (y2 == y1 && x2 > x1)) if (VALID(x1) && VALID(y1) && VALID(x2) && VALID(y2)) if (board[IDX(x1, y1)] != '.' && board[IDX(x2, y2)] != '.') { G[IDX(x1, y1)].PB(IDX(x2, y2)); G[IDX(x2, y2)].PB(IDX(x1, y1)); } } void dfs(int i, int k) { if (board[i] == '.') return; board[i] = '.'; for (auto j : G[i]) dfs(j, i); if (k >= 0) moves.PB({i, k}); } int main() { string s; cin >> N >> s; for (int y = 0; y < N; y++) { cin >> s; for (int x = 0; x < N; x++) board[IDX(x, y)] = s[x]; } for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) switch (board[IDX(x, y)]) { case 'R': for (int i = 0; i < N; i++) { edge(x, y, x, i); edge(x, y, i, y); } break; case 'Q': for (int i = 0; i < N; i++) { edge(x, y, x, i); edge(x, y, i, y); } for (int i = -N; i < N; i++) { edge(x, y, x + i, y + i); edge(x, y, x - i, y + i); } break; case 'B': for (int i = -N; i < N; i++) { edge(x, y, x + i, y + i); edge(x, y, x - i, y + i); } break; case 'N': edge(x, y, x + 2, y + 1); edge(x, y, x + 2, y - 1); edge(x, y, x - 2, y + 1); edge(x, y, x - 2, y - 1); edge(x, y, x + 1, y + 2); edge(x, y, x + 1, y - 2); edge(x, y, x - 1, y + 2); edge(x, y, x - 1, y - 2); break; case 'K': edge(x, y, x - 1, y - 1); edge(x, y, x + 0, y - 1); edge(x, y, x + 1, y - 1); edge(x, y, x - 1, y + 0); edge(x, y, x + 1, y + 0); edge(x, y, x - 1, y + 1); edge(x, y, x + 0, y + 1); edge(x, y, x + 1, y + 1); break; } int u = 0; for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) if (board[IDX(x, y)] != '.') { u++; dfs(IDX(x, y), -1); } if (u == 1) { cout << "YES\n"; for (int i = 0; i < (int)moves.size(); i++) cout << Y(moves[i].ST) + 1 << ' ' << X(moves[i].ST) + 1 << ' ' << Y(moves[i].ND) + 1 << ' ' << X(moves[i].ND) + 1 << '\n'; } else { cout << "NO\n"; } }