// Words are flowing out like endless rain into a paper cup
// They slither while they pass they slip away across the universe
// Pools of sorrow, waves of joy are drifting through my open mind
// Possessing and caressing me

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

using LL = long long;

namespace _buff {

const size_t BUFF = 1 << 19;
char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
char getc() {
    if (ib == ie) {
        ib = ibuf;
        ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    }
    return ib == ie ? -1 : *ib++;
}

}

LL read() {
    using namespace _buff;
    LL ret = 0;
    bool pos = true;
    char c = getc();
    for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
        assert(~c);
    }
    if (c == '-') {
        pos = false;
        c = getc();
    }
    for (; c >= '0' && c <= '9'; c = getc()) {
        ret = (ret << 3) + (ret << 1) + (c ^ 48);
    }
    return pos ? ret : -ret;
}

template <typename T>
void chkmax(T &dp, const T &val) {
    if (val > dp) {
        dp = val;
    }
}

const size_t N = 5E2 + 5;
const size_t M = 2E4 + 5;

bool npr[M];
map<int, int> mp[N][N];
LL a[N][N];

void upd(map<int, int> &mp, const map<int, int> &dat) {
    for (auto &pr : dat) {
        int p = pr.first, e = pr.second;
        chkmax(mp[p], e);
    }
}

LL get_val(const map<int, int> &mp) {
    LL ret = 1;
    for (const auto &pr : mp) {
        int p = pr.first, e = pr.second;
        while (e--) {
            ret *= p;
        }
    }
    return ret;
}

LL calc(LL a, LL b) {
    if (a < b) swap(a, b);
    return a % b;
}

int main() {
    vector<int> vc;
    for (uint i = 2; i < M; ++i) {
        if (!npr[i]) {
            vc.emplace_back(i);
            for (uint j = i << 1; j < M; j += i) {
                npr[j] = true;
            }
        }
    }

    int n = read(), c = 0;
    if (n == 2) {
        puts("4 7\n23 10");
        return 0;
    }
    for (int s = 2; s <= n + n; ++s) {
        if (s & 1) continue;
        for (int i = 1; i <= n; ++i) {
            int j = s - i;
            if (1 <= i && i <= n &&
                1 <= j && j <= n) {
                ++mp[i][j][vc[c]];
            }
        }
        ++c;
    }
    for (int d = 1 - n; d <= n - 1; ++d) {
        if (d & 1) continue;
        for (int i = 1; i <= n; ++i) {
            int j = d + i;
            if (1 <= i && i <= n &&
                1 <= j && j <= n) {
                ++mp[i][j][vc[c]];
            }
        }
        ++c;
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if ((i ^ j) & 1) {
                upd(mp[i][j], mp[i - 1][j]);
                upd(mp[i][j], mp[i][j - 1]);
                upd(mp[i][j], mp[i][j + 1]);
                upd(mp[i][j], mp[i + 1][j]);
                a[i][j] = get_val(mp[i][j]) + 1;
            } else {
                a[i][j] = get_val(mp[i][j]);
            }
            printf("%lld%c", a[i][j], "\n "[j < n]);
        }
    }
    set<LL> s1, s2;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            if (i < n) s1.emplace(calc(a[i][j], a[i + 1][j]));
            if (j < n) s1.emplace(calc(a[i][j], a[i][j + 1]));
            s2.emplace(a[i][j]);
        }
    }
    assert(s1.size() == 1 && *s2.rbegin() <= (LL) 1E15 && s2.size() == n * n);
    return 0;
}


Measured memory_bytes: 64384