#include using namespace std; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int H, W; cin >> H >> W; vector S(H); for (auto &s : S) cin >> s; // 盤面からカギの開始位置を復元する。 // (r, c) ごとに、横・縦のどちらか一方でもカギがあれば // 1つの添字を持つ。 struct KeyPos { int r, c; bool horizontal; bool vertical; }; vector keys; for (int r = 0; r < H; ++r) { for (int c = 0; c < W; ++c) { if (S[r][c] == '#') continue; bool horizontal = (c == 0 || S[r][c - 1] == '#') && (c + 1 < W && S[r][c + 1] == '.'); bool vertical = (r == 0 || S[r - 1][c] == '#') && (r + 1 < H && S[r + 1][c] == '.'); if (horizontal || vertical) { keys.push_back({r, c, horizontal, vertical}); } } } // 入力される R_i, C_i を読む。 vector> clues; string R, C; while (cin >> R >> C) { clues.emplace_back(R, C); } // カギの個数が一致する必要がある。 if (clues.size() != keys.size()) { cout << "No\n"; return 0; } // 各白マスが実際にカギで使われているかを管理する。 vector> usedH(H, vector(W, false)); vector> usedV(H, vector(W, false)); // 交差部分の文字を記録する。 vector> board(H, vector(W, '?')); for (int k = 0; k < (int)keys.size(); ++k) { auto [r, c, hasH, hasV] = keys[k]; auto [rs, cs] = clues[k]; // ------------------------- // 横のカギ // ------------------------- if (hasH) { if (rs == "-") { cout << "No\n"; return 0; } int len = 0; while (c + len < W && S[r][c + len] == '.') { ++len; } // 横の白マスの長さと答えの長さが一致する必要がある。 if ((int)rs.size() != len) { cout << "No\n"; return 0; } for (int x = 0; x < len; ++x) { int nc = c + x; usedH[r][nc] = true; if (board[r][nc] != '?' && board[r][nc] != rs[x]) { cout << "No\n"; return 0; } board[r][nc] = rs[x]; } } else { // 横カギが存在しないなら "-" でなければならない。 if (rs != "-") { cout << "No\n"; return 0; } } // ------------------------- // 縦のカギ // ------------------------- if (hasV) { if (cs == "-") { cout << "No\n"; return 0; } int len = 0; while (r + len < H && S[r + len][c] == '.') { ++len; } // 縦の白マスの長さと答えの長さが一致する必要がある。 if ((int)cs.size() != len) { cout << "No\n"; return 0; } for (int x = 0; x < len; ++x) { int nr = r + x; usedV[nr][c] = true; if (board[nr][c] != '?' && board[nr][c] != cs[x]) { cout << "No\n"; return 0; } board[nr][c] = cs[x]; } } else { // 縦カギが存在しないなら "-" でなければならない。 if (cs != "-") { cout << "No\n"; return 0; } } } // すべての白マスが横・縦のカギによって // ちょうど使われていることを確認する。 for (int r = 0; r < H; ++r) { for (int c = 0; c < W; ++c) { if (S[r][c] == '.') { if (!usedH[r][c] && !usedV[r][c]) { cout << "No\n"; return 0; } } } } cout << "Yes\n"; return 0; }