#include <bits/stdc++.h>
using namespace std;
const int maxn = 500010;
int pa[maxn], sz[maxn];
vector<int> e[maxn];
set<int> grp, tmp;
map<int, int> lft;
int getpa(int u) { return u == pa[u] ? u : (pa[u] = getpa(pa[u])); }
int main() {
  int n, m;
  while (~scanf("%d%d", &n, &m)) {
    grp.clear();
    for (int i = 0; i < (n); ++i)
      pa[i] = i, sz[i] = 1, e[i].clear(), grp.insert(i);
    for (int i = 0; i < (m); ++i) {
      int a, b;
      scanf("%d%d", &a, &b);
      a--, b--;
      e[a].push_back(b), e[b].push_back(a);
    }
    for (int i = 0; i < (n); ++i) {
      sort(e[i].begin(), e[i].end());
      e[i].resize(unique(e[i].begin(), e[i].end()) - e[i].begin());
    }
    for (int i = 0; i < (n); ++i) {
      lft.clear();
      for (int j = 0; j < (e[i].size()); ++j) lft[getpa(e[i][j])]++;
      tmp = grp;
      for (typeof((grp).begin()) it = (grp).begin(); it != (grp).end(); ++it)
        if (tmp.find(*it) != tmp.end() && lft[*it] < sz[*it]) {
          int p1 = getpa(i), p2 = *it;
          if (p1 != p2) {
            sz[p1] += sz[p2], pa[p2] = p1;
            tmp.erase(p2);
          }
        }
      grp = tmp;
    }
    for (int i = 0; i < (n); ++i) e[i].clear();
    int tot = 0;
    for (int i = 0; i < (n); ++i) {
      e[getpa(i)].push_back(i);
      if (getpa(i) == i) tot++;
    }
    printf("%d\n", tot);
    for (int i = 0; i < (n); ++i)
      if (e[i].size() > 0) {
        sort(e[i].begin(), e[i].end());
        printf("%d", e[i].size());
        for (int j = 0; j < (e[i].size()); ++j) printf(" %d", e[i][j] + 1);
        puts("");
      }
  }
  return 0;
}
