#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"
#include "complex"

using namespace std;

const long long int MOD = 1000000007;
const long double EPS = 1e-8;


long long int N, M, K, H, W, L, R;

list<int> Prime(int num) {
	list<int>P;
	for (int i = 5; i <= num; i += 6) {
		bool flag = true;
		for (auto j : P) {
			if (j*j > i) {
				break;
			}
			if (i%j == 0) {
				flag = false;
				break;
			}
		}
		if (flag)P.push_back(i);
		flag = true;
		for (auto j : P) {
			if (j*j > i + 2) {
				break;
			}
			if ((i + 2) % j == 0) {
				flag = false;
				break;
			}
		}
		if (flag)P.push_back(i + 2);
	}
	P.push_front(3);
	P.push_front(2);
	return P;
}

inline long long int gcd(long long int a, long long int b) {
	if (a < b)a ^= b ^= a ^= b;
	while (b) {
		a %= b;
		a ^= b ^= a ^= b;
	}
	return a;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> N;
	auto P = Prime(10000);
	list<int>p;
	P.pop_front();
	while (p.size() < N + 2) {
		p.push_back(P.front());
		P.pop_front();
	}
	vector<int>tate((N+2)/2);
	vector<int>yoko((N+2)/2);
	for (int i = 0; i < (N + 2) / 2; i++) {
		if (i % 2) {
			tate[i] = p.front();
			p.pop_front();
		}
		else {
			tate[i] = p.back();
			p.pop_back();
		}
	}
	for (int i = 0; i < N/2+1; i++) {
		if (i % 2) {
			yoko[i] = p.front();
			p.pop_front();
		}
		else {
			yoko[i] = p.back();
			p.pop_back();
		}
	}
	vector<vector<long long int>>v(N, vector<long long int>(N));
	map<long long int, int>m;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if ((i^j) & 1) {
				v[i][j] = tate[i / 2] * yoko[j / 2] * 2;
				if (m[v[i][j]])v[i][j] *= 2;
				m[v[i][j]]++;
			}
		}
	}
	int dir[] = { 0,1,0,-1,0 };
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (!v[i][j]) {
				v[i][j] = 1;
				for (int k = 0; k < 4; k++) {
					int ny = i + dir[k];
					int nx = j + dir[k + 1];
					if (ny < 0 || nx < 0 || ny >= N || nx >= N)continue;
					v[i][j] = v[i][j] / gcd(v[i][j], v[ny][nx])*v[ny][nx];
				}
				v[i][j]++;
				if (m[v[i][j]])v[i][j] = v[i][j] * 2 - 1;
				m[v[i][j]]++;
			}
		}
	}
	long long int mx = 0;
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (j)cout << " ";
			cout << v[i][j];
			mx = max(mx, v[i][j]);
		}
		cout << endl;
	}
	return 0;
}
#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;

#define pii pair<int , int>
#define mp make_pair
#define fi first
#define se second

const int MAXN = 2e5 + 10;
int pc;
int pr[MAXN] , f[MAXN];
LL A[MAXN] , B[MAXN];

template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
template <typename T> inline void read(T &x) {
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
    x *= f;
}

inline void G(int n) {
		for (int i = 2; i <= n; ++i) {
				if (!f[i]) f[i] = pr[++pc] = i;
				for (int j = 1; j <= pc && i * pr[j] <= n; ++j) {
						f[i * pr[j]] = pr[j];
						if (i % pr[j] == 0) break;
				}
		}
}
int main() {
		
		int n;
		scanf("%d" , &n); G(10000);
		for (int i = 1; i <= n; ++i) A[i] = pr[i & 1 ? i / 2 + 1 : n + n - i / 2 + 1];
		for (int i = 1; i <= n; ++i) B[i] = pr[(i & 1 ? n - i / 2 : n + i / 2) + (n & 1)];
		A[0] = A[n + 1] = B[0] = B[n + 1] = 1;
		for (int i = 1; i <= n; ++i , printf("\n")) 
		for (int j = 1; j <= n; ++j)
				if ((i + j) & 1) printf("%lld " , (LL) A[(i + j) / 2] * A[(i + j) / 2 + 1] * B[(n + i - j + (n & 1)) / 2] * B[(n + i - j + (n & 1)) / 2 + 1] + 1);
				else printf("%lld " , A[(i + j) / 2] * B[(n + i - j + (n & 1)) / 2]); 
	  return 0;
}