#include <iostream>
#include <vector>
#include <stack>
#include <fstream>
#include <algorithm>
#include <cstdio>
using namespace std;
/*ifstream be("lab1_4_1.in");
ofstream ki("lab1_4_1.out");*/
FILE* be;
FILE* ki;
void beolvas(vector<vector<int>>& graf, int n, int m);
void tarjan(vector<vector<int>>& graf, int n);
void dfs_scc(vector<vector<int>>& graf, vector<int>& belep, vector<bool>& vermen, vector<int> &low, stack<int> &verem, vector<vector<int>> &komponensek, int &komponens, int &ido, int v);
int main(){
be = fopen("ctc.in", "r");
ki = fopen("ctc.out", "w");
int n, m;
//be >> n >> m;
fscanf(be,"%d%d", &n, &m);
vector<vector<int>> graf(n);
beolvas(graf, n, m);
tarjan(graf, n);
fclose(be);
fclose(ki);
}
void beolvas(vector<vector<int>>& graf, int n, int m) {
for (int i = 0; i < m; i++) {
int x, y;
fscanf(be, "%d%d", &x, &y);
//be >> x >> y;
graf[x - 1].push_back(y - 1);
}
}
void tarjan(vector<vector<int>>& graf, int n) {
vector<int> belep(n, -1);
vector<bool> vermen(n, false);
vector<int> low(n, -1);
stack<int> verem;
vector<vector<int>> komponensek;
int ido = 0;
int komponens = 0;
for(int i = 0; i < n; i++)
if(belep[i] == -1) dfs_scc(graf, belep, vermen, low, verem, komponensek, komponens, ido, i);
//ki << komponens << endl;
fprintf(ki, "%d\n", komponens);
for (int i = komponensek.size()-1; i >= 0 ; i--) {
for (int j = komponensek[i].size() - 1; j >= 0; j--)
fprintf(ki, "%d ", komponensek[i][j] + 1);
//ki << komponensek[i][j] + 1 << " ";
fprintf(ki, "\n");
//ki << endl;
}
}
void dfs_scc(vector<vector<int>>& graf, vector<int>& belep, vector<bool>& vermen, vector<int>& low, stack<int>& verem, vector<vector<int>>& komponensek, int& komponens, int& ido, int v) {
ido++;
belep[v] = ido;
low[v] = ido;
vermen[v] = true;
verem.push(v);
for (int i : graf[v]) {
if (belep[i] == -1) {
dfs_scc(graf, belep, vermen, low, verem, komponensek, komponens, ido, i);
low[v] = min(low[v], low[i]);
}
else if ((belep[i] < belep[v]) && vermen[i]) {
low[v] = min(low[v], belep[i]);
}
}
if (low[v] == belep[v]) {
komponens++;
komponensek.resize(komponens);
while (!verem.empty() && (belep[verem.top()] >= belep[v])) {
komponensek[komponens - 1].push_back(verem.top());
vermen[verem.top()] = false;
verem.pop();
}
}
}