#include <vector>

struct strongly_connected_componects {
  int n;
  std::vector<std::vector<int>> G;
  std::vector<std::vector<int>> scc;
  std::vector<int> low;
  std::vector<int> num;
  std::vector<int> st;
  std::vector<bool> in_st;
  int cnt;

  strongly_connected_componects(int n):
    n(n), G(n) {}

  void add_edge(int a, int b) {
    G[a].emplace_back(b);
  }

  void visit(int v) {
    low[v] = num[v] = ++cnt;
    st.emplace_back(v);
    in_st[v] = true;

    for(auto t: G[v]) {
      if(num[t] == 0) {
        visit(t);
        low[v] = std::min(low[v], low[t]);
      }
      else if(in_st[t]) {
        low[v] = std::min(low[v], num[t]);
      }
    }

    if(low[v] == num[v]) {
      std::vector<int> vs;
      while(true) {
        int t = st.back();
        st.pop_back();
        in_st[t] = false;
        vs.emplace_back(t);
        if(v == t) break;
      }
      scc.emplace_back(std::move(vs));
    }
  }

  void build_scc() {
    low.assign(n, 0);
    num.assign(n, 0);
    st.reserve(n);
    in_st.assign(n, false);
    cnt = 0;
    for(int i = 0;i < n;i++) {
      if(num[i] == 0) {
        visit(i);
      }
    }
  }
};


#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i,s,e) for(i64 (i) = (s);(i) < (e);(i)++)
#define all(x) x.begin(),x.end()
#define STRINGIFY(n) #n
#define TOSTRING(n) STRINGIFY(n)
#define PREFIX "#" TOSTRING(__LINE__) "| "
#define debug(x) \
{ \
  std::cout << PREFIX << #x << " = " << x << std::endl; \
}

std::ostream& output_indent(std::ostream& os, int ind) {
  for(int i = 0; i < ind; i++) os << " ";
  return os;
}

template<class S, class T> std::ostream& operator<<(std::ostream& os, const std::pair<S, T>& p);
template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v);

template<class S, class T> std::ostream& operator<<(std::ostream& os, const std::pair<S, T>& p) {
  return (os << "(" << p.first << ", " << p.second << ")");
}
template<class T> std::ostream& operator<<(std::ostream& os, const std::vector<T>& v) {
  os << "[";
  for(int i = 0;i < v.size();i++) os << v[i] << ", ";
  return (os << "]");
}

template<class T>
static inline std::vector<T> ndvec(size_t&& n, T val) { return std::vector<T>(n, std::forward<T>(val)); }
template<class... Tail>
static inline auto ndvec(size_t&& n, Tail&&... tail) {
  return std::vector<decltype(ndvec(std::forward<Tail>(tail)...))>(n, ndvec(std::forward<Tail>(tail)...));
}
template<class Cond> struct chain {
  Cond cond; chain(Cond cond) : cond(cond) {}
  template<class T> bool operator()(T& a, const T& b) const { if(cond(a, b)) { a = b; return true; } return false; }
};
template<class Cond> chain<Cond> make_chain(Cond cond) { return chain<Cond>(cond); }


int main() {
  std::cin.tie(nullptr);
  std::ios::sync_with_stdio(false);
  int N, M;
  cin >> N >> M;
  strongly_connected_componects scc(N);
  rep(i,0,M) {
    int a, b;
    cin >> a >> b;
    scc.add_edge(a, b);
  }

  scc.build_scc();
  std::reverse(all(scc.scc));
  cout << scc.scc.size() << '\n';
  for(const auto& v: scc.scc) {
    cout << v.size();
    for(int i = 0;i < v.size(); i++) {
      cout << ' ' << v[i];
    }
    cout << '\n';
  }
}


Measured memory_bytes: 57940