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: Accepted)

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

const int Maxn = 505;
const int Maxm = 100000;

bool nprime[Maxm];
vector <int> pr;
int n;
ll B[Maxn][Maxn];
set <ll> S;

ll gcd(ll x, ll y) { return x? gcd(y % x, x): y; }

ll lcm(ll x, ll y) { return x / gcd(x, y) * y;  }

ll Get(ll a, ll b) { return max(a, b) % min(a, b); }

int main()
{
    for (int i = 2; i < Maxm; i++) if (!nprime[i]) {
        pr.push_back(i);
        for (int j = i + i; j < Maxm; j += i)
            nprime[j] = true;
    }
    scanf("%d", &n);
    int pnt = 2;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) if ((i + j) % 2 == 0) {
            B[i][j] = pr[(i + j) / 2] * pr[n + (i - j + n) / 2];
            S.insert(B[i][j]);
        }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++) if ((i + j) % 2) {
            ll my = 1;
            if (i > 0) my = lcm(my, B[i - 1][j]);
            if (i + 1 < n) my = lcm(my, B[i + 1][j]);
            if (j > 0) my = lcm(my, B[i][j - 1]);
            if (j + 1 < n) my = lcm(my, B[i][j + 1]);
            ll cur = my;
            while (S.find(cur + 1) != S.end()) {
                cur += my;
            }
            B[i][j] = cur + 1;
            S.insert(B[i][j]);
        }
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            printf("%lld%c", B[i][j], j + 1 < n? ' ': '\n');
    return 0;
}