import sys

import numpy as np

import numba

from numba import njit, b1, i4, i8, f8



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



@njit((i8, i8[:, :], i8[:], i8[:], i8[:], i8[:], i8[:], i8, i8, i8, i8),

      cache=True)

def scc_dfs(N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v):

    low[v] = ord[v] = now_ord

    now_ord += 1

    visited[vis_i], vis_i = v, vis_i + 1

    for e in range(idx[v], idx[v + 1]):

        to = G[e, 1]

        if ord[to] == -1:

            now_ord, group_num, vis_i = \

                scc_dfs(N, G, idx, low, ord, ids,

                        visited, now_ord, group_num,

                        vis_i, to)

            low[v] = min(low[v], low[to])

        else:

            low[v] = min(low[v], ord[to])

    if low[v] == ord[v]:

        while True:

            u, vis_i = visited[vis_i - 1], vis_i - 1

            ord[u] = N

            ids[u] = group_num

            if u == v:

                break

        group_num += 1

    return now_ord, group_num, vis_i





@njit((i8, i8[:, :]), cache=True)

def scc(N, G):

    idx = np.searchsorted(G[:, 0], np.arange(N + 1))

    low = np.zeros(N, np.int64)

    ord = np.zeros(N, np.int64) - 1

    now_ord = 0

    group_num = 0

    visited, vis_i = np.empty(N, np.int64), 0

    ids = np.zeros(N, np.int64)

    for v in range(N):

        if ord[v] == -1:

            now_ord, group_num, vis_i = \

                scc_dfs(N, G, idx, low, ord, ids,

                        visited, now_ord, group_num,

                        vis_i, v)

    return group_num, group_num - ids - 1



def main(N, G):

    n_comp, comp = scc(N, G)

    ans = np.empty((N, 2), np.int64)

    ans[:, 0] = np.arange(N)

    ans[:, 1] = comp

    ans = ans[np.argsort(ans[:, 1])]

    idx = np.searchsorted(ans[:, 1], np.arange(n_comp + 1))

    print(n_comp)

    for c in range(n_comp):

        V = ans[idx[c]:idx[c + 1], 0]

        print(len(V), ' '.join(map(str, V)))



N, M = map(int, readline().split())

AB = np.array(read().split(), np.int64).reshape(-1, 2)



AB = AB[np.argsort(AB[:, 0])]



main(N, AB)

import sys

import numpy as np

import numba

from numba import njit, b1, i4, i8, f8



read = sys.stdin.buffer.read

readline = sys.stdin.buffer.readline

readlines = sys.stdin.buffer.readlines



@njit((i8, i8[:, :], i8[:], i8[:], i8[:], i8[:], i8[:], i8, i8, i8, i8),

      cache=True)

def scc_dfs(N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v):

    low[v] = ord[v] = now_ord

    now_ord += 1

    visited[vis_i], vis_i = v, vis_i + 1

    for e in range(idx[v], idx[v + 1]):

        to = G[e, 1]

        if ord[to] == -1:

            now_ord, group_num, vis_i = \

                scc_dfs(N, G, idx, low, ord, ids,

                        visited, now_ord, group_num,

                        vis_i, to)

            low[v] = min(low[v], low[to])

        else:

            low[v] = min(low[v], ord[to])

    if low[v] == ord[v]:

        while True:

            u, vis_i = visited[vis_i - 1], vis_i - 1

            ord[u] = N

            ids[u] = group_num

            if u == v:

                break

        group_num += 1

    return now_ord, group_num, vis_i





@njit((i8, i8[:, :]), cache=True)

def scc(N, G):

    idx = np.searchsorted(G[:, 0], np.arange(N + 1))

    low = np.zeros(N, np.int64)

    ord = np.zeros(N, np.int64) - 1

    now_ord = 0

    group_num = 0

    visited, vis_i = np.empty(N, np.int64), 0

    ids = np.zeros(N, np.int64)

    for v in range(N):

        if ord[v] == -1:

            now_ord, group_num, vis_i = \

                scc_dfs(N, G, idx, low, ord, ids,

                        visited, now_ord, group_num,

                        vis_i, v)

    return group_num, group_num - ids - 1



@njit((i8, i8[:, :]), cache=True)

def main(N, G):

    n_comp, comp = scc(N, G)

    ans = np.empty((N, 2), np.int64)

    ans[:, 0] = np.arange(N)

    ans[:, 1] = comp

    ans = ans[np.argsort(ans[:, 1])]

    idx = np.searchsorted(ans[:, 1], np.arange(n_comp + 1))

    print(n_comp)

    for c in range(n_comp):

        V = ans[idx[c]:idx[c + 1], 0]

        print(len(V))

        for v in V:

            print(v)



N, M = map(int, readline().split())

AB = np.array(read().split(), np.int64).reshape(-1, 2)



AB = AB[np.argsort(AB[:, 0])]



main(N, AB)

import sys
import numpy as np
import numba
from numba import njit, b1, i4, i8, f8

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


@njit((i8, i8[:, :], i8[:], i8[:], i8[:], i8[:], i8[:], i8, i8, i8, i8), cache=True)
def scc_dfs(N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v):
    low[v] = ord[v] = now_ord
    now_ord += 1
    visited[vis_i], vis_i = v, vis_i + 1
    for e in range(idx[v], idx[v + 1]):
        to = G[e, 1]
        if ord[to] == -1:
            now_ord, group_num, vis_i = scc_dfs(
                N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, to
            )
            low[v] = min(low[v], low[to])
        else:
            low[v] = min(low[v], ord[to])
    if low[v] == ord[v]:
        while True:
            u, vis_i = visited[vis_i - 1], vis_i - 1
            ord[u] = N
            ids[u] = group_num
            if u == v:
                break
        group_num += 1
    return now_ord, group_num, vis_i


@njit((i8, i8[:, :]), cache=True)
def scc(N, G):
    idx = np.searchsorted(G[:, 0], np.arange(N + 1))
    low = np.zeros(N, np.int64)
    ord = np.zeros(N, np.int64) - 1
    now_ord = 0
    group_num = 0
    visited, vis_i = np.empty(N, np.int64), 0
    ids = np.zeros(N, np.int64)
    for v in range(N):
        if ord[v] == -1:
            now_ord, group_num, vis_i = scc_dfs(
                N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v
            )
    return group_num, group_num - ids - 1


def main(N, G):
    n_comp, comp = scc(N, G)
    ans = np.empty((N, 2), np.int64)
    ans[:, 0] = np.arange(N)
    ans[:, 1] = comp
    ans = ans[np.argsort(ans[:, 1])]
    idx = np.searchsorted(ans[:, 1], np.arange(n_comp + 1))
    print(n_comp)
    for c in range(n_comp):
        V = ans[idx[c] : idx[c + 1], 0]
        print(len(V), " ".join(map(str, V)))


N, M = map(int, readline().split())
AB = np.array(read().split(), np.int64).reshape(-1, 2)
AB = AB[np.argsort(AB[:, 0])]
main(N, AB)

import sys
import numpy as np
import numba
from numba import njit, b1, i4, i8, f8

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


@njit((i8, i8[:, :], i8[:], i8[:], i8[:], i8[:], i8[:], i8, i8, i8, i8), cache=True)
def scc_dfs(N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v):
    low[v] = ord[v] = now_ord
    now_ord += 1
    visited[vis_i], vis_i = v, vis_i + 1
    for e in range(idx[v], idx[v + 1]):
        to = G[e, 1]
        if ord[to] == -1:
            now_ord, group_num, vis_i = scc_dfs(
                N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, to
            )
            low[v] = min(low[v], low[to])
        else:
            low[v] = min(low[v], ord[to])
    if low[v] == ord[v]:
        while True:
            u, vis_i = visited[vis_i - 1], vis_i - 1
            ord[u] = N
            ids[u] = group_num
            if u == v:
                break
        group_num += 1
    return now_ord, group_num, vis_i


@njit((i8, i8[:, :]), cache=True)
def scc(N, G):
    idx = np.searchsorted(G[:, 0], np.arange(N + 1))
    low = np.zeros(N, np.int64)
    ord = np.zeros(N, np.int64) - 1
    now_ord = 0
    group_num = 0
    visited, vis_i = np.empty(N, np.int64), 0
    ids = np.zeros(N, np.int64)
    for v in range(N):
        if ord[v] == -1:
            now_ord, group_num, vis_i = scc_dfs(
                N, G, idx, low, ord, ids, visited, now_ord, group_num, vis_i, v
            )
    return group_num, group_num - ids - 1


@njit((i8, i8[:, :]), cache=True)
def main(N, G):
    n_comp, comp = scc(N, G)
    ans = np.empty((N, 2), np.int64)
    ans[:, 0] = np.arange(N)
    ans[:, 1] = comp
    ans = ans[np.argsort(ans[:, 1])]
    idx = np.searchsorted(ans[:, 1], np.arange(n_comp + 1))
    print(n_comp)
    for c in range(n_comp):
        V = ans[idx[c] : idx[c + 1], 0]
        print(len(V))
        for v in V:
            print(v)


N, M = map(int, readline().split())
AB = np.array(read().split(), np.int64).reshape(-1, 2)
AB = AB[np.argsort(AB[:, 0])]
main(N, AB)

+@njit((i8, i8[:, :]), cache=True) -        print(len(V), " ".join(map(str, V))) +        print(len(V)) +        for v in V: +            print(v)