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 ix = 1; ix < n; ix++) { for (int iy = 1; iy < n; iy++) { Cell[][] grid = new Cell[n][n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { grid[i][j] = new Cell(i, j); } } grid[0][0].visited = true; grid[0][0].minMoveN = 0; int moveToEnd = reach(grid, 0, 0, n - 1, n - 1, ix, iy, 1); System.out.print(moveToEnd + " "); } System.out.println(); } } public static int reach(Cell[][] grid, int posX, int posY, int endX, int endY, int movX, int movY, int movN) { int destX; int destY; int moveToEnd; Cell currentCell = grid[posX][posY]; destX = posX + movX; destY = posY - movY; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX - movX; destY = posY - movY; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX + movX; destY = posY + movY; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX - movX; destY = posY + movY; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX + movY; destY = posY + movX; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX - movY; destY = posY + movX; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX - movY; destY = posY - movX; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } destX = posX + movY; destY = posY - movX; moveToEnd = look(grid, destX, destY, endX, endY, movX, movY, movN); if (moveToEnd != -1) { moveToEnd++; if (currentCell.moveToEnd == -1 || moveToEnd < currentCell.moveToEnd) { currentCell.moveToEnd = moveToEnd; } } if (currentCell.moveToEnd == -1) { return -1; } return currentCell.moveToEnd; } public static int look(Cell[][] grid, int posX, int posY, int endX, int endY, int movX, int movY, int movN) { if (posX == endX && posY == endY) { return 0; } if (!validate(grid, posX, posY)) { return -1; } Cell destCell = grid[posX][posY]; if (destCell.visited) { if (destCell.moveToEnd > -1 && movN >= destCell.minMoveN) { return destCell.moveToEnd; } if (movN >= destCell.minMoveN) { return -1; } } destCell.visited = true; destCell.minMoveN = movN; return reach(grid, posX, posY, endX, endY, movX, movY, movN + 1); } public static boolean validate(Cell[][] grid, int destX, int destY) { if (destX >= grid.length) { return false; } if (destY >= grid[0].length) { return false; } if (destX < 0) { return false; } if (destY < 0) { return false; } return true; } public static class Cell { public int x; public int y; public boolean visited = false; public int moveToEnd = -1; public int minMoveN = Integer.MAX_VALUE; public Cell(int x, int y) { this.x = x; this.y = y; } } }