#!/bin/python3 import sys n = int(input().strip()) from operator import itemgetter goal = n - 1, n - 1 start = (0, 0) distance = {(i, j): 2 * n - i - j - 2 for i in range(n) for j in range(n)} def get_frontier(s, depth, L, n): if moves.get(s): targets = set(moves.get(s)) else: targets = [] targets.append((s[0] + L[0], s[1] + L[1])) targets.append((s[0] + L[0], s[1] - L[1])) targets.append((s[0] - L[0], s[1] + L[1])) targets.append((s[0] - L[0], s[1] - L[1])) targets.append((s[0] + L[1], s[1] + L[0])) targets.append((s[0] + L[1], s[1] - L[0])) targets.append((s[0] - L[1], s[1] + L[0])) targets.append((s[0] - L[1], s[1] - L[0])) targets = [t for t in targets if all(0 <= x <= n - 1 for x in t)] moves[s] = targets return set([n for n in targets if visited.get(n, float('inf')) > depth + 1]) def search(current, depth, L): global visited, arrivals, moves frontier = get_frontier(current, depth, L, n) if not frontier or min(arrivals or [float('inf')]) < depth: return depth += 1 distances = {n: distance[n] for n in frontier} for node, d in sorted(distances.items(), key=itemgetter(1)): if d == 0: arrivals.update({depth}) return [depth] else: visited.update({node: depth, (node)[::-1]: depth}) search(node, depth, L) return arrivals results = {} for i in range(1, n): results[i] = [] for j in range(1, n): visited = dict() moves = {} depth = 0 arrivals = set() L = i, j res = search(start, depth, L) results[i].append(-1 if not res else min(res)) for i in range(1, n): print(' '.join(map(str, results[i])))