P1008
#include <bits/stdc++.h>
const int N = 500010, M = 2000010;
int n, m;
int head[N], nxt[M << 1], to[M << 1], idx;
int dfn[N], low[N], tsp;
int stk[N], top, root;
int vdcc;
std::vector<int> pts[N];
void add(int u, int v) {
nxt[idx] = head[u];
to[idx] = v;
head[u] = idx;
++ idx;
return;
}
void dfsearch(int u, int last_ed) {
++ tsp;
dfn[u] = low[u] = tsp;
++ top;
stk[top] = u;
if (u == root && head[u] == -1) {
++ vdcc;
pts[vdcc].push_back(u);
return;
}
for (int i = head[u]; i != -1; i = nxt[i]) {
int e = to[i];
if (!dfn[e]) {
dfsearch(e, i);
low[u] = std::min(low[u], low[e]);
if (dfn[u] <= low[e]) {
int topele;
++ vdcc;
do {
topele = stk[top];
-- top;
pts[vdcc].push_back(topele);
} while (topele != e);
pts[vdcc].push_back(u);
}
} else if ((i xor 1) != last_ed) {
low[u] = std::min(low[u], dfn[e]);
}
}
return;
}
int main(void) {
memset(head, -1, sizeof(head));
idx = 0;
int inpu, inpv;
scanf("%d%d", &n, &m);
for (int i = 1; i <= m; ++ i) {
scanf("%d%d", &inpu, &inpv);
if (inpu == inpv) {
continue;
}
add(inpu, inpv);
add(inpv, inpu);
}
tsp = 0, top = 0, vdcc = 0;
for (int i = 1; i <= n; ++ i) {
if (!dfn[i]) {
root = i;
dfsearch(i, -1);
}
}
printf("%d\n", vdcc);
for (int i = 1; i <= vdcc; ++ i, puts("")) {
int len = pts[i].size();
printf("%d ", len);
for (int j = 0; j < len; ++ j) {
printf("%d ", pts[i][j]);
}
}
return 0;
}