def SCC_Tarjan(g):

    def dfs(v):

        nonlocal idx

        pre[v] = low[v] = idx

        idx += 1

        S.append(v)

        #onS[v] = 1

        for c in g[v]:

            if pre[c] == -1: 

                dfs(c)

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

            #elif onS[c]:

            else:

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



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

            cc = []

            while True:

                w = S.pop()

                #onS[w] = 0

                pre[w] = n

                cc.append(w)

                if w==v: break

            scc.append(cc)





    n = len(g)

    pre = [-1]*n # 負なら未処理、[0,n) ならpre-order, n ならvisited

    low = [0]*n

    onS = [0]*n

    idx = 0

    S = []

    scc = []

    for i in range(n):

        if pre[i] == -1:

            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 SCC_Tarjan(g):

    n = len(g)

    order = [-1]*n # 負なら未処理、[0,n) ならpre-order, n ならvisited

    low = [0]*n

    ord_now = 0

    parent = [-1]*n

    gp = [0]*n

    gp_num = 0

    S = []

    q = []

    for i in range(n):

        if order[i] == -1:

            q.append(i)

            while q:

                v = q.pop()

                if v >= 0:

                    if order[v] != -1: continue

                    order[v] = low[v] = ord_now

                    ord_now += 1

                    S.append(v)

                    q.append(~v)

                    for c in g[v]:

                        if order[c] == -1: 

                            q.append(c)

                            parent[c] = v

                        else:

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

                else:

                    v = ~v

                    if parent[v] != -1:

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

                    if low[v] == order[v]:

                        while True:

                            w = S.pop()

                            order[w] = n

                            gp[w] = gp_num

                            if w==v: break

                        gp_num += 1





    scc = [[] for _ in range(gp_num)]

    for i in range(n):

        gp[i] = gp_num-gp[i]-1

        scc[gp[i]].append(i)

    

    #print(gp)

    return scc



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

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



# coding: utf-8

# Your code here!

import sys

readline = sys.stdin.readline

read = sys.stdin.read



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)



scc = SCC_Tarjan(g)

print((len(scc)))

for lst in scc:

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



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

    n = len(g)
    pre = [-1] * n  # 負なら未処理、[0,n) ならpre-order, n ならvisited
    low = [0] * n
    onS = [0] * n
    idx = 0
    S = []
    scc = []
    for i in range(n):
        if pre[i] == -1:
            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 SCC_Tarjan(g):
    n = len(g)
    order = [-1] * n  # 負なら未処理、[0,n) ならpre-order, n ならvisited
    low = [0] * n
    ord_now = 0
    parent = [-1] * n
    gp = [0] * n
    gp_num = 0
    S = []
    q = []
    for i in range(n):
        if order[i] == -1:
            q.append(i)
            while q:
                v = q.pop()
                if v >= 0:
                    if order[v] != -1:
                        continue
                    order[v] = low[v] = ord_now
                    ord_now += 1
                    S.append(v)
                    q.append(~v)
                    for c in g[v]:
                        if order[c] == -1:
                            q.append(c)
                            parent[c] = v
                        else:
                            low[v] = min(low[v], order[c])
                else:
                    v = ~v
                    if parent[v] != -1:
                        low[parent[v]] = min(low[parent[v]], low[v])
                    if low[v] == order[v]:
                        while True:
                            w = S.pop()
                            order[w] = n
                            gp[w] = gp_num
                            if w == v:
                                break
                        gp_num += 1
    scc = [[] for _ in range(gp_num)]
    for i in range(n):
        gp[i] = gp_num - gp[i] - 1
        scc[gp[i]].append(i)
    # print(gp)
    return scc


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

readline = sys.stdin.readline
read = sys.stdin.read
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)
scc = SCC_Tarjan(g)
print((len(scc)))
for lst in scc:
    print((*([len(lst)] + lst)))

-    def dfs(v): -        nonlocal idx -        pre[v] = low[v] = idx -        idx += 1 -        S.append(v) -        # onS[v] = 1 -        for c in g[v]: -            if pre[c] == -1: -                dfs(c) -                low[v] = min(low[v], low[c]) -            # elif onS[c]: -            else: -                low[v] = min(low[v], pre[c]) -        if low[v] == pre[v]: -            cc = [] -            while True: -                w = S.pop() -                # onS[w] = 0 -                pre[w] = n -                cc.append(w) -                if w == v: -                    break -            scc.append(cc) - -    pre = [-1] * n  # 負なら未処理、[0,n) ならpre-order, n ならvisited +    order = [-1] * n  # 負なら未処理、[0,n) ならpre-order, n ならvisited -    onS = [0] * n -    idx = 0 +    ord_now = 0 +    parent = [-1] * n +    gp = [0] * n +    gp_num = 0 -    scc = [] +    q = [] -        if pre[i] == -1: -            dfs(i) -    # print(g) -    # print("idx",pre) -    # print("low",low) -    # print(scc) +        if order[i] == -1: +            q.append(i) +            while q: +                v = q.pop() +                if v >= 0: +                    if order[v] != -1: +                        continue +                    order[v] = low[v] = ord_now +                    ord_now += 1 +                    S.append(v) +                    q.append(~v) +                    for c in g[v]: +                        if order[c] == -1: +                            q.append(c) +                            parent[c] = v +                        else: +                            low[v] = min(low[v], order[c]) +                else: +                    v = ~v +                    if parent[v] != -1: +                        low[parent[v]] = min(low[parent[v]], low[v]) +                    if low[v] == order[v]: +                        while True: +                            w = S.pop() +                            order[w] = n +                            gp[w] = gp_num +                            if w == v: +                                break +                        gp_num += 1 +    scc = [[] for _ in range(gp_num)] +    for i in range(n): +        gp[i] = gp_num - gp[i] - 1 +        scc[gp[i]].append(i) +    # print(gp) -sys.setrecursionlimit(10**6) -# n,*w = [int(i) for i in read().split()] -gp = SCC_Tarjan(g) -print((len(gp))) -for lst in gp[::-1]: +scc = SCC_Tarjan(g) +print((len(scc))) +for lst in scc: