Problem:
Score : 1100 points

Problem Statement

You are given an integer N.

Construct any one N-by-N matrix a that satisfies the conditions below. It can be proved that a solution always exists under the constraints of this problem.

1 \leq a_{i,j} \leq 10^{15}

a_{i,j} are pairwise distinct integers.

There exists a positive integer m such that the following holds: Let x and y be two elements of the matrix that are vertically or horizontally adjacent. Then, {\rm max}(x,y) {\rm mod} {\rm min}(x,y) is always m.

Constraints

2 \leq N \leq 500

Input

Input is given from Standard Input in the following format:

N

Output

Print your solution in the following format:

a_{1,1} ... a_{1,N}
:
a_{N,1} ... a_{N,N}

Sample Input 1

2

Sample Output 1

4 7
23 10

For any two elements x and y that are vertically or horizontally adjacent, {\rm max}(x,y) {\rm mod} {\rm min}(x,y) is always 3.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<cassert>
using namespace std;
long long gcd(long long a,long long b)
{
	if(!b)return a;
	return gcd(b,a%b);
}
int n,nn;
map<long long,bool>mp;
long long a[510][510];
bool used[250050];
int p[250050],cnt;
long long calc(int i,int j)
{
	long long res=1,s;
	if(i>1)res=res*a[i-1][j]/gcd(res,a[i-1][j]);
	if(i<n)res=res*a[i+1][j]/gcd(res,a[i+1][j]);
	if(j>1)res=res*a[i][j-1]/gcd(res,a[i][j-1]);
	if(j<n)res=res*a[i][j+1]/gcd(res,a[i][j+1]);
	s=res;
	while(mp[s+1])s+=res;
	mp[s+1]=1;
	if(s+1>1e15)assert(0);
	return s+1;
}
int main()
{
	scanf("%d",&n);
	if(n&1)nn=n+1;
	else nn=n;
	int lim1=nn*nn/2+1;
//	for(int i=3-(n&1);i<=n;i+=4)a[n][i]=lim1--,i!=n?a[i][n]=lim1--:0;
//	int ps=3-(n&1)+2;
//	while(ps+4<=n)ps+=4;
//	for(int i=ps;i;i-=4)a[n][i]=lim1--,i!=n?a[i][n]=lim1--:0;
//	for(int i=2;i<=n;i+=2)a[1][i]=lim1--,a[i][1]=lim1--;
	for(int i=1;2*i<=lim1;++i)
	{
		p[++cnt]=2*i+1;
		p[++cnt]=4*i+2;
	}
//	if(lim1&1)p[++cnt]=2;
//	for(int c=2;c<=lim1/2;++c)
//		for(int i=2;i<=lim1/c;++i)
//			if(3*i>=lim1&&!used[i]&&!used[c*i])
//			{
//				used[i]=used[c*i]=1;
//				p[++cnt]=i,p[++cnt]=c*i;
//			}
//	printf("!!!\n");
/*	int l=2,r=lim1;
	while(l<r)
	{
		while(used[l])++l;
		while(used[r])--r;
		p[++cnt]=l;
		if(l!=r)p[++cnt]=r;
		used[l]=1,used[r]=1;
	}*/
	int st=1,ed=lim1-(lim1&1);
	for(int i=1;i<=nn-1;i+=2)
		for(int j=1;j<=nn-1;j+=2)
		{
			if((i+j)&3)a[i][j+1]=p[st++],a[i+1][j]=p[st++];
			else a[i][j+1]=p[ed--],a[i+1][j]=p[ed--];
		}
/*	int l=2,r=n*n/2+1;
	for(int i=1;i<=n;i+=4)p1[++len1]=i;
	for(int i=2;i<=n;i+=4)p2[++len2]=i;
	for(int i=3;i<=n;i+=4)p3[++len3]=i;
	for(int i=4;i<=n;i+=4)p4[++len4]=i;
	for(int i=1;i<=n;++i)
	{
		if(i&1)
		{
			for(int j=1;j<=len2;++j)a[i][p2[j]]=r--;
			for(int j=len4;j;--j)a[i][p4[j]]=r--;
		}
		else
		{
			for(int j=1;j<=len1;++j)a[i][p1[j]]=l++;
			for(int j=len3;j;--j)a[i][p3[j]]=l++;
		}
	}*/
/*	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)printf("%3lld ",a[i][j]);
		printf("\n");
	}*/
	for(int i=1;i<=n;++i)
		for(int j=2-(i&1);j<=n;j+=2)a[i][j]=calc(i,j);
	for(int i=1;i<=n;++i)
	{
		for(int j=1;j<=n;++j)printf("%lld ",a[i][j]);
		printf("\n");
	}
	return 0;
}