import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { public static class Position { private final int row; private final int col; Position(int row, int col) { this.row = row; this.col = col; } private void safeAdd(List adj, Position pos, int n) { if (isValidPosition(pos.row, n) && isValidPosition(pos.col, n) && !adj.contains(pos)) { adj.add(pos); } } List adjacent(int a, int b, int n) { List adj = new ArrayList<>(); int[][] d = new int[][]{ {a, b}, {-a, b}, {a, -b}, {-a, -b}, {b, a}, {-b, a}, {b, -a}, {-b, -a} }; for (int[] val : d) { safeAdd(adj, new Position(row + val[0], col + val[1]), n); } return adj; } @Override public boolean equals(Object o) { if (o instanceof Position) { Position that = (Position) o; return (this.row == that.row && this.col == that.col) || (that.col == this.row && that.row == this.col); } return false; } @Override public int hashCode() { return 31 * row + col; } private boolean isValidPosition(int newPosition, int n) { return newPosition <= n - 1 && newPosition >= 0; } @Override public String toString() { return "Position[row="+row+", col="+col+"]"; } public boolean atGoal(int n) { return row == n - 1 && col == n - 1; } } private static int getMinMoves(int a, int b, int n) { int moves, level, nextLevel; moves = level = nextLevel = 0; Position start = new Position(0, 0); Queue q = new LinkedList<>(); Set visited = new HashSet<>(); q.add(start); visited.add(start); level++; moves++; boolean levelChanged = false; while (!q.isEmpty()) { Position position = q.poll(); //System.out.println("level: " + level); levelChanged = --level == 0; //System.out.println("Start at " + position + ", moves " + moves); for (Position p : position.adjacent(a, b, n)) { //System.out.println(p); if (p.atGoal(n)) { return moves; } if (!visited.contains(p)) { visited.add(p); q.add(p); nextLevel++; } } if (levelChanged) { moves++; level = nextLevel; nextLevel = 0; } } return -1; } private static void getMinMoves(int n) { int a = 1; int b = 1; for (int i = a; i < n; i++) { for (int j = b; j < n; j++) { System.out.printf("%d ", getMinMoves(i, j, n)); } System.out.println(); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); // your code goes here //System.out.println(getMinMoves(1, 1, n)); getMinMoves(n); } } /** n=7 6 4 4 8 2 12 4 3 4 2 16 3 4 4 2 4 4 4 8 2 4 -1 -1 -1 2 16 4 -1 -1 -1 12 3 4 -1 -1 1 */