import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { public static boolean[][] haveChecked; public static class Point { int x; int y; int movesTo; // moves taken to get to point public Point(int x, int y, int movesTo) { this.x = x; this.y = y; this.movesTo = movesTo; } private boolean isInBounds(int size) { if (this.x < 0 || this.y < 0 || this.x >= size || this.y >= size) { return false; } return true; } } public static int minOf8(List list) { int min = Integer.MAX_VALUE; for (int i: list) { if (i < min) { min = i; } } return min; } public static void main(String[] args) { Scanner s = new Scanner(System.in); int n = s.nextInt(); Point start = new Point(0,0,0); for (int i = 1; i < n; i++) { for (int j = 1; j < n; j++) { haveChecked = new boolean[n][n]; int dist = calcDistToEnd(start, i, j, n); if (dist == Integer.MAX_VALUE) { dist = -1; } System.out.printf(Integer.toString(dist)); if (j != n - 1) { System.out.printf(" "); } } System.out.println(); } } public static int calcDistToEnd(Point p, int a, int b, int size) { haveChecked[p.x][p.y] = true; if (!p.isInBounds(size)) { return Integer.MAX_VALUE; } if (p.x == size - 1 && p.y == size - 1) { return p.movesTo; } List minMoves = new LinkedList<>(); Point p1 = new Point(p.x + a, p.y + b, p.movesTo + 1); if (p1.isInBounds(size)) { if (!haveChecked[p1.x][p1.y] || (p1.x == size - 1 && p1.y == size - 1)) { minMoves.add(calcDistToEnd(p1, a, b, size)); } } Point p2 = new Point(p.x + a, p.y - b, p.movesTo + 1); if (p2.isInBounds(size)) { if (!haveChecked[p2.x][p2.y] || (p2.x == size - 1 && p2.y == size - 1)) { minMoves.add(calcDistToEnd(p2, a, b, size)); } } Point p3 = new Point(p.x - a, p.y + b, p.movesTo + 1); if (p3.isInBounds(size)) { if (!haveChecked[p3.x][p3.y] || (p3.x == size - 1 && p2.y == size - 1)) { minMoves.add(calcDistToEnd(p3, a, b, size)); } } Point p4 = new Point(p.x - a, p.y - b, p.movesTo + 1); if (p4.isInBounds(size)) { if (!haveChecked[p4.x][p4.y] || (p4.x == size - 1 && p4.y == size - 1)) { minMoves.add(calcDistToEnd(p4, a, b, size)); } } Point p5 = new Point(p.x + b, p.y + a, p.movesTo + 1); if (p5.isInBounds(size)) { if (!haveChecked[p5.x][p5.y] || (p5.x == size - 1 && p5.y == size - 1)) { minMoves.add(calcDistToEnd(p5, a, b, size)); } } Point p6 = new Point(p.x + b, p.y - a, p.movesTo + 1); if (p6.isInBounds(size)) { if (!haveChecked[p6.x][p6.y] || (p6.x == size - 1 && p6.y == size - 1)) { minMoves.add(calcDistToEnd(p6, a, b, size)); } } Point p7 = new Point(p.x - b, p.y + a, p.movesTo + 1); if (p7.isInBounds(size)) { if (!haveChecked[p7.x][p7.y] || (p7.x == size - 1 && p7.y == size - 1)) { minMoves.add(calcDistToEnd(p7, a, b, size)); } } Point p8 = new Point(p.x - b, p.y - a, p.movesTo + 1); if (p8.isInBounds(size)) { if (!haveChecked[p8.x][p8.y] || (p8.x == size - 1 && p8.y == size - 1)) { minMoves.add(calcDistToEnd(p8, a, b, size)); } } return minOf8(minMoves); } }