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 <set>
using namespace std;
typedef long long ll;
const int N = 505;
int n, tail;
ll ans[N][N];
set<ll> used;
ll gcd(ll x, ll y) { return (!x) ? (y) : gcd(y % x, x); }
ll lcm(ll x, ll y) { return (!x || !y) ? (x | y) : (x * y / gcd(x, y)); }
int pri[N * N];
bool isNot[N * N];
void Sieve() {
	for (int i = 2; i <= n * n; ++i) {
		if (!isNot[i])
			pri[++tail] = i;
		for (int j = 1; j <= tail && pri[j] * i <= n * n; ++j) {
			isNot[pri[j] * i] = 1;
			if (i % pri[j] == 0)
				continue ;
		}
	}
}
int main() {
	scanf("%d", &n);
	Sieve();
	int cnt = 0;
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j)
			if ((i & 1) == (j & 1))
				ans[i][j] = pri[++cnt], used.insert(pri[cnt]);
	for (int i = 1; i <= n; ++i)
		for (int j = 1; j <= n; ++j) {
			if ((i & 1) != (j & 1)) {
				ans[i][j] = 1;
				if (ans[i - 1][j])
					ans[i][j] *= ans[i - 1][j];
				if (ans[i][j - 1])
					ans[i][j] *= ans[i][j - 1];
				if (ans[i + 1][j])
					ans[i][j] *= ans[i + 1][j];
				if (ans[i][j + 1])
					ans[i][j] *= ans[i][j + 1];
				ll tmp = ans[i][j];
				while (used.count(ans[i][j] + 1))
					ans[i][j] += tmp;
				++ans[i][j];
				used.insert(ans[i][j]);
			}
		}
	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= n; ++j)
			printf("%lld ", ans[i][j]);
		printf("\n");
	}
	return 0;
}