using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
class Solution {

    static int Solve(int dx, int dy, int n)
    {
        var queue = new Queue<Tuple<int,int>>();
        queue.Enqueue(new Tuple<int,int>(0, 0));
        
        var path = new int[n, n];
        for(var i = 0; i < n; ++i)
            for(var j = 0; j < n; ++j)
                path[i, j] = Int32.MaxValue;
        path[0, 0] = 0;
        
        while(queue.Count > 0)
        {
            var element = queue.Dequeue();
            foreach(var i in new int[]{dx, -dx})
            {
                foreach(var j in new int[]{dy, -dy})
                {
                    for(var mode = 0; mode <= 1; ++mode)
                    {
                        var nx = (mode == 0 ? element.Item1 : element.Item2) + i;
                        var ny = (mode == 0 ? element.Item2 : element.Item1)+ j;
                        if(nx >= 0 && nx < n && ny >= 0 && ny < n)
                        {
                            if(path[nx, ny] > path[element.Item1, element.Item2] + 1)
                            {
                                queue.Enqueue(new Tuple<int,int>(nx, ny));    
                                path[nx, ny] = path[element.Item1, element.Item2] + 1;
                            }
                        }  
                    }
                }   
            }
        }
        
        return path[n-1, n-1] == Int32.MaxValue ? -1 : path[n-1, n-1];
    }
    
    static void Main(String[] args) {
        var n = Convert.ToInt32(Console.ReadLine());
        var m = new int[n, n];
        for(var i = 0; i < n; ++i)
        {
            for(var j = i; j < n; ++j)
            {
                m[i, j] = Solve(i + 1, j + 1, n);
                m[j, i] = m[i, j];
            }
        }
        for(var i = 0; i < n - 1; ++i){
            var s = "";
            for(var j = 0; j < n - 1; ++j){
                s += m[i, j] + " ";
            }    
            Console.WriteLine(s);
        }
    }
}