import java.io.*; import java.util.*; import java.text.*; import java.math.*; import java.util.regex.*; public class Solution { private int N; private Pair[][] board; public Solution(int n) { this.N = n; board = new Pair[N][N]; for(int i=0; i < N; i++) { for(int j=0; j < N; j++) { board[i][j] = new Pair(i, j); } } } private static class Pair { int x, y; public Pair(int a, int b) { this.x = a; this.y = b; } @Override public int hashCode() { return x+y; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Pair other = (Pair) obj; if (x != other.x) return false; if (y != other.y) return false; return true; } } private boolean isValid(int x, int y) { return x >= 0 && x < N && y >= 0 && y < N; } private int getNumStepsToReach(Pair start, Pair end, Pair stepBy) { int numSteps = 0; Set allVisited = new HashSet<>(); Set newVisited = new HashSet<>(); allVisited.add(start); newVisited.add(start); while(!allVisited.contains(end) && !newVisited.isEmpty()) { newVisited = getAllNewVisited(allVisited, newVisited, stepBy); allVisited.addAll(newVisited); numSteps++; } if(allVisited.contains(end)) { return numSteps; } else { return -1; } } private Set getAllNewVisited(Set allVisited, Set prevVisited, Pair stepBy) { Set newVisited = new HashSet<>(); for(Pair p : prevVisited) { Set nextMoves = getAllNextPoint(p, stepBy, allVisited); newVisited.addAll(nextMoves); } return newVisited; } private Set getAllNextPoint(Pair start, Pair stepBy, Set allVisited) { Set next = new HashSet<>(); addValidMoves(start, stepBy, next, allVisited); return next; } private void addValidMoves(Pair start, Pair stepBy, Set next, Set allVisited) { addValidMoves(start, stepBy.x+1, stepBy.y+1, next, allVisited); addValidMoves(start, stepBy.y+1, stepBy.x+1, next, allVisited); } private void addValidMoves(Pair start, int x, int y, Set next, Set allVisited) { if(isValid(start.x + x, start.y + y) && !allVisited.contains(this.board[start.x + x][start.y + y])) { next.add(this.board[start.x + x][start.y + y]); } if(isValid(start.x - x, start.y + y) && !allVisited.contains(this.board[start.x - x][start.y + y])) { next.add(this.board[start.x - x][start.y + y]); } if(isValid(start.x + x, start.y - y) && !allVisited.contains(this.board[start.x + x][start.y - y])) { next.add(this.board[start.x + x][start.y - y]); } if(isValid(start.x - x, start.y - y) && !allVisited.contains(this.board[start.x - x][start.y - y])) { next.add(this.board[start.x - x][start.y - y]); } } private void printSteps() { Pair startPoint = new Pair(0, 0); Pair endPoint = new Pair(N-1, N-1); for(int i=0; i < N-1; i++) { for(int j=0; j < N-1; j++) { Pair stepBy = this.board[i][j]; System.out.print(getNumStepsToReach(startPoint, endPoint, stepBy) + " "); } System.out.println(); } } public static void main(String[] args) { Scanner in = new Scanner(System.in); int n = in.nextInt(); // your code goes here Solution board = new Solution(n); board.printSteps(); } }