Source: IMOSLC-2023-P1
Category: Operations and Strategies

Problem: "Let $m$ and $n$ be integers greater than $1$. On an $m\\times n$ grid, each cell contains a coin placed face down. In each operation, one may choose a $2\\times2$ square, flip the coins at the top-left and bottom-right corners, and flip one of the coins at the bottom-left or top-right corner. Determine all pairs $(m,n)$ for which it is possible to turn all coins face up after finitely many operations.
"

Answer: All $(m,n)$ such that $3\mid mn$

Reference solution:
The possible pairs are all $(m,n)$ such that $3\mid mn$.

When $3\mid mn$, the $m\times n$ grid can be partitioned into several $1\times3$ or $3\times1$ small rectangles. By applying a sequence of valid operations to flip the coins in a single small rectangle, all coins on the board can be turned over in a finite number of steps.

In the cell $(i,j)$, write the remainder of $i+j$ modulo $3$. For $k=0,1,2$, let $A_k$ denote the number of coins showing heads in the cells containing $k$. Initially, $A_0=A_1=A_2=0$. Because each operation simultaneously flips exactly one coin from each of the three types of cells, $A_0$, $A_1$, and $A_2$ change parity together, so the parities of $A_0$, $A_1$, and $A_2$ are always the same. If finally all coins are heads up, then the total numbers of the three types of cells in the board must have the same parity. But when $3\nmid mn$, one type of cell has one more or one fewer than the other two types, a contradiction!

If we assign to the cell $(i,j)$ the value $x^i y^j$, then there exist polynomials $P(x,y)$ and $Q(x,y)$ such that 
\begin{aligned}
&P(x,y)(x+y+1)+Q(x,y)(x+y+xy)\\
&\equiv (1+x+\cdots+x^{m-1})(1+x+\cdots+x^{n-1})\pmod{2}.
\end{aligned}

Grading guidelines:
(Partial) 1. Introduced the 3-colouring by i+j (mod 3) and correctly observed that each move flips exactly one coin of each colour. 2. Derived a correct invariant/congruence consequence of the move, e.g. that the parities of the numbers A0,A1,A2 of heads in the three colour classes always stay equal (or an equivalent mod-2 linear invariant). 3. From the invariant, proved a necessary condition excluding some boards (e.g. showed impossibility when 3∤mn by comparing the parities of the sizes of the three colour classes in an m×n grid). (Almost) 1. Proved the necessity (3|mn) via the 3-colouring parity argument, and for sufficiency gave a valid decomposition into 1×3/3×1 blocks but did not fully justify that a single 1×3 (or 3×1) block can always be solved by legal 2×2 moves (missing an explicit sequence or a local argument). 2. Proved sufficiency by an explicit local procedure (e.g. solving a 1×3/3×1 block and tiling the board when 3|mn), but the impossibility part is left with only a sketchy/incorrect parity count for the case 3∤mn (e.g. did not fully justify the distribution of i+j mod 3 in the m×n grid). 3. Established both directions and the final condition 3|mn, but with a small gap such as not handling one boundary case in the tiling (e.g. when only one of m,n is divisible by 3) or an unverified final step in the invariant-to-contradiction argument.

Construction task:
Give, for the 12 \times 10 grid (rows 0..11, cols 0..9), an explicit finite sequence of allowed operations that turns all coins from face-down to face-up. Output exactly one Python expression (Python-literal-friendly) that evals to a list of operations. Each operation must be a length-3 list of distinct [r,c] integer coordinates, 0-based, within the stated ranges, and must correspond to choosing some 2 \times 2 square with top-left corner (r,c) and flipping exactly: [r,c] (top-left), [r+1,c+1] (bottom-right), and exactly one of [r+1,c] (bottom-left) or [r,c+1] (top-right). The returned operation list must achieve that after applying all operations (toggling coin state), every cell is face-up.

Reference construction:
[op for a in range(4) for b in range(5) for op in ([[[3*a, 2*b], [3*a, 2*b+1], [3*a+1, 2*b+1]], [[3*a+1, 2*b], [3*a+2, 2*b], [3*a+2, 2*b+1]]])]

Verifier code:
import sys, ast

def fail(msg):
    print(msg)
    raise SystemExit(0)

data = sys.stdin.read()
try:
    tree = ast.parse(data, mode="eval")
    obj = eval(compile(tree, "<construction>", "eval"), {"__builtins__": {}, "range": range}, {})
except Exception as e:
    fail(f"Parse/eval error: {e}")

if not isinstance(obj, list):
    fail("Top-level must be a list of operations.")

ROWS, COLS = 12, 10
grid = [[0 for _ in range(COLS)] for _ in range(ROWS)]

def coord_to_tuple(x, op_idx, coord_idx):
    if not isinstance(x, (list, tuple)) or len(x) != 2:
        fail(f"Operation {op_idx}: coordinate {coord_idx} must be a list/tuple of length 2.")
    r, c = x[0], x[1]
    if not isinstance(r, int) or not isinstance(c, int):
        fail(f"Operation {op_idx}: coordinate {coord_idx} entries must be integers.")
    if not (0 <= r <= ROWS - 1 and 0 <= c <= COLS - 1):
        fail(f"Operation {op_idx}: coordinate {coord_idx} out of bounds: [{r},{c}].")
    return (r, c)

for i, op in enumerate(obj):
    if not isinstance(op, list) or len(op) != 3:
        fail(f"Operation {i}: must be a list of length 3.")

    coords = [coord_to_tuple(op[j], i, j) for j in range(3)]

    if len(set(coords)) != 3:
        fail(f"Operation {i}: coordinates must be pairwise distinct.")

    pts = set(coords)

    legal = False
    legal_rtct = None
    for (rt, ct) in pts:
        if 0 <= rt <= ROWS - 2 and 0 <= ct <= COLS - 2:
            pattern1 = {(rt, ct), (rt + 1, ct + 1), (rt, ct + 1)}
            pattern2 = {(rt, ct), (rt + 1, ct + 1), (rt + 1, ct)}
            if pts == pattern1 or pts == pattern2:
                legal = True
                legal_rtct = (rt, ct)
                break
    if not legal:
        fail(f"Operation {i}: illegal operation; does not match required 2x2 pattern with a valid top-left.")

    # Apply toggles
    for (r, c) in coords:
        grid[r][c] ^= 1

bad = [(r, c) for r in range(ROWS) for c in range(COLS) if grid[r][c] == 0]
if bad:
    preview = ", ".join([f"[{r},{c}]" for (r, c) in bad[:20]])
    more = "" if len(bad) <= 20 else f" ... and {len(bad)-20} more"
    fail(f"Not all coins are face-up; face-down cells include: {preview}{more}")

print("True")