use proconio::*;

struct SCCInternalGraph {
    start: Vec<usize>,
    elist: Vec<usize>,
}

impl SCCInternalGraph {
    fn build(n: usize, edge: &[(usize, usize)]) -> Self {
        let mut start = vec![0; n + 1];
        edge.iter().for_each(|&(s, _)| start[s + 1] += 1);
        for i in 1..=n {
            start[i] += start[i - 1];
        }
        let mut index = start.clone();
        let mut elist = vec![0; edge.len()];
        for &(s, t) in edge.iter() {
            elist[index[s]] = t;
            index[s] += 1;
        }
        SCCInternalGraph { start, elist }
    }
    fn neighbor(&self, v: usize) -> &[usize] {
        assert!(v + 1 < self.start.len());
        &self.elist[self.start[v]..self.start[v + 1]]
    }
}

struct SCCGraph {
    n: usize,
    edge: Vec<(usize, usize)>,
}

impl SCCGraph {
    fn new(n: usize) -> Self {
        Self { n, edge: vec![] }
    }
    fn add_edge(&mut self, a: usize, b: usize) {
        assert!(a < self.n);
        assert!(b < self.n);
        self.edge.push((a, b));
    }
    fn build(&self) -> Vec<usize> {
        let graph = SCCInternalGraph::build(self.n, &self.edge);
        let n = self.n;
        let mut ord = vec![n; n];
        let mut stack_s = vec![];
        let mut stack_p = vec![];
        let mut call = vec![];
        let mut ts = 0;
        let mut ids = vec![n; n];
        let mut gid = 0;
        enum Operation {
            Call(usize),
            Iter(usize, usize),
            Eval(usize),
        }
        for i in 0..n {
            if ord[i] != n {
                continue;
            }
            call.push(Operation::Call(i));
            while let Some(op) = call.pop() {
                match op {
                    Operation::Call(v) => {
                        ord[v] = ts;
                        ts += 1;
                        stack_s.push(v);
                        stack_p.push(v);
                        call.push(Operation::Eval(v));
                        call.push(Operation::Iter(v, 0));
                    }
                    Operation::Iter(v, k) => {
                        let g = graph.neighbor(v);
                        for i in k..g.len() {
                            let u = g[i];
                            if ord[u] == n {
                                call.push(Operation::Iter(v, i + 1));
                                call.push(Operation::Call(u));
                                break;
                            } else if ids[u] == n {
                                while ord[*stack_p.last().unwrap()] > ord[u] {
                                    stack_p.pop();
                                }
                            }
                        }
                    }
                    Operation::Eval(v) => {
                        if *stack_p.last().unwrap() == v {
                            while let Some(u) = stack_s.pop() {
                                ids[u] = gid;
                                // res[u] = gid;
                                // assigned[u] = true;
                                if u == v {
                                    break;
                                }
                            }
                            stack_p.pop();
                            gid += 1;
                        }
                    }
                }
            }
        }
        ids.iter_mut().for_each(|x| *x = gid - 1 - *x);
        ids
        // res.iter_mut().for_each(|v| *v = gid - 1 - *v);
        // res
    }
}

fn main() {
    input! {
    n: usize,
    m: usize,
    e: [(usize, usize); m],
    }
    let mut scc = SCCGraph::new(n);
    for (s, t) in e {
        scc.add_edge(s, t);
    }

    let ids = scc.build();

    let k = *ids.iter().max().unwrap() + 1;
    let mut node = vec![vec![]; k];
    for (i, &id) in ids.iter().enumerate() {
        node[id].push(i);
    }
    println!("{}", k);
    for i in 0..k {
        print!("{}", node[i].len());
        for j in &node[i] {
            print!(" {}", j);
        }
        println!();
    }

    // println!("{:?}", ids);
}


Measured memory_bytes: 50560