import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;

public class Solution {

    private class Position {
        int x;
        int y;
        Position(int x, int y) {
            this.x = x;
            this.y = y;
        }
        @Override
        public String toString(){
        	return x + " " + y;
        }
        
        @Override
        public boolean equals(Object p) {
        	Position temp = (Position)p;
        	if(temp.x == this.x && temp.y == this.y) {
        		return true;
        	} else {
        		return false;
        	}
        }
    }
    
    public static void knightProblem(int n) {
    	int [][]minMoves = new int[n-1][n-1];
        for(int a = 1; a < n; a++) {
            for(int b = 1; b < n; b++) {
                
                if( b >= a) {
		            Position currentPosition = new Solution().new Position(0,0);
		            Set<Position> positionSet = new HashSet<Position>();
		            positionSet.add(currentPosition);
		            
		            int numberOfMoves = getNumberOfMoves(a,b,n,0,currentPosition,positionSet);
		            minMoves[a-1][b-1] = numberOfMoves;
                } else {
                	minMoves[a-1][b-1] = minMoves[b-1][a-1];
                }
            }
        }
        
        for(int i = 0; i < minMoves.length;i++) {
        	for(int j = 0; j < minMoves.length; j++) {
        		System.out.print(minMoves[i][j] + " ");
        	}
        	System.out.println();
        }
    }
    
    private static int getNumberOfMoves(int a, int b, int n, int numberOfMoves, Position currentPosition, Set<Position>positionSet) {
        
    	if(currentPosition.x == n-1 && currentPosition.y == n-1) {
    		return numberOfMoves;
    	}
    	
        currentPosition = nextPosition(a, b, n, currentPosition, positionSet);
        
        if(currentPosition == null) {
        	return -1;
        }
        numberOfMoves++;
        positionSet.add(currentPosition);
        return getNumberOfMoves(a, b, n, numberOfMoves, currentPosition, positionSet);
    }

	private static Position nextPosition(int a, int b, int n, Position currentPosition, Set<Position> positionSet) {
		Position nextPosition = null;
		switch(1) {
            case 1:
                if(currentPosition.x + a < n && currentPosition.y + b < n) {
                    nextPosition = new Solution().new Position(currentPosition.x + a, currentPosition.y + b);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 2:
            	if(currentPosition.x + b < n && currentPosition.y + a < n) {
                    nextPosition = new Solution().new Position(currentPosition.x + b, currentPosition.y + a);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 3:
            	if(currentPosition.x + a < n && currentPosition.y - b >= 0) {
                    nextPosition = new Solution().new Position(currentPosition.x + a, currentPosition.y - b);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 4:
            	if(currentPosition.x + b < n && currentPosition.y - a >= 0) {
                    nextPosition = new Solution().new Position(currentPosition.x + b, currentPosition.y - a);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 5:
            	if(currentPosition.x - a >= 0 && currentPosition.y + b < n) {
                    nextPosition = new Solution().new Position(currentPosition.x - a, currentPosition.y + b);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 6:
            	if(currentPosition.x - b >= 0 && currentPosition.y + a < n) {
                    nextPosition = new Solution().new Position(currentPosition.x - b, currentPosition.y + a);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 7:
            	if(currentPosition.x - a >= 0 && currentPosition.y - b >= 0) {
                    nextPosition = new Solution().new Position(currentPosition.x - a, currentPosition.y - b);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
            case 8:
                if(currentPosition.x - b >= 0 && currentPosition.y - a >= 0) {
                    nextPosition = new Solution().new Position(currentPosition.x - b, currentPosition.y - a);
                    if( !setContains(nextPosition, positionSet) ) {
                        break;
                    } else {
                    	nextPosition = null;
                    }
                }
        }
		
		return nextPosition;
	}
	
	public static boolean setContains(Position pos, Set<Position>set) {
		for(Position p:set) {
			if(p.x == pos.x && p.y == pos.y) {
				return true;
			}
		}
		
		return false;
	}
    
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        // your code goes here
        knightProblem(n);
    }
}