object Solution {
    
        class queue(n: Int){
            var arr = Array.fill[(Int,Int)](n)((-1,-1))
            var head = -1
            var tail = 0    
            var count = 0
            
            def isFull(): Boolean = {
                if(arr(tail) != (-1,-1) || count == n){
                    true
                } else {
                    false    
                }
            }
        
        def isEmpty(): Boolean = {
            if(head == -1 || head == tail || count == 0) true else false
        }    
            
        def enqueue(elem: (Int,Int)): Boolean = {
            if(isFull) false 
            else {
                arr(tail) = elem
                if(head == -1) head = 0    
                tail = (tail+1)%n
                /*println("Enqueued " + elem + " head is: " + head + " tail is: " + tail)    
                arr.foreach(i => print(i +" "))
                println()    */
                count = count + 1    
                true    
            }    
        }   
        
        def dequeue(): Option[(Int,Int)] = {

            if(isEmpty()) None
            else {
               var toRet = arr(head)                        
               arr(head) = (-1,-1)
               head = (head+1)%n
               if(arr(head) == (-1,-1)){
                 head = -1  
               } 
               /*println("Dequeuing " + toRet + " head is: " + head + " tail is: " + tail)
               arr.foreach(i => print(i +" "))
               println()*/
               count = count - 1
               if(count == 0){
                   head = -1
                   tail = 0    
               }    
               Some(toRet)    
            }    
        }
    }
    
    def getValidMoves(i: Int, j: Int, n : Int, pos: (Int,Int)): List[(Int,Int)]= {
        //1,1,5,(1,1)
        //22,20,00
        var movesRef = List((pos._1+i,pos._2+j),(pos._1+i,pos._2-j),(pos._1-i,pos._2+j),(pos._1-i,pos._2-j),
                            (pos._1+j,pos._2+i),(pos._1+j,pos._2-i),(pos._1-j,pos._2+i),(pos._1-j,pos._2-i))    
        movesRef.filter(i => (i._1 >= 0 && i._1 < n && i._2 >= 0 && i._2 < n))    
    }
    
    def getCount(i: Int, j: Int, n: Int): Int={
        //var q = new queue(8)
        //q.enqueue((0,0))
        var q = new scala.collection.mutable.Queue[(Int,Int)]
        q.enqueue((0,0))    
        var visited = Array.ofDim[Boolean](n,n)
        var distance = Array.ofDim[Int](n,n)    
        distance(0)(0) = 0
        var destReached = false
        var res = 0    
        while(q.isEmpty == false && destReached == false){
            var curr = q.dequeue   
                //println("Dq: " + curr._1 +","+curr._2)
            var validMoves = getValidMoves(i,j,n,curr)
                //validMoves.foreach(i => println(i._1+","+i._2))     
            validMoves.foreach(i => {
                if(visited(i._1)(i._2) == false){
                    distance(i._1)(i._2) = distance(curr._1)(curr._2) + 1
                    visited(i._1)(i._2) = true
                    //println("Eq: " + i._1 +","+i._2)    
                    if(i._1 == n-1 && i._2 == n-1){
                        destReached = true
                        res = distance(i._1)(i._2)    
                    } else {
                        q.enqueue(i)    
                    }    
                }
            })
        }
        if(destReached == false) 0 else res
    
    }

    def main(args: Array[String]) {
        val sc = new java.util.Scanner (System.in);
        var n = sc.nextInt();
        //var mat = Array.fill[Int](n-1)(0)
        for(i <- 1 to n-1){
            for(j <- 1 to n-1){
                var count = getCount(i,j,n)
                if(count == 0){
                    print(-1+ " ")
                } else {
                    print(count + " ")
                }    
            }
            println()
        }
    }
}