import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Scanner; import java.util.concurrent.*; public class Solution { private static class KnightSolver { private int n; private class SingleKnightSolution { int i; int j; int minMoves; public SingleKnightSolution(int i, int j, int minMoves) { this.i = i; this.j = j; this.minMoves = minMoves; } } private class SingleKnightSolver implements Callable { int i; int j; int possibleDistances[] = new int[8]; int[][] board = createMatrix(n); public SingleKnightSolver(int i, int j) { this.i = i; this.j = j; } @Override public SingleKnightSolution call() throws Exception { for (int k = 0; k < n; k++) { Arrays.fill(board[k], Integer.MAX_VALUE); } calcMinMoves(0, 0, 0); int minMoves = board[n-1][n-1]; return new SingleKnightSolution(i, j, minMoves == Integer.MAX_VALUE ? -1 : minMoves); } private void calcMinMoves(int currentI, int currentJ, int distance) { if (currentI < 0 || currentJ < 0) { return; } if (currentI >= n || currentJ >= n) { return; } if (board[currentI][currentJ] <= distance) { return; } board[currentI][currentJ] = distance; if (currentI == n - 1 && currentJ == n - 1) { return; } calcMinMoves(currentI - i, currentJ - j, distance + 1); calcMinMoves(currentI - i, currentJ + j, distance + 1); calcMinMoves(currentI + i, currentJ - j, distance + 1); calcMinMoves(currentI + i, currentJ + j, distance + 1); calcMinMoves(currentI - j, currentJ - i, distance + 1); calcMinMoves(currentI - j, currentJ + i, distance + 1); calcMinMoves(currentI + j, currentJ - i, distance + 1); calcMinMoves(currentI + j, currentJ + i, distance + 1); } } public KnightSolver(int n) { this.n = n; } public int[][] solve() throws InterruptedException, ExecutionException { int[][] solutionMatrix = createMatrix(n - 1); ArrayList solvers = new ArrayList<>(n * n); for (int i = 1; i < n; i++) { for (int j = i; j < n; j++) { solvers.add(new SingleKnightSolver(i, j)); } } List> futureResults = Executors.newWorkStealingPool().invokeAll(solvers); for (Future fr : futureResults) { SingleKnightSolution sol = fr.get(); solutionMatrix[sol.i - 1][sol.j - 1] = sol.minMoves; solutionMatrix[sol.j - 1][sol.i - 1] = sol.minMoves; } return solutionMatrix; } private static int[][] createMatrix(int n) { int[][] solutionMatrix = new int[n][]; for (int i = 0; i < n; i++) { solutionMatrix[i] = new int[n]; } return solutionMatrix; } } public static void main(String[] args) throws ExecutionException, InterruptedException { Scanner in = new Scanner(System.in); int n = in.nextInt(); KnightSolver solver = new KnightSolver(n); int[][] solution = solver.solve(); for (int i = 0; i < solution.length; i++) { for (int j = 0; j < solution.length; j++) { System.out.print(solution[i][j]); System.out.print(" "); } System.out.println(); } } }