#include <bits/stdc++.h>
using namespace std;
const int MAXN = 500010;
const int inf = (1 << 30);
int n, m;
vector<int> adj[MAXN];
int p[MAXN], cmpn[MAXN];
int find(int i) { return p[i] == i ? i : p[i] = find(p[i]); }
void merge(int u, int v) {
  u = find(u);
  v = find(v);
  p[u] = v;
}
vector<int> ans[MAXN];
bool check(int u, int v) {
  int lo = 0, hi = (int)adj[u].size() - 1;
  while (lo < hi && lo < adj[u].size()) {
    int mid = lo + (hi - lo) / 2;
    if (adj[u][mid] >= v) {
      hi = mid;
    } else {
      lo = mid + 1;
    }
  }
  if (lo == hi && lo >= 0 && lo < adj[u].size() && adj[u][lo] == v) {
    return true;
  }
  return false;
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) {
    sort(adj[i].begin(), adj[i].end());
    p[i] = i;
  }
  set<int> s;
  for (int i = 1; i <= n; i++) {
    s.insert(i);
  }
  while (!s.empty()) {
    queue<int> q;
    q.push(*s.begin());
    s.erase(s.begin());
    while (!q.empty()) {
      int u = q.front();
      q.pop();
      for (set<int>::iterator it = s.begin(); it != s.end();) {
        if (check(u, *it)) {
          it++;
          continue;
        }
        q.push(*it);
        merge(u, *it);
        s.erase(it++);
      }
    }
  }
  int sze = 0;
  for (int i = 1; i <= n; i++) {
    int u = find(i);
    if (ans[u].size() == 0) sze++;
    ans[u].push_back(i);
  }
  printf("%d\n", sze);
  for (int i = 1; i <= n; i++) {
    if (ans[i].size() > 0) {
      printf("%d", ans[i].size());
      for (int j = 0; j < ans[i].size(); j++) {
        printf(" %d", ans[i][j]);
      }
      printf("\n");
    }
  }
}
