#!/bin/python3 def path_len(l_knight): board = [] for n in range(N): board.append([-1] * N) n, m = l_knight x, y = [0,0] def possible_moves(x,y, n, m): # possible moves moves = [] edge = len(board) xn_safe = x + n < edge xm_safe = x + m < edge ym_safe = y + m < edge yn_safe = y + n < edge ym0_safe = y - m >= 0 yn0_safe = y - n >= 0 xn0_safe = x - n >= 0 xm0_safe = x - m >= 0 if xn_safe and ym_safe: moves.append([x + n, y + m]) if xn_safe and ym0_safe: moves.append([x + n, y - m]) if xn0_safe and ym_safe: moves.append([x - n, y + m]) if xn0_safe and ym0_safe: moves.append([x - n, y - m]) if xm_safe and yn_safe: moves.append([x + m, y + n]) if xm_safe and yn0_safe: moves.append([x + m, y - n]) if xm0_safe and yn_safe: moves.append([x - m, y + n]) if xm0_safe and yn0_safe: moves.append([x - m, y - n]) return moves queue = [] queue.append((x, y, 0)) while len(queue) > 0: x, y, moves = queue.pop(0) if board[x][y] != -1 and moves >= board[x][y]: continue board[x][y] = moves next_moves = possible_moves(x, y, n, m) for next in next_moves: queue.append((next[0], next[1], moves+1)) return board[-1][-1] N = int(input()) results = [0] * (N-1) diagonal_length = N - 1 for n in range(N - 1): results[n] = [0] * N for m in range(n + 1): l_knight = ((n+1,m+1)) if m == n and diagonal_length % (n + 1) == 0: path = int(diagonal_length / (m+1)) else: path = path_len(l_knight) results[n][m] = path results[m][n] = path for n in range(len(results)): for m in range(len(results)): print(results[n][m], end = ' ') print()