def StrongConnectedComponent(g,S):

    from collections import deque

    S = deque() #逆辺で帰りがけが遅い順にpopされるスタック

    #まず逆辺でDFS、帰りがけに S に積む

    q = deque()

    n = len(g)

    gp = [1]*n # 1 -> 0 -> -1

    for i in range(n):

        if gp[i] == 1:

            q.append(i)

            while q:

                v = q.pop()

                #帰りがけ

                if v < 0:

                    if gp[~v] == 0:

                        gp[~v] = -1

                        S.append(~v)

                #未処理

                elif gp[v] == 1:

                    q.append(~v)

                    gp[v] = 0

                    for c in rg[v]:

                        # 子が未処理

                        if gp[c] == 1:

                            q.append(c)

    q = deque()

    gp = [-1]*n

    # Sのpop順にDFS

    #この段階で gp = [-1]*n（使いまわす）

    g_scc = []

    cnt = 0

    while S:

        v = S.pop()

        if gp[v] == -1:

            q.append(v)

            gp[v] = cnt

            sv = set()

            while q:

                w = q.pop()

                for c in g[w]:

                    if gp[c] == -1:

                        q.append(c)

                        gp[c] = gp[w]

                    elif gp[c] != cnt:

                        sv.add(gp[c])

            cnt += 1

            g_scc.append(sv)



    return gp, g_scc



###########################################################################                        

###########################################################################                        



# coding: utf-8

# Your code here!

import sys

readline = sys.stdin.readline

read = sys.stdin.read



#n,*w = [int(i) for i in read().split()]



n,m = [int(i) for i in readline().split()]



g = [[] for _ in range(n)]

rg = [[] for _ in range(n)]

for _ in range(m):

    a,b = map(int, readline().split())

    g[a].append(b)

    rg[b].append(a)







gp, scc = StrongConnectedComponent(g,rg)



#print(gp)

#print(scc)





v = max(gp)+1

ans = [[] for _ in range(v)]

for i, gpi in enumerate(gp):

    ans[gpi].append(i)



print(v)

for lst in ans[::-1]:

    print(len(lst), end=" ")

    print(*lst)

def SCC_Tarjan(g):

    def dfs(v):

        nonlocal idx

        used[v] = 1

        pre[v] = low[v] = idx

        idx += 1

        S.append(v)

        onS[v] = 1

        for c in g[v]:

            if not used[c]:

                dfs(c)

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

            elif onS[c]:

                low[v] = min(low[v], pre[c])

        used[v] = 2



        if low[v] == pre[v]:

            cc = []

            while True:

                w = S.pop()

                onS[w] = 0

                cc.append(w)

                if w==v: break

            scc.append(cc)





    n = len(g)

    used = [0]*n # 0 -> 1 -> 2

    pre = [0]*n

    low = [0]*n

    onS = [0]*n

    idx = 0

    S = []

    scc = []

    for i in range(n):

        if not used[i]:

            dfs(i)

    #print(g)    

    #print("idx",pre)

    #print("low",low)

    #print(scc)

        

    return scc



###########################################################################                        

###########################################################################                        



# coding: utf-8

# Your code here!

import sys

readline = sys.stdin.readline

read = sys.stdin.read

sys.setrecursionlimit(10**6)

#n,*w = [int(i) for i in read().split()]



n,m = [int(i) for i in readline().split()]



g = [[] for _ in range(n)]

for _ in range(m):

    a,b = list(map(int, readline().split()))

    g[a].append(b)



gp = SCC_Tarjan(g)

print((len(gp)))

for lst in gp[::-1]:

    print((*([len(lst)]+lst)))



def StrongConnectedComponent(g, S):
    from collections import deque

    S = deque()  # 逆辺で帰りがけが遅い順にpopされるスタック
    # まず逆辺でDFS、帰りがけに S に積む
    q = deque()
    n = len(g)
    gp = [1] * n  # 1 -> 0 -> -1
    for i in range(n):
        if gp[i] == 1:
            q.append(i)
            while q:
                v = q.pop()
                # 帰りがけ
                if v < 0:
                    if gp[~v] == 0:
                        gp[~v] = -1
                        S.append(~v)
                # 未処理
                elif gp[v] == 1:
                    q.append(~v)
                    gp[v] = 0
                    for c in rg[v]:
                        # 子が未処理
                        if gp[c] == 1:
                            q.append(c)
    q = deque()
    gp = [-1] * n
    # Sのpop順にDFS
    # この段階で gp = [-1]*n（使いまわす）
    g_scc = []
    cnt = 0
    while S:
        v = S.pop()
        if gp[v] == -1:
            q.append(v)
            gp[v] = cnt
            sv = set()
            while q:
                w = q.pop()
                for c in g[w]:
                    if gp[c] == -1:
                        q.append(c)
                        gp[c] = gp[w]
                    elif gp[c] != cnt:
                        sv.add(gp[c])
            cnt += 1
            g_scc.append(sv)
    return gp, g_scc


###########################################################################
###########################################################################
# coding: utf-8
# Your code here!
import sys

readline = sys.stdin.readline
read = sys.stdin.read
# n,*w = [int(i) for i in read().split()]
n, m = [int(i) for i in readline().split()]
g = [[] for _ in range(n)]
rg = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, readline().split())
    g[a].append(b)
    rg[b].append(a)
gp, scc = StrongConnectedComponent(g, rg)
# print(gp)
# print(scc)
v = max(gp) + 1
ans = [[] for _ in range(v)]
for i, gpi in enumerate(gp):
    ans[gpi].append(i)
print(v)
for lst in ans[::-1]:
    print(len(lst), end=" ")
    print(*lst)

def SCC_Tarjan(g):
    def dfs(v):
        nonlocal idx
        used[v] = 1
        pre[v] = low[v] = idx
        idx += 1
        S.append(v)
        onS[v] = 1
        for c in g[v]:
            if not used[c]:
                dfs(c)
                low[v] = min(low[v], low[c])
            elif onS[c]:
                low[v] = min(low[v], pre[c])
        used[v] = 2
        if low[v] == pre[v]:
            cc = []
            while True:
                w = S.pop()
                onS[w] = 0
                cc.append(w)
                if w == v:
                    break
            scc.append(cc)

    n = len(g)
    used = [0] * n  # 0 -> 1 -> 2
    pre = [0] * n
    low = [0] * n
    onS = [0] * n
    idx = 0
    S = []
    scc = []
    for i in range(n):
        if not used[i]:
            dfs(i)
    # print(g)
    # print("idx",pre)
    # print("low",low)
    # print(scc)
    return scc


###########################################################################
###########################################################################
# coding: utf-8
# Your code here!
import sys

readline = sys.stdin.readline
read = sys.stdin.read
sys.setrecursionlimit(10**6)
# n,*w = [int(i) for i in read().split()]
n, m = [int(i) for i in readline().split()]
g = [[] for _ in range(n)]
for _ in range(m):
    a, b = list(map(int, readline().split()))
    g[a].append(b)
gp = SCC_Tarjan(g)
print((len(gp)))
for lst in gp[::-1]:
    print((*([len(lst)] + lst)))

-def StrongConnectedComponent(g, S): -    from collections import deque +def SCC_Tarjan(g): +    def dfs(v): +        nonlocal idx +        used[v] = 1 +        pre[v] = low[v] = idx +        idx += 1 +        S.append(v) +        onS[v] = 1 +        for c in g[v]: +            if not used[c]: +                dfs(c) +                low[v] = min(low[v], low[c]) +            elif onS[c]: +                low[v] = min(low[v], pre[c]) +        used[v] = 2 +        if low[v] == pre[v]: +            cc = [] +            while True: +                w = S.pop() +                onS[w] = 0 +                cc.append(w) +                if w == v: +                    break +            scc.append(cc) -    S = deque()  # 逆辺で帰りがけが遅い順にpopされるスタック -    # まず逆辺でDFS、帰りがけに S に積む -    q = deque() -    gp = [1] * n  # 1 -> 0 -> -1 +    used = [0] * n  # 0 -> 1 -> 2 +    pre = [0] * n +    low = [0] * n +    onS = [0] * n +    idx = 0 +    S = [] +    scc = [] -        if gp[i] == 1: -            q.append(i) -            while q: -                v = q.pop() -                # 帰りがけ -                if v < 0: -                    if gp[~v] == 0: -                        gp[~v] = -1 -                        S.append(~v) -                # 未処理 -                elif gp[v] == 1: -                    q.append(~v) -                    gp[v] = 0 -                    for c in rg[v]: -                        # 子が未処理 -                        if gp[c] == 1: -                            q.append(c) -    q = deque() -    gp = [-1] * n -    # Sのpop順にDFS -    # この段階で gp = [-1]*n（使いまわす） -    g_scc = [] -    cnt = 0 -    while S: -        v = S.pop() -        if gp[v] == -1: -            q.append(v) -            gp[v] = cnt -            sv = set() -            while q: -                w = q.pop() -                for c in g[w]: -                    if gp[c] == -1: -                        q.append(c) -                        gp[c] = gp[w] -                    elif gp[c] != cnt: -                        sv.add(gp[c]) -            cnt += 1 -            g_scc.append(sv) -    return gp, g_scc +        if not used[i]: +            dfs(i) +    # print(g) +    # print("idx",pre) +    # print("low",low) +    # print(scc) +    return scc +sys.setrecursionlimit(10**6) -rg = [[] for _ in range(n)] -    a, b = map(int, readline().split()) +    a, b = list(map(int, readline().split())) -    rg[b].append(a) -gp, scc = StrongConnectedComponent(g, rg) -# print(gp) -# print(scc) -v = max(gp) + 1 -ans = [[] for _ in range(v)] -for i, gpi in enumerate(gp): -    ans[gpi].append(i) -print(v) -for lst in ans[::-1]: -    print(len(lst), end=" ") -    print(*lst) +gp = SCC_Tarjan(g) +print((len(gp))) +for lst in gp[::-1]: +    print((*([len(lst)] + lst)))