#include <bits/stdc++.h> using namespace std; #define endl '\n' // #define int long long const int M = 5e6 + 5, mod = 998244353; int c, dfn[M], low[M], head[M], cnt, belong[M]; struct dian { int from, to, ne; } f[M]; vector<int> p[M]; void add(int x, int y) { f[++c].to = y; f[c].from = x; f[c].ne = head[x]; head[x] = c; } void dfs(int now, int fa) { dfn[now] = low[now] = ++cnt; for (int i = head[now]; i; i = f[i].ne) { int to = f[i].to; if (!dfn[to]) dfs(to, now); else if (fa != to) low[now] = min(low[now], dfn[to]); } low[fa] = min(low[fa], low[now]); } vector<int> edge[M]; void dfss(int start, int now) { belong[now] = start; for (auto x : edge[now]) { if (belong[x]) continue; dfss(start, x); } } void solve() { int n, m, V; cin >> n >> m; // vector<int> a(n + 2); // for (int i = 1; i <= n; i++) // cin >> a[i]; while (m--) { int x, y; cin >> x >> y; if (x == y) continue; add(x, y); add(y, x); } for (int i = 1; i <= n; ++i) if (!dfn[i]) dfs(i, i); vector<int> vis(c + 2); for (int now = 1; now <= n; ++now) { for (int i = head[now]; i; i = f[i].ne) { int to = f[i].to; if (low[to] > dfn[now]) vis[i] = 1; } } set<pair<int, int>> s; for (int i = 1; i <= c; i += 2) { int minn = min(f[i].from, f[i].to); int maxx = max(f[i].from, f[i].to); if ((vis[i] || vis[i + 1]) && s.find({minn, maxx}) == s.end()) // 如果这条边是桥,就跳过 { s.insert(make_pair(minn, maxx)); continue; } int x = f[i].from, y = f[i].to; edge[x].push_back(y); edge[y].push_back(x); } vector<vector<int>> f(n + 2); for (int i = 1; i <= n; ++i) { if (!belong[i]) dfss(i, i); } for (int i = 1; i <= n; ++i) f[belong[i]].push_back(i); int ans = 0; for (int i = 1; i <= n; ++i) { if (f[i].size() == 0) continue; ans++; } cout << ans << endl; for (int i = 1; i <= n; ++i) { if (f[i].size() == 0) continue; cout << f[i].size() << ' '; for (auto j : f[i]) { cout << j << ' '; } cout << endl; } } signed main() { ios::sync_with_stdio(false), cin.tie(0), cout.tie(0); int t = 1; // cin >> t; while (t--) solve(); return 0; }

