#include <map>
#include <set>
#include <list>
#include <cmath>
#include <ctime>
#include <deque>
#include <queue>
#include <stack>
#include <string>
#include <bitset>
#include <cstdio>
#include <limits>
#include <vector>
#include <climits>
#define mp make_pair
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <numeric>
#include <sstream>
#include <iostream>
#include <algorithm>
#define maximum 1000000000
#include <unordered_map>
int n;
using namespace std;
queue<pair<int,pair<int,int>>>q;
bool inrange(int x,int y){
    //cout<<x<<" "<<y<<"heyy"<<endl;
    if(x<n and x>=0 and y>=0 and y<n){
        return true;
    }
    return false;
}
bool visited[26][26]={0};
int rec(int a,int b){
    while(!q.empty())q.pop();
    q.push(mp(0,mp(0,0)));
    while(!q.empty()){
    pair<int,pair<int,int>> tempi=q.front();
    q.pop();
    int x=tempi.second.first;
    int y=tempi.second.second;
    //cout<<x<<" "<<y<<endl;
    int temp=tempi.first;
    if(x==n-1 and y==n-1){return tempi.first;}
    if(inrange(x+a,y+b)){
        if(visited[x+a][y+b]!=1)
        {q.push(mp(temp+1,mp((x+a),y+b)));
         visited[x+a][y+b]=1;}
    }
        if(inrange(x+a,y-b)){
           // cout<<"hi"<<endl;
        if(visited[x+a][y-b]!=1)
        {q.push(mp(temp+1,mp((x+a),y-b)));
         visited[x+a][y-b]=1;
        }
    }
        if(inrange(x-a,y+b)){
        if(visited[x-a][y+b]!=1)
        { q.push(mp(temp+1,mp((x-a),y+b)));
           visited[x-a][y+b]=1;
        }
    }
        if(inrange(x-a,y-b)){
        if(visited[x-a][y-b]!=1)
        {q.push(mp(temp+1,mp((x-a),y-b)));
        visited[x-a][y-b]=1;}
    }
        if(inrange(x+b,y+a)){
        if(visited[x+b][y+a]!=1)
        {q.push(mp(temp+1,mp((x+b),y+a)));
        visited[x+b][y+a]=1;}
    }
        if(inrange(x+b,y-a)){
        if(visited[x+b][y-a]!=1)
        {q.push(mp(temp+1,mp((x+b),y-a)));
        visited[x+b][y-a]=1;}
    }
        if(inrange(x-b,y+a)){
        if(visited[x-b][y+a]!=1)
        {q.push(mp(temp+1,mp((x-b),y+a)));
        visited[x-b][y+a]=1;}
    }
        if(inrange(x-b,y-a)){
        if(visited[x-b][y-a]!=1)
        {q.push(mp(temp+1,mp((x-b),y-a)));
        visited[x-b][y-a]=1;}
    }
}
   return maximum;
}
int main(){
    int i,j;
    int ans[26][26];//answer
    cin >> n;
    memset(visited,0,sizeof(visited));
    //cout<<rec(1,4)<<endl;
    for(i=1;i<n;i++){
        for(j=i;j<n;j++){
            memset(visited,0,sizeof(visited));
            //cout<<i<<" "<<j<<endl;
            ans[i][j]=rec(i,j);
            if(ans[i][j]>=maximum){ans[i][j]=-1;}
            //cout<<ans[i][j]<<endl;
            ans[j][i]=ans[i][j];
        }
    }
    for(i=1;i<n;i++){
        for(j=1;j<n;j++){
                cout<<ans[i][j]<<" ";
        }
        cout<<endl;
    }
    // your code goes here
    return 0;
}