Source: IMO-2004-P3
Category: Existence and Construction

Problem: Define a “hook” to be a figure made up of six unit squares as shown below in the picture, or any of the figures obtained by applying rotations and reflections to this figure.Which $m 	imes n$ rectangles can be tiled by hooks?

Answer: The answer is that one requires:
$$
\bigl({1,2,5}\cap{m,n}=\varnothing\bigr)\ \land\ \bigl(3\mid m\ \lor\ 3\mid n\bigr)\ \land\ \bigl(4\mid m\ \lor\ 4\mid n\bigr).
$$ e.g., (m,n) = (24,19), (10,12), (6,8).

Reference solution:
The answer is that one requires: $m, n \notin \{1,2,5\}$, and ($3 \mid m$ or $3 \mid n$), and ($4 \mid m$ or $4 \mid n$). 

First, we check that all rectangles satisfying these conditions can be tiled by $3 \times 4$ rectangles (and hence by hooks, since a $3 \times 4$ rectangle can be tiled by two hooks). If $3 \mid m$ and $4 \mid n$, this is clear. Else, suppose $12 \mid m$ but $3 \nmid n$ and $4 \nmid n$. Since $n \notin \{1,2,5\}$ and $n$ is not a multiple of $3$ or $4$, we must have $n \ge 7$. Any integer $n \ge 7$ can be written in the form $3x+4y$ for nonnegative integers $x$ and $y$. This permits a tiling of the $m \times n$ rectangle by partitioning it into $m \times 3$ and $m \times 4$ rectangles, each of which can be tiled by $3 \times 4$ rectangles (since $12 \mid m$).

We now prove these conditions are necessary. It is straightforward to see that $m,n \notin \{1,2,5\}$ is necessary, as no combination of hooks can tile rectangles with these dimensions. We thus turn our attention to the divisibility conditions. 

Each hook has a "hole", and if we associate each hook with the one that fills its hole, we get a bijective pairing of hooks. Thus, the total number of cells is divisible by $12$, and the cells come grouped into two possible shapes, which we will call **tiles** (rotations and reflections permitted). 

Suppose for the sake of contradiction there is a tileable rectangle that satisfies $12 \mid mn$ but fails the condition "($3 \mid m$ or $3 \mid n$) and ($4 \mid m$ or $4 \mid n$)". Since $12 \mid mn$, $3$ must divide $m$ or $n$, so the failure must be that $4 \nmid m$ and $4 \nmid n$. Since $4 \mid mn$, this implies $m$ and $n$ are both even but not divisible by $4$, so $m \equiv 2 \pmod 4$ and $n \equiv 2 \pmod 4$. Since $3$ divides $m$ or $n$, we may assume without loss of generality that $3 \mid m$. Then $m$ is a multiple of $6$ and $n$ is a multiple of $2$, so we can write $m = 6a$ and $n = 2b$. Since $m, n \equiv 2 \pmod 4$, both $a$ and $b$ must be odd. Thus, the problem is reduced to proving that if a $6a \times 2b$ rectangle is tiled by these tiles, then at least one of $a$ and $b$ is even (which would contradict that $a$ and $b$ are both odd).

Note that the tiles can be classified into two types:
**First type**: These tiles have exactly four columns, each with exactly three cells (an odd number). Moreover, all rows have an even number of cells (either $2$ or $4$).
**Second type**: Vice-versa. These tiles have exactly four rows, each with exactly three cells (an odd number). Moreover, all columns have an even number of cells (either $2$ or $4$).

We claim that any tiling uses an even number of each type of tile, which is enough to show that the total number of tiles, $ab$, is even, meaning at least one of $a$ and $b$ is even. 

By symmetry, it suffices to prove there is an even number of first-type tiles. Color red every fourth column of the rectangle. The number of cells colored red is even, because the rectangle has an even height of $6a$, meaning each column contains an even number of cells. 
The tiles of the second type have an even number of cells in every column, so they must cover an even number of red cells. 
Since a tile of the first type is connected and has exactly four columns, it spans exactly four consecutive columns, meaning exactly one of its columns is colored red. Because each of its columns contains exactly three cells, a tile of the first type covers exactly $3$ red cells, which is an odd number. 

Since the total number of red cells is even, and the second-type tiles cover an even number of red cells, the number of first-type tiles must be even. By a symmetric argument coloring every fourth row, the number of second-type tiles is also even. Hence, the total number of tiles $ab$ is even, completing the proof.

Grading guidelines:
(Partial) 1. Observed that a 3×4 rectangle can be tiled by two hooks, and reduced the sufficiency part to tiling the m×n rectangle by 3×4 rectangles (e.g. via splitting n as 3x+4y when 12|m, or the symmetric case). 2. Proved a necessary area/divisibility condition such as: in any tiling the hooks can be paired into 12-cell “tiles”, hence 12 | mn (or equivalently 3|mn and 4|mn). 3. Gave a correct obstruction for small side lengths, e.g. proved that no rectangle with m∈{1,2,5} or n∈{1,2,5} can be tiled (with a valid local/invariant argument, not just examples). (Almost) 1. Established the full characterization m,n∉{1,2,5}, (3|m or 3|n), (4|m or 4|n), and proved the construction for all such rectangles by reducing to 3×4 blocks, but left a small gap in the decomposition step (e.g. the claim that every n≥7 can be written as 3x+4y, or a boundary case when swapping roles of m,n). 2. Proved necessity via pairing hooks into 12-cell tiles and the parity-of-types coloring argument (every 4th row/column) to rule out the case m≡n≡2 (mod 4), but did not fully justify one local structural claim about the two tile types (e.g. why each type covers an odd/even number of marked cells, or why a first-type tile meets exactly one marked column). 3. Solution is almost complete, but made minor mistakes which are not negligible.

Construction task:
After solving the problem, output a finite list of construction units.

Definition (construction units). Let the output be a finite set of 2D grids U={U_1,...,U_t} (represented by a Python list [U_1,...,U_t]). For every m×n rectangle R,
R is tileable by hooks if and only if R is tileable by translated/rotated/reflected copies of elements of U.

Hook-level encoding requirement. In each unit grid U_i, every positive integer label must appear exactly 6 times and must form (up to rotation/reflection) a hook; different labels represent different hooks. Each U_i must contain at least two hooks (i.e., at least 12 occupied cells).

Non-redundancy requirement. For all i!=j, U_i must not be tileable by translated/rotated/reflected copies of U_j alone (and vice versa).

Output format requirements:
- Include exactly one construction block and put ONLY a Python 3D list literal (a list of 2D grids) between the tags:
<construct>
<python_literal_3d_grid_list>
</construct>
- The 3D literal must have the form [grid1, grid2, ...], where each gridk is a Python list-of-lists (a 2D matrix) encoding one construction unit.
- Do not use code fences and do not put any extra text inside <construct>...</construct>.

Reference construction:
[
  [
    [1, 1, 1, 2],
    [1, 2, 1, 2],
    [1, 2, 2, 2]
  ],
  [
    [0, 1, 1, 1],
    [0, 1, 2, 1],
    [2, 1, 2, 0],
    [2, 2, 2, 0]
  ]
]

Verifier code:
import ast
import sys


BASE_UNITS = [
    [
        [1, 1, 1, 2],
        [1, 2, 1, 2],
        [1, 2, 2, 2],
    ],
    [
        [0, 1, 1, 1],
        [0, 1, 2, 1],
        [2, 1, 2, 0],
        [2, 2, 2, 0],
    ],
]


def _is_int(value) -> bool:
    return isinstance(value, int) and not isinstance(value, bool)


def _fail() -> None:
    print("False")
    raise SystemExit(0)


def _parse_units(text: str):
    try:
        value = ast.literal_eval(text)
    except Exception:
        _fail()
    if not isinstance(value, list) or len(value) != 2:
        _fail()
    return value


def _validate_grid(grid):
    if not isinstance(grid, list) or not grid:
        _fail()
    if any(not isinstance(row, list) for row in grid):
        _fail()
    width = len(grid[0])
    if width == 0 or any(len(row) != width for row in grid):
        _fail()

    has_positive = False
    for row in grid:
        for value in row:
            if not _is_int(value) or value < 0:
                _fail()
            if value > 0:
                has_positive = True
    if not has_positive:
        _fail()
    return grid


def _trim_zero_border(grid):
    rows = [i for i, row in enumerate(grid) if any(v > 0 for v in row)]
    cols = [j for j in range(len(grid[0])) if any(grid[i][j] > 0 for i in range(len(grid)))]
    if not rows or not cols:
        _fail()
    r1, r2 = rows[0], rows[-1]
    c1, c2 = cols[0], cols[-1]
    return [row[c1 : c2 + 1] for row in grid[r1 : r2 + 1]]


def _rotate_90(grid):
    h = len(grid)
    w = len(grid[0])
    return [[grid[h - 1 - r][c] for r in range(h)] for c in range(w)]


def _reflect(grid):
    return [list(reversed(row)) for row in grid]


def _all_transforms(grid):
    seen = set()
    out = []
    cur = [row[:] for row in grid]
    for _ in range(4):
        for cand in (cur, _reflect(cur)):
            sig = tuple(tuple(v for v in row) for row in cand)
            if sig not in seen:
                seen.add(sig)
                out.append(cand)
        cur = _rotate_90(cur)
    return out


def _canonical_label_signature(grid):
    mapping = {}
    next_label = 1
    out = []
    for row in grid:
        new_row = []
        for value in row:
            if value == 0:
                new_row.append(0)
                continue
            if value not in mapping:
                mapping[value] = next_label
                next_label += 1
            new_row.append(mapping[value])
        out.append(tuple(new_row))
    return tuple(out)


def _unit_signature(grid):
    checked = _validate_grid(grid)
    trimmed = _trim_zero_border(checked)
    return _canonical_label_signature(trimmed)


def _variant_signature_set(base_grid):
    trimmed = _trim_zero_border(base_grid)
    return {
        _canonical_label_signature(_trim_zero_border(variant))
        for variant in _all_transforms(trimmed)
    }


def _can_match_bijection(candidate_to_base):
    used = set()

    def _dfs(i: int) -> bool:
        if i == len(candidate_to_base):
            return True
        for base_idx in candidate_to_base[i]:
            if base_idx in used:
                continue
            used.add(base_idx)
            if _dfs(i + 1):
                return True
            used.remove(base_idx)
        return False

    return _dfs(0)


def main() -> None:
    text = sys.stdin.read()
    if not text:
        _fail()

    units = _parse_units(text)

    base_variants = [_variant_signature_set(unit) for unit in BASE_UNITS]

    candidate_matches = []
    for unit in units:
        sig = _unit_signature(unit)
        matches = [idx for idx, variants in enumerate(base_variants) if sig in variants]
        if not matches:
            _fail()
        candidate_matches.append(matches)

    if not _can_match_bijection(candidate_matches):
        _fail()

    print("True")


if __name__ == "__main__":
    main()