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++ (GCC 5.4.1) (judge verdict: Wrong Answer)

#include<bits/stdc++.h>
#define Fail puts("NO"),exit(0);
#define eps 1e-10
#define maxn 505
#define maxm 4010
#define inf 1000000007
#define mod 998244353
#define pi acos(-1)
#define mp(x,y) make_pair(x,y)
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int>pii;
typedef bitset<maxn> bit;
int read()
{
    int x=0,f=1;
    char ch=getchar();
    while(ch-'0'<0||ch-'0'>9){if(ch=='-') f=-1;ch=getchar();}
    while(ch-'0'>=0&&ch-'0'<=9){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int n;
int prime[100010],primesize;
bool notprime[100010];
void get_prime()
{
    for(int i=2;i<=100000;i++)
    {
        if(!notprime[i])   prime[++primesize]=i;
        for(int j=1;j<=primesize&&i*prime[j]<=100000;j++)
        {
            notprime[i*prime[j]]=true;
            if(i%prime[j]==0)  break;
        }
    }
}
ll ans[maxn][maxn];
int xx[4]={0,0,1,-1};
int yy[4]={1,-1,0,0};
bool check(int x,int y)
{
    return (x>=1&&x<=n&&y>=1&&y<=n);
}
ll gcd(ll x,ll y)
{
    if(!y)  return x;
    return gcd(y,x%y);
}
ll lcm(ll x,ll y)
{
    return x*(y/gcd(x,y));
}
int main()
{
    get_prime();
    n=read();
    int l=1,r=(n<<1)+(!(n&1));
    for(int i=2;i<=(n<<1);i+=2)
    {
        int val;
        if(i%4==0)  val=prime[l++];
        else        val=prime[r--];
        for(int x=1;x<=n;x++)
        {
            int y=(i-x);
            if(y<=0||y>n)  continue;
            ans[x][y]=val;
        }
    }
    for(int i=-(n-1)/2*2;i<=(n-1)/2*2;i+=2)
    {
        int val;
        if(i%4==0)  val=prime[l++];
        else        val=prime[r--];
        for(int x=1;x<=n;x++)
        {
            int y=(i+x);
            if(y<=0||y>n)  continue;
            ans[x][y]*=val;
        }
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if((i+j)&1)
            {
                for(int k=0;k<4;k++)
                {
                    int tx=i+xx[k],ty=j+yy[k];
                    if(check(tx,ty))
                    {
                        if(!ans[i][j])  ans[i][j]=ans[tx][ty];
                        else          ans[i][j]=lcm(ans[i][j],ans[tx][ty]);
                    }
                }
                ans[i][j]++;
            }
        }
    }
    ll mx=0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)  mx=max(mx,ans[i][j]),printf("%lld ",ans[i][j]);
        puts("");
    }
    cout<<mx<<endl;
    return 0;
}