#!/bin/python3
import collections
import heapq
import sys

n = int(input().strip())
# your code goes here
GOAL = (n - 1, n - 1)

def heuristic(square, a, b):
    return (GOAL[0] + GOAL[1] - square[0] - square[1])/(a + b)

def is_legal(square):
    return 0 <= square[0] < n and 0 <= square[1] < n

def get_neighbors(square, a, b):
    diffs = ((a, b), (a, -b), (-a, b), (-a, -b), (b, a), (b, -a), (-b, a), (-b, -a))
    neighbors = set([])
    for d in diffs:
        neighbor = (square[0] + d[0], square[1] + d[1])
        if is_legal(neighbor):
            neighbors.add(neighbor)
    return neighbors

def moves_to_goal(a, b):
    closed_squares = set([])
    #frontier_squares = collections.deque([((0, 0), 0)])
    frontier_squares = [(0, [(0, 0), 0])]
    while len(frontier_squares):
        current_square, path_len = heapq.heappop(frontier_squares)[1]
        if current_square in closed_squares:
            continue
        closed_squares.add(current_square)
        neighbors = get_neighbors(current_square, a, b)
        for neighbor in neighbors:
            if neighbor == GOAL:
                return path_len + 1
            if not neighbor in closed_squares:
                #frontier_squares.append((neighbor, path_len + 1))
                heapq.heappush(frontier_squares, (path_len + 1 + heuristic(neighbor, a, b), [neighbor, path_len + 1]))
    return -1

for a in range(1, n):
    row = []
    for b in range(1, n):
        row.append(str(moves_to_goal(a, b)))
    print(' '.join(row))