#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 10;
const int maxn5 = 5e5 + 10;
const int maxnt = 1.2e6 + 10;
const int maxn3 = 1e3 + 10;
const long long mod = 1e9 + 7;
const long long inf = 2e18;
int st, cmp[maxn5], nxt[maxn5], pre[maxn5];
vector<int> adj[maxn5], ver[maxn5];
bool mark[maxn5];
void join(int a, int b) {
  if (ver[a].size() > ver[b].size()) swap(a, b);
  for (auto u : ver[a]) {
    cmp[u] = b;
    ver[b].push_back(u);
  }
  if (a == st) {
    st = nxt[a];
    pre[nxt[a]] = -1;
  } else {
    if (nxt[a] != -1) pre[nxt[a]] = pre[a];
    nxt[pre[a]] = nxt[a];
  }
  ver[a].clear();
  return;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < m; i++) {
    int a, b;
    cin >> a >> b;
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  for (int i = 1; i <= n; i++) {
    cmp[i] = i;
    ver[i].push_back(i);
    pre[i] = i == 1 ? -1 : i - 1;
    nxt[i] = i == n ? -1 : i + 1;
  }
  st = 1;
  for (int i = 1; i <= n; i++) {
    int ind = st;
    for (auto u : adj[i]) mark[u] = true;
    while (ind != -1) {
      if (ind == cmp[i]) {
        ind = nxt[ind];
        continue;
      }
      bool done = false;
      for (auto u : ver[ind])
        if (!mark[u]) {
          int c = ind;
          ind = nxt[ind];
          done = true;
          join(c, cmp[i]);
          break;
        }
      if (!done) ind = nxt[ind];
    }
    for (auto u : adj[i]) mark[u] = false;
  }
  int cnt = 0, ind = st;
  while (ind != -1) {
    cnt++;
    ind = nxt[ind];
  }
  cout << cnt << '\n';
  while (st != -1) {
    cout << ver[st].size() << ' ';
    for (auto u : ver[st]) cout << u << ' ';
    cout << '\n';
    st = nxt[st];
  }
  return 0;
}
