Link to this code:
https://cses.fi/paste/b02c9e1f0d07d679d6fde7/# APPROACH 1: only passes till 5
"""
n = int(input())
grid = [[0] * n for _ in range(n)]
for row in range(1, n):
start = row
update_val = -1 if start & 1 else 1
for col in range(row):
square_val = start
grid[row][col] = square_val
grid[col][row] = square_val
start += update_val
for row in grid:
print(*row)
"""
# APPROACH 2: seen sets for each row & col
"""
n = int(input())
grid = [[0] * n for _ in range(n)]
row_seen_sets = [set() for _ in range(n)]
col_seen_sets = [set() for _ in range(n)]
for row in range(n):
for col in range(n):
seen_row_vals = row_seen_sets[row]
seen_col_vals = col_seen_sets[col]
mex_val = 0
while mex_val in seen_row_vals or mex_val in seen_col_vals:
mex_val += 1
grid[row][col] = mex_val
seen_row_vals.add(mex_val)
seen_col_vals.add(mex_val)
for row in grid:
print(*row)
"""
# APPROACH 3: Bit Manipulation (XOR) + grundy numbers
n = int(input())
grid = [[row ^ col for row in range(n)] for col in range(n)]
for row in grid:
print(*row)