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 i = 1; i < n; i++) {
            for (int j = 1; j < n; j++) {
                System.out.print(getMinForKnight(n, i, j) + " ");
            }
            System.out.println();
        }
    }
    
    public static int getMinForKnight(int n, int h, int v) {
            
        int [][]graph = new int[n][n];
        
        ArrayList<int[]> retPoints = new ArrayList<int[]>();
        int []start = new int[2];
        start[0] = 0;
        start[1] = 0;
        retPoints.add(start);
        int w = -1;
        
        outerLoop : while (retPoints.size() > 0) {
            
            w++;
            ArrayList<int[]> newRetPoints = new ArrayList<int[]>();
            for (int []retItem : retPoints) {
                
                if (graph[n - 1][n - 1] > 0) {
                    break outerLoop;
                }
             
                int i = retItem[0];
                int j = retItem[1];
                int width = w;       
                
                int maxPoint = n - 1;
        
                int [][]pointsOptions = {
                    {i + h, j + v},
                    {i + h, j - v},                     
                    {i - h, j + v},
                    {i - h, j - v},
                    {i + v, j + h},
                    {i + v, j - h},                     
                    {i - v, j + h},
                    {i - v, j - h},
                };

                for (int q = 0; q < 8; q++) {
                    int []currentPoint = pointsOptions[q];

                    if (currentPoint[0] <= maxPoint && currentPoint[0] >= 0) {
                        if (currentPoint[1] <= maxPoint && currentPoint[1] >= 0) {
                            if (graph[currentPoint[0]][currentPoint[1]] == 0 ||
                                graph[currentPoint[0]][currentPoint[1]] > width) {
                                
                                boolean isAlreadyAdded = false;
                                for (int []item : newRetPoints) {
                                    if (item[0] == currentPoint[0] &&
                                        item[1] == currentPoint[1]) {
                                        isAlreadyAdded = true;
                                    }
                                }
                                
                                if (!isAlreadyAdded) {
                                    newRetPoints.add(currentPoint);
                                    
                                    graph[currentPoint[0]][currentPoint[1]] = width + 1;
                                }
                            }
                        }
                    }
                }
            }
            
            retPoints = newRetPoints;
        }
        
        if (graph[n - 1][n - 1] > 0)  {
            return graph[n - 1][n - 1];
        }  else {
            return -1;
        }
        
        
    }
    
}