import java.util.*; import java.io.*; public class Solution { public static void main(String[] args) { Kattio io = new Kattio(System.in, System.out); int n = io.getInt(); int size = n*n; int[] dist = new int[size]; boolean[] visited = new boolean[size]; int[][] edges = new int[size][size]; int[][] answer = new int[n][n]; for (int a = 1; a<n; a++) { for (int b=a; b<n; b++) { answer[a][b] = solve(io, n, size, dist, visited, edges, a, b); answer[b][a] = answer[a][b]; } } for (int a = 1; a<n; a++) { for (int b=1; b<n; b++) { io.print(answer[a][b]); io.print(' '); } io.println(); } io.close(); } private static int solve(Kattio io, int n, int size, int[] dist, boolean[] visited, int[][] edges, int a, int b) { Arrays.fill(dist, -1); Arrays.fill(visited, false); for (int i = 0; i < size; i++) { Arrays.fill(edges[i], -1); } for (int i1 = 0; i1 < n; i1++) { for (int j1 = 0; j1 < n; j1 ++) { int i2,j2; i2 = i1+a; j2 = j1+b; addEdge(n, edges, i1, j1, i2, j2); i2 = i1+a; j2 = j1-b; addEdge(n, edges, i1, j1, i2, j2); i2 = i1-a; j2 = j1+b; addEdge(n, edges, i1, j1, i2, j2); i2 = i1-a; j2 = j1-b; addEdge(n, edges, i1, j1, i2, j2); i2 = i1+b; j2 = j1+a; addEdge(n, edges, i1, j1, i2, j2); i2 = i1+b; j2 = j1-a; addEdge(n, edges, i1, j1, i2, j2); i2 = i1-b; j2 = j1+a; addEdge(n, edges, i1, j1, i2, j2); i2 = i1-b; j2 = j1-a; addEdge(n, edges, i1, j1, i2, j2); } } // // for (int i = 0; i < edges.length; i++) { // io.println(Arrays.toString(edges[i])); // } // io.println(); // // int row = 1; // for (int i1 = 0; i1 < n; i1++) { // for (int j1 = 0; j1 < n; j1 ++) { // io.print(edges[row][i1*n+j1] > 0 ? 'x' : '.'); // } // io.println(); // } // io.println(); dist[0] = 0; PriorityQueue<Integer> pq = new PriorityQueue<>( Comparator.comparing(i -> dist[i] < 0 ? Long.MAX_VALUE : dist[i])); pq.add(0); while (!pq.isEmpty()) { int cur = pq.poll(); if (visited[cur]) continue; visited[cur] = true; for (int v2 = 0; v2 < size; v2++) { if (edges[cur][v2] < 0) continue; int d = dist[cur] + edges[cur][v2]; int d2 = dist[v2]; if (d2 < 0 || d < d2) { dist[v2] = d; } pq.add(v2); } } int distab = dist[size-1]; return distab; } private static void addEdge(int n, int[][] edges, int i1, int j1, int i2, int j2) { if (0 <= i2 && i2 < n && 0 <= j2 && j2 < n) { edges[i1*n+j1][i2*n+j2] = 1; } } static class Kattio extends PrintWriter { public Kattio(InputStream i) { super(new BufferedOutputStream(System.out)); r = new BufferedReader(new InputStreamReader(i)); } public Kattio(InputStream i, OutputStream o) { super(new BufferedOutputStream(o)); r = new BufferedReader(new InputStreamReader(i)); } public boolean hasMoreTokens() { return peekToken() != null; } public int getInt() { return Integer.parseInt(nextToken()); } public double getDouble() { return Double.parseDouble(nextToken()); } public long getLong() { return Long.parseLong(nextToken()); } public String getWord() { return nextToken(); } private BufferedReader r; private String line; private StringTokenizer st; private String token; private String peekToken() { if (token == null) try { while (st == null || !st.hasMoreTokens()) { line = r.readLine(); if (line == null) return null; st = new StringTokenizer(line); } token = st.nextToken(); } catch (IOException e) { } return token; } private String nextToken() { String ans = peekToken(); token = null; return ans; } } }