#!/bin/python3

import sys
import queue

n = int(input().strip())
(a,b)=(1,1)

def valid_move(i,j):
    return 0<=i<n and 0<=j<n

def find_new_moves(i,j):
    moves = [(i+a,j+b),(i+a,j-b),(i-a,j+b),(i-a,j-b),(i+b,j+a),(i+b,j-a),(i-b,j+a),(i-b,j-a)]
    moves = [move for move in moves if valid_move(move[0],move[1])]
    return moves

#BFS algorithm from CLRS 

def BFS():
    #initialize BFS
    distance = [[-1]*n for i in range(n)]
    color = [['white']*n for i in range(n)]
    parent = [[(-1,-1)]*n for i in range(n)]

    source = (0,0)
    color[0][0] = 'gray'
    distance[0][0] = 0
    parent[0][0] = (-1,-1)

    q = queue.Queue(250)
    q.put(source)
    while not q.empty() and distance[n-1][n-1] is -1:
        u = q.get()
        for v in find_new_moves(u[0],u[1]):
            i=v[0]
            j=v[1]
            if color[i][j] is 'white':
                color[i][j] = 'gray'
                distance[i][j] = distance[u[0]][u[1]]+1
                parent[i][j] = u
                q.put((i,j))
        color[u[0]][u[1]]= 'black'
    return distance[n-1][n-1]

for i in range(1,n):
    paths = []
    for j in range(1,n):
        (a,b)=(i,j)
        answer = BFS()
        paths.append(str(answer))
    print(' '.join(paths))