#include using namespace std; using ll = long long; // ---------- XOR Basis for up to 20 bits ---------- struct XorBasis { static const int B = 20; int v[B]; // basis value bitset<128> used[B]; // cells set that forms this basis vector XorBasis(){ memset(v, 0, sizeof(v)); } void add(int x, const bitset<128>& bs){ bitset<128> c = bs; for(int b=B-1; b>=0; --b){ if(((x>>b)&1)==0) continue; if(v[b]==0){ v[b]=x; used[b]=c; return; } x ^= v[b]; c ^= used[b]; } } pair> build(int target) const { int t = target, made = 0; bitset<128> sel; sel.reset(); for(int b=B-1; b>=0; --b){ if(((t>>b)&1)==0) continue; if(v[b]==0) continue; // cannot set this bit t ^= v[b]; made ^= v[b]; sel ^= used[b]; } return {made, sel}; } }; // score for a given s: sum of max(A[i], A[i]^s) static inline long long eval_score(const vector& flatA, int s){ long long sum = 0; for(int x: flatA){ int y = x ^ s; sum += (y > x ? y : x); } return sum; } // move helper (0-indexed coords) static inline void move_to(int &r, int &c, int tr, int tc, vector& ops){ while(rtr){ ops.push_back('U'); --r; } while(ctc){ ops.push_back('L'); --c; } } int main(){ ios::sync_with_stdio(false); cin.tie(nullptr); int N,T; if(!(cin>>N>>T)) return 0; // N=10, T=1000 vector> A(N, vector(N)); for(int i=0;i>A[i][j]; // flatten A for fast eval vector flatA(N*N); for(int i=0;i>b)&1) cnt1++; else cnt0++; } if(cnt0 > cnt1) s1_target |= (1< bs; bs.reset(); bs.set(i*N + j); basis.add(A[i][j], bs); } auto [s0_real, cells0] = basis.build(s0); auto [s1_real, cells1] = basis.build(s1_target); long long sc0 = eval_score(flatA, s0_real); long long sc1 = eval_score(flatA, s1_real); int S = s0_real; // start from the better of s0_real, s1_real bitset<128> needC = cells0; long long bestScore = sc0; if(sc1 > sc0){ S = s1_real; needC = cells1; bestScore = sc1; } // ---------- Hill climbing: single & pair XOR (non-decreasing only) ---------- // single XOR bool improved = true; while(improved){ improved = false; long long cur = bestScore; int bestIdx = -1; long long addGain = 0; for(int idx=0; idx addGain){ addGain = sc - cur; bestIdx = idx; } } if(addGain > 0){ S ^= flatA[bestIdx]; bestScore += addGain; improved = true; } } // pair XOR (optional, still cheap) bool improved2 = true; while(improved2){ improved2 = false; long long cur = bestScore; long long addGain = 0; int p = -1, q = -1; for(int i=0;i addGain){ addGain = sc - cur; p = i; q = j; } } } if(addGain > 0){ S ^= flatA[p]; S ^= flatA[q]; bestScore += addGain; improved2 = true; } } // Rebuild cells for final S (should be representable) auto [S_real, needC2] = basis.build(S); if(S_real != S){ // fallback: choose better of (S_real, original S) long long sc_real = eval_score(flatA, S_real); if(sc_real >= bestScore){ S = S_real; bestScore = sc_real; needC = needC2; }else{ // keep S, but still need some C set => build from original S through basis needC = needC2; // although mismatch rare, allow anyway } }else{ needC = needC2; } // ---------- Build operation sequence ---------- vector ops; int r=0, c=0; // current pos (0-indexed -> (1,1) in problem statement) // Phase 1: traverse snake once, perform C when needed vector> snake; snake.reserve(N*N); for(int i=0;i=0;j--) snake.emplace_back(i,j); } if(!snake.empty()){ move_to(r,c, snake[0].first, snake[0].second, ops); for(size_t k=0;k0) move_to(r,c, rr, cc, ops); int x = A[rr][cc]; if( (x ^ S) > x ) ops.push_back('W'); } } // Safety if((int)ops.size() > T){ // We shouldn't exceed, but trim if necessary (may break correctness though) ops.resize(T); } for(char ch: ops) cout << ch << '\n'; return 0; }