#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];
  }
}
