import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); for (int i = 1; i < n; i++) { for (int j = 1; j < n; j++) { System.out.print(getMinForKnight(n, i, j) + " "); } System.out.println(); } } public static int getMinForKnight(int n, int h, int v) { int [][]graph = new int[n][n]; ArrayList retPoints = new ArrayList(); int []start = new int[2]; start[0] = 0; start[1] = 0; retPoints.add(start); int w = -1; outerLoop : while (retPoints.size() > 0) { w++; ArrayList newRetPoints = new ArrayList(); for (int []retItem : retPoints) { if (graph[n - 1][n - 1] > 0) { break outerLoop; } int i = retItem[0]; int j = retItem[1]; int width = w; int maxPoint = n - 1; int [][]pointsOptions = { {i + h, j + v}, {i + h, j - v}, {i - h, j + v}, {i - h, j - v}, {i + v, j + h}, {i + v, j - h}, {i - v, j + h}, {i - v, j - h}, }; for (int q = 0; q < 8; q++) { int []currentPoint = pointsOptions[q]; if (currentPoint[0] <= maxPoint && currentPoint[0] >= 0) { if (currentPoint[1] <= maxPoint && currentPoint[1] >= 0) { if (graph[currentPoint[0]][currentPoint[1]] == 0 || graph[currentPoint[0]][currentPoint[1]] > width) { boolean isAlreadyAdded = false; for (int []item : newRetPoints) { if (item[0] == currentPoint[0] && item[1] == currentPoint[1]) { isAlreadyAdded = true; } } if (!isAlreadyAdded) { newRetPoints.add(currentPoint); graph[currentPoint[0]][currentPoint[1]] = width + 1; } } } } } } retPoints = newRetPoints; } if (graph[n - 1][n - 1] > 0) { return graph[n - 1][n - 1]; } else { return -1; } } }