#include using namespace std; static const int DIGIT = 20; int N, T; vector> A; int curr_i = 0, curr_j = 0; int curr_s = 0; vector answer; // store single-letter operations: 'D','U','R','L','W','C' inline void move_to(int dist_i, int dist_j) { if (curr_i < dist_i) { answer.insert(answer.end(), dist_i - curr_i, 'D'); } else { answer.insert(answer.end(), curr_i - dist_i, 'U'); } if (curr_j < dist_j) { answer.insert(answer.end(), dist_j - curr_j, 'R'); } else { answer.insert(answer.end(), curr_j - dist_j, 'L'); } curr_i = dist_i; curr_j = dist_j; } inline void do_write() { A[curr_i][curr_j] ^= curr_s; answer.push_back('W'); } inline void do_copy() { curr_s ^= A[curr_i][curr_j]; answer.push_back('C'); } long long score_sum_for_v(int v) { long long xor_sum = 0; for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { int x = A[i][j]; xor_sum += max(x ^ v, x); } } return xor_sum; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); if (!(cin >> N >> T)) return 0; A.assign(N, vector(N)); for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) cin >> A[i][j]; } // S = {0} unordered_set S; S.reserve(1 << 16); S.insert(0); // set_idx size = 2**DIGIT const int LIM = 1 << DIGIT; vector> set_idx(LIM, make_pair(-1, -1)); // for i, j in product(range(N), repeat=2): for (int i = 0; i < N; ++i) { bool break_outer = false; for (int j = 0; j < N; ++j) { unordered_set next_S = S; // copy next_S.reserve(S.size() * 2 + 4); for (int k : S) { int x = k ^ A[i][j]; // Python code indexes set_idx[x] assuming x < 2**DIGIT // We also assume the same constraint holds. if (next_S.find(x) == next_S.end()) { next_S.insert(x); if (0 <= x && x < LIM) { set_idx[x] = {i, j}; } } } S.swap(next_S); if ((int)S.size() >= LIM) { break_outer = true; break; } } if (break_outer) break; } // get_start(S) long long max_xor = -1; int start = 0; // will be set to the best v for (int v : S) { long long val = score_sum_for_v(v); if (val > max_xor) { max_xor = val; start = v; } } // reconstruct get_idxes vector> get_idxes; while (start > 0) { if (!(0 <= start && start < LIM)) { // Out-of-range safety (should not happen if assumptions hold) break; } auto p = set_idx[start]; int i = p.first, j = p.second; // If not recorded (defensive) if (i < 0 || j < 0) break; get_idxes.emplace_back(i, j); start ^= A[i][j]; } reverse(get_idxes.begin(), get_idxes.end()); // perform moves and copies for (auto [i, j] : get_idxes) { move_to(i, j); do_copy(); } // final sweep over all cells (product(range(N), repeat=2)) for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { move_to(i, j); // if A[curr_i][curr_j] < curr_s ^ A[curr_i][curr_j]: write() int before = A[curr_i][curr_j]; int after = (curr_s ^ A[curr_i][curr_j]); if (before < after) { do_write(); } } } // print for (char c : answer) { cout << c << '\n'; } return 0; }