#include <bits/stdc++.h>
using namespace std;
const int C=1;
map<__int128,int> mp;
__int128 lcm(__int128 x,__int128 y){
	if (!(x&&y)) return x^y;
	return (__int128)x*y/__gcd(x,y);
}
const int N=600;
const long long INF=1e18;
long long z[N][N];
int n,a[N*N];
int main(){
	scanf("%d",&n);
	int tot=((n*n)+1)/2;
	for (int i=1; i<=tot; ++i) a[i]=i*2;
	//random_shuffle(a+1,a+tot+1);
	int d=0;
	for (int i=2; i<=n; i+=2)
		for (int j=((i&1)?1:2); j<=n; j+=2)
			z[i][j]=a[++d];
	for (int i=(n%2==0?n-1:n); i>=1; i-=2){
		stack<int> s;
		for (int j=((i&1)?1:2); j<=n; j+=2)
			s.push(a[++d]);
		for (int j=((i&1)?1:2); j<=n; j+=2)
			z[i][j]=s.top(),s.pop();
	}
	/*for (int i=1; i<=n; ++i,putchar('\n'))
			for (int j=1; j<=n; ++j) printf("%d ",z[i][j]);
   	cerr<<"tot"<<tot<<endl;
	getchar(); getchar();*/
	for (int i=1; i<=n; i++)
		for (int j=((i&1)?2:1); j<=n; j+=2){
			__int128 k=lcm(z[i-1][j],lcm(z[i][j-1],lcm(z[i+1][j],z[i][j+1])));
			__int128 zz=k;
			while (mp.find(zz+C)!=mp.end()) zz+=k;
			if (zz+C>INF){
				swap(z[i+1][j],z[i+3][j]);
				k=lcm(z[i-1][j],lcm(z[i][j-1],lcm(z[i+1][j],z[i][j+1])));
				zz=k;
				while (mp.find(zz+C)!=mp.end()) zz+=k;
			}
			if (zz+C>INF){
				swap(z[i+1][j],z[i+3][j]);
				swap(z[i][j+1],z[i][j+3]);
				k=lcm(z[i-1][j],lcm(z[i][j-1],lcm(z[i+1][j],z[i][j+1])));
				zz=k;
				while (mp.find(zz+C)!=mp.end()) zz+=k;
			}
			if (zz+C>INF){
				swap(z[i+1][j],z[i+3][j]);
				k=lcm(z[i-1][j],lcm(z[i][j-1],lcm(z[i+1][j],z[i][j+1])));
				zz=k;
				while (mp.find(zz+C)!=mp.end()) zz+=k;
			}
            //cerr<<i<<" "<<j<<endl;
			//cerr<<(long long)zz<<" "<<(long long)k<<" "<<z[i-1][j]<<" "<<z[i][j-1]<<" "<<z[i+1][j]<<" "<<z[i][j+1]<<" "<<i<<" "<<j<<endl;
			//assert(zz+C<=INF);
			//getchar();
			z[i][j]=zz+C;
			mp[zz+C]=1;
		}
	for (int i=1; i<=n; ++i,putchar('\n'))
		for (int j=1; j<=n; ++j) printf("%lld ",z[i][j]);
}
