#include <vector>
#include <iostream>
#include <fstream>
#include <stack>
#include <string.h>
using namespace std;
ifstream f("ctc.in");
ofstream g("ctc.out");
vector <int> graf1[100001], graf2[100001], componente[100001];
int vizitat[100001], nr, n, m;
stack<int> s;
void citire() {
int x, y;
f >> n >> m;
for(int i = 1; i <= m; i++) {
f >> x >> y;
graf1[x].push_back(y);
graf2[y].push_back(x);
}
}
int DFS1(int nod) {
vizitat[nod] = 1;
for(int i=0; i < graf1[nod].size(); i++)
if(vizitat[graf1[nod][i]] == 0)
DFS1(graf1[nod][i]);
s.push(nod);
}
int DFS2(int nod) {
vizitat[nod] = 1;
componente[nr].push_back(nod);
for(int i=0; i < graf2[nod].size(); i++)
if(vizitat[graf2[nod][i]] == 0)
DFS2(graf2[nod][i]);
}
void afisare() {
g << nr << "\n";
for(int i = 1; i <= nr; i++) {
for(int j = 0; j < componente[i].size(); j++)
g << componente[i][j] <<" ";
g << "\n";
}
}
int main() {
citire();
for(int i = 1; i <= n; i++)
if(vizitat[i] == 0)
DFS1(i);
memset(vizitat, 0, sizeof(vizitat));
while(s.empty() == 0) {
if(vizitat[s.top()] == 0) {
nr++;
DFS2(s.top());
}
s.pop();
}
afisare();
return 0;
}