#include<bits/stdc++.h>
const int INF = 0x3f3f3f3f;
const int Maxn = 255;
#define ll long long
#define mem(x,y) memset(x,y,sizeof(x))
using namespace std;
int mp[Maxn][Maxn], cnt = 0, flag = 0;
int mx[8] = {2, 2, 1, 1, -2, -2, -1, -1}, my[8] = {1, -1, 2, -2, 1, -1, 2, -2};
int door(int x, int y, int n) { // 计算(x,y)下一步能跳的位置数
int cnt = 0;
for (int i = 0; i < 8; i++) {
int a = x + mx[i], b = y + my[i];
if (a >= 1 && a <= n && b >= 1 && b <= n && mp[a][b] == 0)
cnt++;
}
return cnt;
}
void deal(int n) {
if (n > 1 && n < 5) return;
cnt = flag = 0;
for (int tt = 1; tt <= 8; tt++)
for (int xx = 1; xx <= 6; xx++) {
int x = tt, y = xx;
mem(mp, 0);
for (cnt = 1; cnt <= n * n; cnt++) {
mp[x][y] = cnt;
if (cnt == n * n) {
flag = 1;
return;
}
if (door(x, y, n) == 0)
break;
int m = 10, a, b;
for (int i = 0; i < 8; i++) { // 贪心
int p = x + mx[i], q = y + my[i];
if (!(p >= 1 && p <= n && q >= 1 && q <= n && mp[p][q] == 0)) continue;
int k = door(p, q, n);
if (k < m) {
m = k;
a = p, b = q;
}
}
x = a, y = b;
}
}
}
int main() {
freopen("classic.in", "r", stdin);
freopen("classic.out", "w", stdout);
int N;
while (cin >> N) {
deal(N);
if (flag == 0)
printf("No solution.\n");
else {
printf("There is solution:\n");
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
printf("%d%c", mp[i][j], j == N ? '\n' : ' ');
}
}
}