#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 100;
template <typename T>
inline T read() {
  T s = 0, f = 1;
  char ch = getchar();
  while (!isdigit(ch)) {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    s = (s << 3) + (s << 1) + ch - 48;
    ch = getchar();
  }
  return s * f;
}
set<int> st;
int vis[N];
int color[N];
vector<int> v[N], one[N];
int tot = 0;
int main() {
  int n = read<int>(), m = read<int>();
  for (int i = 1; i <= m; ++i) {
    int x = read<int>(), y = read<int>();
    one[x].push_back(y);
    one[y].push_back(x);
  }
  for (int i = 1; i <= n; ++i) {
    st.insert(i);
    sort(one[i].begin(), one[i].end());
    one[i].push_back(1e6);
  }
  queue<int> q;
  int ans = 0;
  for (int i = 1; i <= n; ++i) {
    if (vis[i]) continue;
    q.push(i);
    st.erase(i);
    ++ans;
    color[i] = ans;
    v[ans].push_back(i);
    while (!q.empty()) {
      int now = q.front();
      q.pop();
      if (vis[now]) continue;
      vis[now] = 1;
      for (auto it = st.begin(); it != st.end();) {
        if (vis[*it]) continue;
        auto item = lower_bound(one[now].begin(), one[now].end(), *it);
        if (item == one[i].end() || *item != *it) {
          color[*it] = color[now];
          v[color[now]].push_back(*it);
          q.push(*it);
          it = st.erase(it);
        } else
          ++it;
      }
    }
  }
  printf("%d\n", ans);
  for (int i = 1; i <= ans; ++i) {
    printf("%d", v[i].size());
    for (auto to : v[i]) {
      printf(" %d", to);
    }
    printf("\n");
  }
}
