#include <bits/stdc++.h>

#define debug(x) cout << #x << " = " << x << endl
#define fori(i, ini, lim) for(int i = int(ini); i < int(lim); i++)
#define ford(i, ini, lim) for(int i = int(ini); i >= int(lim); i--)

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> ii;

const int MAX = 1000 + 5;
ll mat[MAX][MAX];
vector<int> primes;
int n;

void sieve() {
    for(int i = 2; (int) primes.size() < MAX; i++) {
        bool is_prime = true;
        fori(j, 2, i) {
            if(i % j == 0) {
                is_prime = false;
                break;
            }
        }
        if(is_prime) {
            primes.push_back(i);
        }
    }
}

ll gcd(ll a, ll b) {
    return !b ? a : gcd(b, a % b);
}

ll lcm(ll a, ll b) {
    return (a * (b / (gcd(a, b))));
}

bool construct() {
    //random_shuffle(primes.begin(), primes.end()); 
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            mat[i][j] = 1;
        }
    }
    int k = 0;
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            if((i == 1 || j == 1) && (i + j) % 2 == 1) {
                for(int ni = i, nj = j; ni <= n && nj <= n; ni++, nj++) {
                    mat[ni][nj] *= primes[k];                                        
                }
                k++;
            }
        }
    }
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            if((i == 1 || j == n) && (i + j) % 2 == 1) {
                for(int ni = i, nj = j; ni <= n && nj >= 1; ni++, nj--) {
                    mat[ni][nj] *= primes[k];                                        
                }
                k++;
            }
        }
    }
    const vector<ii> dir {{0, -1}, {-1, 0}, {0, 1}, {1, 0}};
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            if((i + j) % 2 == 0) {
                ll l = 1;
                for(auto &each : dir) {
                    int ni = i + each.first;
                    int nj = j + each.second;
                    if(ni >= 1 && ni <= n && nj >= 1 && nj <= n) {
                        l = lcm(l, mat[ni][nj]);
                    }
                }
                mat[i][j] = l + 1;
            }
        }
    }
    set<ll> all;
    bool ok = true;
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            all.insert(mat[i][j]);
            assert(mat[i][j] > 0);
            if(mat[i][j] > (ll) 1e15) {
                ok = false;
            }
            for(auto &each : dir) {
                int ni = i + each.first;
                int nj = j + each.second;
                if(ni >= 1 && ni <= n && nj >= 1 && nj <= n) {
                    assert(max(mat[i][j], mat[ni][nj]) % min(mat[i][j], mat[ni][nj]) == 1);
                }
            }
        }
    }
    return ok && (int) all.size() == n * n;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    srand(time(nullptr));
    cin >> n;
    if(n == 2) {
        cout << "4 7" << '\n';
        cout << "23 10" << '\n';
        return 0;
    }
    sieve();
    while(!construct());
    fori(i, 1, n + 1) {
        fori(j, 1, n + 1) {
            if(j > 1) {
                cout << " ";
            }
            cout << mat[i][j];
        }
        cout << '\n';
    }
    return 0;
}


Measured memory_bytes: 18816