#!/bin/python3

import sys

n = int(input().strip())

def find_min_num_knight_moves(n, a, b):
    offsets = [(+a, +b), (+a, -b), (-a, +b), (-a, -b), (+b, +a), (-b, +a), (+b, -a), (-b, -a)]
    store = [[0 for _ in range(n)] for _ in range(n)]
    queue = [(0,0)]

    while len(queue)!= 0:
        i,j = queue.pop(0)
        for o in offsets:
            i_ = i + o[0]
            j_ = j + o[1]
            #print("(i,j)=(%d,%d) with offsets %s to (i_,j_)=(%d,%d)" %(i, j, repr(o), i_, j_)),
            if i_ in range(n) and j_ in range(n):
                #print("on board")
                new_value = store[i][j] + 1 # 1 more jump from position (i,j)
                old_value = store[i_][j_]
                if old_value == 0 or (old_value != 0 and new_value < old_value):
                    # print("(i_,j_) = (%d, %d) was %d" % (i_, j_, old_value)),
                    # print("will now be %d, got there from (%d, %d)-> %d" % (new_value, i, j, store[i][j]))
                    store[i_][j_] = new_value
                    
                    # accept loops in case they bring us to places faster
                    queue.append((i_,j_))
                    #print("queue updated, is now: ", queue)
            # else: 
            #     print("not on board")
    result = store[-1][-1]
    if store[-1][-1] == 0: result = -1
    return result

for a in range(1, n):
    msg = ""
    for b in range(1, n):
        result = find_min_num_knight_moves(n, a, b)
        msg = msg + str(result) + " "
    print(msg)