1 #include<iostream>
2 #include<queue>
3 #include<cstdio>
4 #include<cstring>
5 #include<cmath>
6 using namespace std;
7
8 const int INF = 0x3f3f3f3f;
9 const int maxn = 100100;
10
11 int d[maxn];
12 int now[maxn];
13 const int st = 0, ed = 100010;
14 int n;
15 int cnt = 1;
16 int tot;
17 int num;
18 int ans[maxn];
19 bool vis[maxn];
20 int nxt[maxn];
21
22 struct Edge
23 {
24 int v, nxt;
25 int w;
26 }e[maxn];
27
28 int head[maxn];
29
30 void add_dinic(int u, int v)
31 {
32 e[++cnt].v = v;
33 e[cnt].w = 0;
34 e[cnt].nxt = head[u];
35 head[u] = cnt;
36 }
37
38 void add(int u, int v, int w)
39 {
40 e[++cnt].v = v;
41 e[cnt].nxt = head[u];
42 head[u] = cnt;
43 e[cnt].w = w;
44 add_dinic(v, u);
45 }
46
47 int dfs_dinic(int x, int flow)
48 {
49 if (x == ed) return flow;
50 int res = 0;
51 for (int i = now[x]; i != -1; i = e[i].nxt)
52 {
53 int v = e[i].v;
54 if (d[v] + 1 == d[x] && e[i].w > 0)
55 {
56 int k = dfs_dinic(v, min(e[i].w, flow));
57 if (k >= 0) nxt[x >> 1] = v >> 1;
58 res += k;
59 flow -= k;
60 e[i].w -= k;
61 e[i ^ 1].w += k;
62 if (!flow) break;
63 }
64 }
65 return res;
66 }
67
68 bool bfs_dinic()
69 {
70 memset(d, 0, sizeof(d));
71 queue<int>q;
72 q.push(ed);
73 d[ed] = 1;
74 while (!q.empty())
75 {
76 int u = q.front();
77 q.pop();
78 for (int i = head[u]; i != -1; i = e[i].nxt)
79 {
80 int v = e[i].v;
81 if (!d[v] && e[i ^ 1].w > 0)
82 {
83 q.push(v);
84 d[v] = d[u] + 1;
85 }
86 }
87 }
88 return d[st] > 0;
89 }
90
91 int dinic()
92 {
93 int flow = 0;
94 while (bfs_dinic())
95 {
96 for (int i = 0; i <= ed; i++) now[i] = head[i];
97 flow += dfs_dinic(st, INF);
98 }
99 return flow;
100 }
101
102 int main()
103 {
104 memset(head, -1, sizeof(head));
105 memset(nxt, -1, sizeof(nxt));
106 cin >> n;
107 cnt = 1;
108 while (tot <= n)
109 {
110 num++;
111 add(st, num << 1, 1);
112 add(num << 1 | 1, ed, 1);
113 for (int i = sqrt(num) + 1; i * i < (num << 1); ++i)
114 add((i * i - num) << 1, num << 1 | 1, 1);
115 int k = dinic();
116 if (!k) ans[++tot] = num;
117 }
118 cout << --num << endl;
119 for (int i = 1; i <= n; i++)
120 {
121 if (vis[ans[i]]) continue;
122 int x = ans[i];
123 cout << x << " ";
124 vis[x] = true;
125 while ((~nxt[x]) && nxt[x] != (ed >> 1) && nxt[x])
126 {
127 x = nxt[x];
128 vis[x] = true;
129 cout << x << " ";
130 }
131 cout << endl;
132 }
133
134 }