#pragma GCC optimize("O3,unroll-loops") #include #include #include #include #include #include using namespace std; int N; int W_edge[105]; bool used_even[205]; int even_candidates[105]; int num_even; int adj_to[105][5]; int adj_weight[105][5]; int adj_id[105][5]; int adj_deg[105]; bool is_sq[40005]; int current_path[105]; int path_len; vector found_path_res; bool vis[105]; int dfs_steps; const int MAX_DFS_STEPS = 2000; int backtrack_calls; const int MAX_CALLS = 100000; inline void add_edge(int u, int v, int w, int id) { adj_to[u][adj_deg[u]] = v; adj_weight[u][adj_deg[u]] = w; adj_id[u][adj_deg[u]] = id; adj_deg[u]++; adj_to[v][adj_deg[v]] = u; adj_weight[v][adj_deg[v]] = w; adj_id[v][adj_deg[v]] = id; adj_deg[v]++; } inline void remove_edge(int u, int v) { adj_deg[u]--; adj_deg[v]--; } bool has_square_path(int u, int target, int current_sum, bool is_verify) { if (is_verify) { dfs_steps++; if (dfs_steps > MAX_DFS_STEPS) return false; } if (current_sum >= 40005) return false; if (u == target) { if (is_sq[current_sum]) { found_path_res.assign(current_path, current_path + path_len); return true; } return false; } int deg = adj_deg[u]; int order[4] = {0, 1, 2, 3}; for(int i = 0; i < deg; ++i) { for(int j = i + 1; j < deg; ++j) { if (abs(adj_to[u][order[i]] - target) > abs(adj_to[u][order[j]] - target)) { int tmp = order[i]; order[i] = order[j]; order[j] = tmp; } } } for(int i = 0; i < deg; ++i) { int v = adj_to[u][order[i]]; if (vis[v]) continue; vis[v] = true; current_path[path_len++] = adj_id[u][order[i]]; if (has_square_path(v, target, current_sum + adj_weight[u][order[i]], is_verify)) return true; path_len--; vis[v] = false; } return false; } mt19937 rng(1337); bool backtrack(int k) { backtrack_calls++; if (backtrack_calls > MAX_CALLS) return false; if (k == N - 1) return true; int new_node = k + 2; vector preferred; vector secondary; int odd_squares[] = {9, 25, 49, 81, 121, 169, 225, 289, 361}; for(int S : odd_squares) { int w = S - (2 * k - 1); if (w >= 2 && w <= 200 && w % 2 == 0 && !used_even[w]) { preferred.push_back(w); } } shuffle(preferred.begin(), preferred.end(), rng); for (int i = 0; i < num_even; ++i) { int w = even_candidates[i]; if (!used_even[w]) { bool in_pref = false; for(int p : preferred) if (p == w) in_pref = true; if (!in_pref) secondary.push_back(w); } } shuffle(secondary.begin(), secondary.end(), rng); vector combined = preferred; combined.insert(combined.end(), secondary.begin(), secondary.end()); for (int w : combined) { W_edge[k] = w; used_even[w] = true; add_edge(k, new_node, w, N - 1 + k); bool valid = true; for (int start = 1; start < new_node; ++start) { for(int v = 1; v <= new_node; ++v) vis[v] = false; vis[new_node] = true; dfs_steps = 0; path_len = 0; if (!has_square_path(new_node, start, 0, true)) { valid = false; break; } } if (valid) { if (backtrack(k + 1)) return true; } used_even[w] = false; remove_edge(k, new_node); if (backtrack_calls > MAX_CALLS) return false; } return false; } int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); if (!(cin >> N)) return 0; for (int i = 0; i < 40005; ++i) is_sq[i] = false; for (int i = 1; i * i < 40005; ++i) is_sq[i * i] = true; num_even = 0; for (int i = 2; i <= 200; i += 2) { even_candidates[num_even++] = i; } while (true) { for(int i = 0; i <= 200; ++i) used_even[i] = false; for(int i = 1; i <= N; ++i) adj_deg[i] = 0; for (int i = 1; i < N; ++i) { add_edge(i, i + 1, 2 * i - 1, i); } backtrack_calls = 0; if (backtrack(1)) break; } cout << (2 * N - 3) << "\n"; for (int i = 1; i < N; ++i) { cout << i << " " << (i + 1) << " " << (2 * i - 1) << "\n"; } for (int k = 1; k <= N - 2; ++k) { cout << k << " " << (k + 2) << " " << W_edge[k] << "\n"; } for (int i = 1; i <= N; ++i) { for (int j = i + 1; j <= N; ++j) { for(int v = 1; v <= N; ++v) vis[v] = false; vis[i] = true; dfs_steps = 0; path_len = 0; found_path_res.clear(); has_square_path(i, j, 0, false); cout << found_path_res.size() << "\n"; for (int k = 0; k < found_path_res.size(); ++k) { cout << found_path_res[k] << (k == found_path_res.size() - 1 ? "" : " "); } cout << "\n"; } } return 0; }