// Author -- Frame

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<iostream>
#include<set>

#define lowbit(x) ((x)&(-x))
#define Finline __inline__ __attribute__ ((always_inline))
#define DEBUG fprintf(stderr,"Running on Line %d in Function %s\n",__LINE__,__FUNCTION__)

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int inf=0x3f3f3f3f,Inf=0x7fffffff;
const ll INF=0x7fffffffffffffff;
const double eps=1e-10;

template <typename _Tp>_Tp gcd(const _Tp &a,const _Tp &b){return (!b)?a:gcd(b,a%b);}
template <typename _Tp>Finline _Tp abs(const _Tp &a){return a>=0?a:-a;}
template <typename _Tp>Finline _Tp max(const _Tp &a,const _Tp &b){return a<b?b:a;}
template <typename _Tp>Finline _Tp min(const _Tp &a,const _Tp &b){return a<b?a:b;}
template <typename _Tp>Finline void chmax(_Tp &a,const _Tp &b){(a<b)&&(a=b);}
template <typename _Tp>Finline void chmin(_Tp &a,const _Tp &b){(b<a)&&(a=b);}
template <typename _Tp>Finline bool _cmp(const _Tp &a,const _Tp &b){return abs(a-b)<=eps;}
template <typename _Tp>Finline void read(_Tp &x)
{
	register char ch(getchar());
	bool f(false);
	while(ch<48||ch>57) f|=ch==45,ch=getchar();
	x=ch&15,ch=getchar();
	while(ch>=48&&ch<=57) x=(((x<<2)+x)<<1)+(ch&15),ch=getchar();
	if(f) x=-x;
}
template <typename _Tp,typename... Args>Finline void read(_Tp &t,Args &...args)
{
	read(t);read(args...);
}
Finline int read_str(char *s)
{
	register char ch(getchar());
	while(ch==' '||ch=='\r'||ch=='\n') ch=getchar();
	register char *tar=s;
	*tar=ch,ch=getchar();
	while(ch!=' '&&ch!='\r'&&ch!='\n'&&ch!=EOF) *(++tar)=ch,ch=getchar();
	return tar-s+1;
}

const int N=505;
const int MAXN=20005;
Finline ll lcm(ll a,ll b)
{
	if(!a||!b) return a|b;
	return a/gcd(a,b)*b;
}
bool pr[MAXN];
int p[MAXN],pos;
int p1[MAXN],pos1;
int p2[MAXN],pos2;
int a1[N][N],a2[N][N];
ll a[N][N];
std::set<ll> S;
void sieve()
{
	for(int i=2;i<MAXN;++i)
	{
		if(!pr[i])
		{
			p[++pos]=i;
			if(pos&1) p1[++pos1]=i;
			else p2[++pos2]=i;
		}
		for(int j=1;j<=pos&&i*p[j]<MAXN;++j)
		{
			pr[i*p[j]]=true;
			if(!(i%p[j]))
			{
				break;
			}
		}
	}
}
int main()
{
	sieve();
	int n;
	read(n);
	int cur1=0,cur2=0;
	for(int i=n;i>=1;--i)
	{
		if(!(i&1))
		{
			a1[1][i]=++cur1;
			a2[1][i]=++cur2;
		}
	}
	for(int i=1;i<=n;++i)
	{
		if(!(i&1))
		{
			a1[i][1]=++cur1;
		}
		if((i+n)&1)
		{
			a2[i][n]=++cur2;
		}
	}
	for(int i=1;i<=cur1;++i)
	{
		if(i<cur1-i+1&&(i&1))
		{
			std::swap(p1[i],p1[cur1-i+1]);
		}
	}
	for(int i=1;i<=cur2;++i)
	{
		if(i<cur2-i+1&&(i&1))
		{
			std::swap(p2[i],p2[cur2-i+1]);
		}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if(i==1||j==1) continue;
			if((i+j)&1)
			{
				a1[i][j]=a1[i-1][j-1];
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if(i==1||j==n) continue;
			if((i+j)&1)
			{
				a2[i][j]=a2[i-1][j+1];
			}
		}
	}
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if((i+j)&1)
			{
				a[i][j]=p1[a1[i][j]]*p2[a2[i][j]];
				S.insert(a[i][j]);
			}
		}
	}
	
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			if(!((i+j)&1))
			{
				ll tmp=lcm(lcm(a[i-1][j],a[i+1][j]),lcm(a[i][j-1],a[i][j+1]));
				ll cur=tmp+1;
				while(S.find(cur)!=S.end())
				{
					cur+=tmp;
				}
				a[i][j]=cur;
				S.insert(cur);
			}
		}
	}
	ll maxx=0;
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)
		{
			chmax(maxx,a[i][j]);
			printf("%lld ",a[i][j]);
		}
		printf("\n");
	}
	fprintf(stderr,"@ %lld\n",maxx);
	return 0;
}


Measured memory_bytes: 18944