#include <bits/stdc++.h>
using namespace std;
const int maxn = 500 * 1000 + 10, maxm = (1 << 17), mod = (int)1e9 + 7,
          hash = 7000001, inf = (1 << 29);
const double pi = 3.14159265359, ee = 2.71828;
struct node {
  int par, sz;
  bool mark;
  vector<int> g;
} v[maxn];
vector<int> comp[maxn];
set<int> ch;
int father(int u) {
  if (v[u].par == -1) return u;
  return v[u].par = father(v[u].par);
}
void merge(int a, int b) {
  a = father(a), b = father(b);
  if (a == b) return;
  if (v[a].sz < v[b].sz) swap(a, b);
  v[a].sz += v[b].sz, v[b].par = a;
}
int main() {
  ios::sync_with_stdio(0);
  int n, m, u = 0, a, b, c;
  cin >> n >> m;
  for (int i = 0; i < n; i++) v[i].par = -1, v[i].sz = 1;
  for (int i = 0; i < m; i++)
    cin >> a >> b, a--, b--, v[a].g.push_back(b), v[b].g.push_back(a);
  for (int i = 0; i < n; i++) {
    if (v[i].g.size() < v[u].g.size()) u = i;
    sort(v[i].g.begin(), v[i].g.end());
  }
  for (int i = 0; i < v[u].g.size(); i++) v[v[u].g[i]].mark = 1;
  for (int i = 0; i < n; i++)
    if (!v[i].mark && u != i) merge(i, u);
  for (int i = 0; i < v[u].g.size(); i++) {
    a = v[u].g[i], c = v[a].g.size();
    for (int j = 0; j < v[a].g.size(); j++)
      if (v[v[a].g[j]].mark) c--;
    if (c < n - v[u].g.size()) merge(u, a);
    for (int j = i + 1; j < v[u].g.size(); j++) {
      b = v[u].g[j];
      c = lower_bound(v[a].g.begin(), v[a].g.end(), b) - v[a].g.begin();
      if (c == v[a].g.size())
        merge(a, b);
      else if (v[a].g[c] != b)
        merge(a, b);
    }
  }
  for (int i = 0; i < n; i++)
    a = father(i), comp[a].push_back(i + 1), ch.insert(a);
  cout << ch.size() << endl;
  while (ch.size()) {
    u = *ch.begin(), ch.erase(ch.begin());
    cout << comp[u].size() << " ";
    for (int i = 0; i < comp[u].size(); i++) cout << comp[u][i] << " ";
    cout << endl;
  }
  return 0;
}
