#include<bits/stdc++.h>
#define taskname "C"
using namespace std;
typedef long long ll;
template<class T>bool minimize(T& a, T b){
if(a > b){
a = b;
return true;
}
return false;
}
const int lim = 51;
ll Ckn[lim][lim];
vector<vector<int>>ans[lim];
int best_min[lim];
void merge(int a, int b, int c, int d){
int x = a + b + c + d, sum_best_min = best_min[a] + best_min[b] + best_min[c] + best_min[d];
if(x >= lim || sum_best_min >= lim || !minimize(best_min[x], sum_best_min)){
return;
}
ans[x].clear();
int offset = 0;
for(int y : {a, b, c, d}){
for(vector<int>& ve : ans[y]){
ans[x].push_back(ve);
for(int& i : ans[x].back()){
i += offset;
}
}
offset += best_min[y];
}
}
int main(){
ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
if(fopen(taskname".inp", "r")){
freopen(taskname".inp", "r", stdin);
}
memset(Ckn, 0, sizeof(Ckn));
fill(Ckn[0], Ckn[0] + lim, 1);
for(int k = 1; k < lim; k++){
for(int n = k; n < lim; n++){
Ckn[k][n] = Ckn[k][n - 1] + Ckn[k - 1][n - 1];
}
}
memset(best_min, 0x0f, sizeof(best_min));
for(int d : {1, 2, 3, 4, 6}){
for(int k = 1; 12 + d * k < lim && Ckn[k][12 / d + k] < lim; k++){
int siz = 12 / d + k, n = Ckn[k][siz];
if(minimize(best_min[n], siz * d)){
vector<vector<int>>S(siz, vector<int>(d));
for(int i = 0; i < siz; i++){
iota(S[i].begin(), S[i].end(), i * d + 1);
}
for(int mask = 0; mask < (1 << siz); mask++){
if(__builtin_popcount(mask) == k){
vector<int>t;
for(int i = 0; i < siz; i++){
if((mask >> i & 1) == 0){
for(int& j : S[i]){
t.push_back(j);
}
}
}
ans[n].push_back(t);
}
}
}
}
}
ans[1].push_back({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, best_min[1] = 12});
ans[2].push_back({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12});
ans[2].push_back({13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, best_min[2] = 24});
for(int a = best_min[0] = 0; a < lim; a++){
for(int b = a; b < lim; b++){
for(int c = b; c < lim; c++){
for(int d = c; d < lim; d++){
merge(a, b, c, d);
}
}
}
}
int n;
cin >> n;
for(vector<int>& ve : ans[n]){
for(int& x : ve){
cout << x - 1 << " ";
}
cout << "\n";
}
}