#include <bits/stdc++.h>   using namespace std;   vector<vector<int>> compos;   int complement_component(vector<vector<int>> &g) {     int n = g.size(), ans = 0;     set<int> S;     for (int i = 0; i < n; ++i) S.insert(i);     while (S.size()) {       ++ans;       int theCompo = 0;       queue<int> q;       q.push(*S.begin());       S.erase(S.begin());       compos.push_back(vector<int>{});       while (q.size()) {         int u = q.front();         q.pop();         compos.back().push_back(u);         if (g[u].size()) {           while (S.size() and *S.begin() < g[u][0]) {             q.push(*S.begin());             S.erase(S.begin());           }           int it = 0;           while (S.size() and it < g[u].size()) {             auto cur = S.upper_bound(g[u][it]);             while (cur != S.end() and                    (it + 1 == g[u].size() or *cur < g[u][it + 1])) {               q.push(*cur), S.erase(cur);               cur = S.upper_bound(g[u][it]);             }             ++it;           }         } else {           compos.back() = vector<int>(n);           iota(compos.back().begin(), compos.back().end(), 0);           return 1;         }       }     }     return ans;   }   int main() {     ios_base::sync_with_stdio(false);     cin.tie(0);     int N, M, u, v;     cin >> N >> M;     vector<vector<int>> g(N);     while (M--) {       cin >> u >> v, --u, --v;       g[u].push_back(v), g[v].push_back(u);     }     for (int i = 0; i < N; ++i) sort(g[i].begin(), g[i].end());     cout << complement_component(g) <<   n ;     sort(compos.begin(), compos.end());     for (auto &compo : compos) {       cout << compo.size() <<    ;       for (int i = 0; i < compo.size(); ++i)         cout << compo[i] + 1 <<    n [i == compo.size() - 1];     }   }   