#include <bits/stdc++.h>
using namespace std;
const int Distance[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
const int Nmax = 500100;
int n, m;
vector<vector<int> > g;
queue<int> que;
set<int> unUsed;
int d[Nmax];
inline void add(int vertex, int color) {
  d[vertex] = color;
  unUsed.erase(vertex);
  que.push(vertex);
}
inline int componentCount() {
  for (int i = 1; i <= n; i++) {
    d[i] = 0;
    unUsed.insert(i);
  }
  int comps = 0;
  for (int vv = 1; vv <= n; vv++) {
    if (d[vv] > 0) continue;
    add(vv, ++comps);
    while (!que.empty()) {
      int vertex = que.front();
      que.pop();
      int i = 0;
      vector<int> good;
      for (set<int>::iterator it = unUsed.begin(); it != unUsed.end(); it++) {
        int u = *it;
        assert(d[u] == 0);
        while (i < g[vertex].size() && g[vertex][i] < u) i++;
        if (i == g[vertex].size() || g[vertex][i] != u) good.push_back(u);
      }
      for (int i = 0; i < good.size(); i++) add(good[i], d[vertex]);
    }
  }
  return comps;
}
int main() {
  ios_base::sync_with_stdio(0);
  scanf("%d %d", &n, &m);
  g.resize(n + 1);
  for (int i = 1; i <= m; i++) {
    int x, y;
    scanf("%d %d", &x, &y);
    g[x].push_back(y);
    g[y].push_back(x);
  }
  for (int i = 1; i <= n; i++) sort(g[i].begin(), g[i].end());
  int comps = componentCount();
  printf("%d\n", comps);
  g.resize(0);
  g.resize(n + 1);
  for (int i = 1; i <= n; i++) g[d[i]].push_back(i);
  for (int i = 1; i <= comps; i++) {
    printf("%d", (int)g[i].size());
    for (int j = 0; j < g[i].size(); j++) printf(" %d", g[i][j]);
    printf("\n");
  }
  return 0;
}
