#include <bits/stdc++.h>
using namespace std;
int n, m;
set<int> s;
const int nax = 5e5 + 4;
int link[nax];
set<pair<int, int>> edge;
vector<vector<int>> group;
inline void make_set(int i) { link[i] = i; }
int Find(int a) {
  if (link[a] == a) return a;
  return (link[a] = Find(link[a]));
}
void Unite(int a, int b) {
  a = Find(a);
  b = Find(b);
  if (a == b) return;
  link[a] = b;
}
int component() {
  set<int> had;
  for (int i = 1; i <= n; ++i) {
    had.insert(Find(i));
    group[Find(i)].push_back(i);
  }
  return ((int)had.size());
}
void bfs(int i) {
  queue<int> q;
  q.push(i);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    s.erase(u);
    vector<int> temp;
    for (auto &c : s) {
      if (edge.find({min(u, c), max(u, c)}) == edge.end()) {
        Unite(u, c);
        q.push(c);
        temp.push_back(c);
      }
    }
    for (auto &c : temp) s.erase(c);
  }
}
void solve() {
  cin >> n >> m;
  group.resize(n + 1);
  for (int i = 1; i <= m; ++i) {
    int u, v;
    cin >> u >> v;
    edge.insert({min(u, v), max(u, v)});
  }
  for (int i = 1; i <= n; ++i) make_set(i);
  for (int i = 1; i <= n; ++i) s.insert(i);
  for (int i = 1; i <= n; ++i) {
    if (s.find(i) != s.end()) bfs(i);
  }
  cout << component() << '\n';
  for (int i = 1; i <= n; ++i) {
    if (!group[i].empty()) {
      cout << group[i].size() << ' ';
      for (auto &c : group[i]) cout << c << ' ';
      cout << '\n';
    }
  }
}
signed main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int t = 1;
  while (t--) {
    solve();
  }
}
