#include using namespace std; #define all(x) begin(x), end(x) void fail(){ cout << "No" << endl; exit(0); }; int H, W, N; void print(int idx) { cerr << idx / W << " " << idx%W << endl; } void fill(vector& occupied, map>& sides, int idx, int from = -1) { if (occupied[idx]) fail(); occupied[idx] = true; for (auto s: sides[idx]) { if (s != from) { fill(occupied, sides, s, idx); } } sides.erase(idx); }; int main() { cin.tie(0)->sync_with_stdio(0); cin.exceptions(cin.failbit); cin >> H >> W >> N; vector occupied(H * W, false); auto idx = [=] (int x, int y) { return x * W + y; }; // idx & idx, both dirs; map > sides; for (size_t i = 0; i < N; ++i) { int X, Y, K; char c; cin >> X >> Y >> K >> c; X--; Y--; int dir_y = 0; int dir_x = 0; if (c == 'R') { dir_y = 1; } else if (c == 'L') { dir_y = -1; } if (c == 'U') { dir_x = -1; } else if (c == 'D') { dir_x = 1; } for (int j = 1; j < K-1; ++j){ fill(occupied, sides, idx(X + dir_x * j, Y + dir_y * j)); } auto start = idx(X, Y); auto end = idx(X + dir_x * (K-1), Y + dir_y * (K-1)); if (occupied[start]) { fill(occupied, sides, end); } else if(occupied[end]) fill(occupied, sides, start); else { sides[start].insert(end); sides[end].insert(start); } } auto remove_value = [&](int idx1, int idx2) { auto& s = sides[idx1]; s.erase(idx2); }; auto remove_pair = [&](int idx1, int idx2) { remove_value(idx1, idx2); remove_value(idx2, idx1); }; while (sides.size()) { auto it = sides.begin(); if (it->second.empty()) { sides.erase(it); continue; } std::map val_to_idx; std::vector stack; auto insert_value = [&](int idx) { val_to_idx[idx] = stack.size(); stack.push_back(idx); }; auto pop_value = [&]() { auto val = stack[stack.size()-1]; stack.pop_back(); val_to_idx.erase(val); }; insert_value(it->first); while (stack.size()) { int idx = stack[stack.size() - 1]; auto& conn = sides[idx]; if (conn.size() == 1 && stack.size() > 1) { int idx2 = *conn.begin(); remove_pair(idx, idx2); fill(occupied, sides, idx); pop_value(); } else { auto it = conn.begin(); if (stack.size() > 1 && *it == stack[stack.size()-2]) it++; if (val_to_idx.find(*it) == val_to_idx.end()) { insert_value(*it); } else { int stack_idx = val_to_idx.find(*it)->second; int next_in_cycle = *it; vector to_fill; while (stack_idx < stack.size()){ int current = stack[stack.size() - 1]; to_fill.push_back(current); remove_pair(current, next_in_cycle); next_in_cycle = current; pop_value(); } for (int idx: to_fill) { fill(occupied, sides, idx); } } } } } cout << "Yes" << endl; return 0; }