#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int nax = 2500;
vector<int> p[nax];
mt19937
rng((unsigned int)chrono::steady_clock::now().time_since_epoch().count());
// metoda uzaludnih pokusaja
// bilo bi zanimljivo da prodje
void prepare() {
for (int i = 0; i < nax; ++i) {
p[i].assign(50, 0);
iota(p[i].begin(), p[i].end(), 0);
shuffle(p[i].begin(), p[i].end(), rng);
}
}
vector<int> normalize(vector<int> v) {
ranges::sort(v);
v.erase(unique(v.begin(), v.end()), v.end());
vector<int> used(50);
for (int x : v)
used[x] = 1;
while (v.size() < 12) {
int x = rng() % 50;
if (!used[x]) {
used[x] = 1;
v.push_back(x);
}
}
ranges::sort(v);
return v;
}
vector<int> get_random_12() {
int id = rng() % nax;
vector<int> v;
for (int i = 0; i < 12; ++i) {
v.emplace_back(p[id][i]);
}
return normalize(v);
}
void print_vec(vector<int> v) {
v = normalize(v);
for (auto x : v)
cout << x << " ";
cout << "\n";
}
void solve(int n) {
if (n <= 4) {
for (int i = 0, num = 0; i < n; ++i) {
for (int j = 0; j < 12; ++j) {
cout << num++ << " ";
}
cout << "\n";
}
return;
}
int done = 0;
while (n - done >= 4) {
int id = rng() % nax;
vector<int> base(16);
for (int i = 0; i < 16; ++i) {
base[i] = p[id][i];
}
array<vector<int>, 4> ans;
vector<int> miss = {0, 1, 2, 3};
shuffle(miss.begin(), miss.end(), rng);
for (int who = 0; who < 4; ++who) {
for (int j = 0; j < 16; ++j) {
if (j % 4 != miss[who])
ans[who].push_back(base[j]);
}
}
for (int who = 0; who < 4; ++who) {
print_vec(ans[who]);
}
done += 4;
}
while (done < n) {
print_vec(get_random_12());
done++;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n;
cin >> n;
prepare();
solve(n);
// cout << endl;
// solve(13);
// for (int i = 5; i < n; ++i) {
// solve(i);
// }
return 0;
}