#include using namespace std; bool is_sq(int x) { if (x < 0) return false; int r = (int)sqrt(x); while (r*r < x) ++r; while (r*r > x) --r; return r*r == x; } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int N; cin >> N; vector> edges; auto add = [&](int u, int v, int w) { edges.push_back({u, v, w}); return (int)edges.size(); }; int e12 = add(1, 2, 1); vector a(N+1), b(N+1); vector e1(N+1), e2(N+1); vector used(201, false); used[1] = true; for (int i = 3; i <= N; ++i) { bool found = false; for (int av = 2; av <= 200 && !found; ++av) { if (used[av]) continue; for (int S : {196, 225, 169, 144, 256, 121, 289, 100, 324, 361, 64, 400}) { int bv = S - 1 - av; if (bv < 1 || bv > 200 || used[bv] || av == bv) continue; bool ok = true; for (int j = 3; j < i; ++j) { if (!is_sq(av + a[j]) && !is_sq(bv + b[j]) && !is_sq(av + 1 + b[j]) && !is_sq(bv + 1 + a[j])) { ok = false; break; } } if (ok) { a[i] = av; b[i] = bv; used[av] = used[bv] = true; e1[i] = add(1, i, av); e2[i] = add(2, i, bv); found = true; break; } } } if (!found) { cerr << "Failed\n"; return 1; } } vector>> path(N+1, vector>(N+1)); auto setp = [&](int i, int j, const vector& v) { path[i][j] = v; }; setp(1, 2, {e12}); for (int i = 3; i <= N; ++i) { setp(1, i, {e1[i]}); setp(2, i, {e2[i]}); } for (int i = 3; i <= N; ++i) { for (int j = i+1; j <= N; ++j) { vector>> cand = { {a[i]+a[j], {e1[i], e1[j]}}, {b[i]+b[j], {e2[i], e2[j]}}, {a[i]+1+b[j], {e1[i], e12, e2[j]}}, {b[i]+1+a[j], {e2[i], e12, e1[j]}} }; for (auto& [sum, ids] : cand) { if (is_sq(sum)) { setp(i, j, ids); break; } } } } cout << edges.size() << "\n"; for (auto& [u,v,w] : edges) cout << u << " " << v << " " << w << "\n"; for (int i = 1; i <= N; ++i) { for (int j = i+1; j <= N; ++j) { cout << path[i][j].size(); for (int id : path[i][j]) cout << " " << id; cout << "\n"; } } }