/// Kazuki Hoshino


#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
using namespace std;
#define int long long
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef vector<pi> vpi;
#define inf 1000000000
#define mod 1000000007
#define rep(i,a,b) for (int i = a; i <= b; i++)
#define rep1(i, a, b) for(int i =a; i >=b; i--)
#define f first
#define ss second
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define mt make_tuple
//#define endl '\n'
typedef tree<
int,
null_type,less<int>,
rb_tree_tag,tree_order_statistics_node_update>
ordered_set;


int n,ans[2000][2000], ans1[2000][2000], ans2[2000][2000],mx;
set<int> primes;
bool siv[100005];
vector<int> v;
int lc (){
       int res = v[0];
       for(int i=1;i<v.size();i++){
              res = (res)/(__gcd(res,v[i]))*v[i];
       }
       //cout << res << endl;
       assert(res<=1000000000000000&&res>=2);
       if(res>=1000000000000000){
              cout << endl;
              for(auto t:v){
                     cout << t << " ";
              }
              cout << endl;
              //cout << x << " " << y << " " << z << " " << w << endl;
              exit(0);
       }
       v.clear();
       return res;

}
bool check(){
       set<int> s;
       for(int i=1;i<n+1;i++){
              for(int j=1;j<n+1;j++){
                     int mx = max(ans[i+1][j],ans[i][j]);
                     int mn = min(ans[i+1][j],ans[i][j]);
                     if(i+1<=n)s.insert(mx%mn);
                     mx = max(ans[i][j+1],ans[i][j]);
                     mn = min(ans[i][j+1],ans[i][j]);
                     if(j+1<=n)s.insert(mx%mn);
              }
       }
       //cout << s.size() << endl;
       return s.size()==1;
}
void show(){
       for(int i=1;i<=n;i++){
              for(int j=1;j<=n;j++){
                     cout << ans[i][j] << " ";
                     mx = max(mx,ans[i][j]);
              }
              cout << endl;
       }
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);

//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);

cin >> n;
if(n==2){
       cout << "4 7 \n23 10 \n";
       return 0;
}
for(int i=1;i<=n;i++){
       for(int j=1;j<=n;j++)ans[i][j]=ans1[i][j]=ans2[i][j]=1;
}
for(int i=2;i<100000;i++){
       if(siv[i])continue;
       for(int j=i+i;j<100000;j+=i){
              siv[j]=true;
       }
}
for(int i=2;i<100000;i++){
       if(!siv[i])primes.insert(i);
}


int t=n;
if(n%2==0)t--;
for(int i=1;i<=n;i+=2){
       auto it=primes.begin();
       int cur = *it;
       primes.erase(it);
       it = primes.begin();
       int cur1 = *it;
       primes.erase(it);
       for(int k=0;i+k<=n;k++){
              ans[1+k][i+k]*=cur;
              if(i!=1){
                     ans[i+k][1+k]*=cur1;
              }
       }
}
/*
for(int i=t;i>=1;i=-2){
       auto it=primes.begin();
       int cur = *it;
       primes.erase(it);
       ans[i][n-i+1]*=cur;
       if(ans[n][i]==1)
       for(int k=0;i-k>0;k++){
              ans[n-k][i-k]*=cur;
              ans[n-k][i-k]*=cur;
       }
}
*/
//show();
for(int i=1;i<=n;i++){
       auto it = primes.begin();
       int cur = *it;
       primes.erase(it);
       ans[i][i]*=cur;
       for(int k=1;i-k>0;k++){
              ans[i-k][i+k]*=cur;
              ans[i+k][i-k]*=cur;
       }
}
//show();
int dx[]={1,0,-1,0},dy[]={0,1,0,-1};
for(int i=1;i<=n;i++){
       for(int j=1;j<=n;j++){
              if(ans[i][j]==1){
                     int res=1;
                     v.clear();
                     for(int k=0;k<4;k++){
                                   int x = ans[i+dx[k]][j+dy[k]];
                                   if(x>0){
                                          //cout << x << endl;
                                          v.pb(x);
                                   }
                     }
                     res = lc();
                     ans[i][j] = res + 1;
              }
              assert(ans[i][j]<=10000000000000000);
              //cout << ans[i][j] << " ";
       }
       //cout << endl;
}
assert(check()==true);

for(int i=1;i<n+1;i++){
       for(int j=1;j<n+1;j++){
              cout << ans[i][j] << " ";
              mx = max(ans[i][j],mx);
       }
       cout << endl;
}

//cout << mx << endl;

return 0;}
///....


Measured memory_bytes: 39424