#include <bits/stdc++.h>
using namespace std;
ifstream fin("ctc.in");
ofstream fout("ctc.out");
int n, m;
int low[100005], tmp[100005], scc[100005], idx, compCnt;
vector<int> g[100005];
vector<vector<int> > ctc;
stack<int> stk;
void tarjan(int x) {
stk.push(x);
low[x] = tmp[x] = ++idx;
for(auto next: g[x]) {
if(!tmp[next]) { // next hasnt been visited yet => it is a child of x
tarjan(next);
low[x] = min(low[x], low[next]);
} else if(scc[next] == 0) { // it wasnt assigned to a scc => it is an ancestor whose level may improve low[x]
low[x] = min(low[x], tmp[next]);
}
}
// if we didn't find low improvements
// pop everything from the stack and create a new scc
if(low[x] == tmp[x]) {
compCnt ++;
ctc.push_back({});
while(!stk.empty()) {
int nx = stk.top();
stk.pop();
ctc.back().push_back(nx);
scc[nx] = compCnt;
if(nx == x) break;
}
}
}
int main() {
fin >> n >> m;
while(m--) {
int a, b;
fin >> a >> b;
g[a].push_back(b);
}
for(int i = 1; i <= n; i++)
if(!scc[i]) tarjan(i);
fout << ctc.size() << '\n';
for(auto x: ctc) {
for(auto y: x) fout << y << ' ';
fout << '\n';
}
}