code: def tarjan_recursif(graph):
      
      global sccp, waiting, dfs_time, dfs_num
      sccp = []
      waiting = []
      waits = [False] * len(graph)
      dfs_time = 0
      dfs_num = [None] * len(graph)
  
      def dfs(node):
          global sccp, waiting, dfs_time, dfs_num
          waiting.append(node)           # new node is waiting
          waits[node] = True
          dfs_num[node] = dfs_time       # mark visit
          dfs_time += 1
          dfs_min = dfs_num[node]        # compute dfs_min
          for neighbor in graph[node]:
              if dfs_num[neighbor] is None:
                  dfs_min = min(dfs_min, dfs(neighbor))
              elif waits[neighbor] and dfs_min > dfs_num[neighbor]:
                  dfs_min = dfs_num[neighbor]
          if dfs_min == dfs_num[node]:   # representative of a component
              sccp.append([])            # make a component
              while True:                # add waiting nodes
                  u = waiting.pop()
                  waits[u] = False
                  sccp[-1].append(u)
                  if u == node:          # until representative
                      break
          return dfs_min
  
      for node in range(len(graph)):
          if dfs_num[node] is None:
              dfs(node)
      return sccp
docs: Strongly connected components by Tarjan, recursive implementation
  
      :param graph: directed graph in listlist format, cannot be listdict
      :returns: list of lists for each component
      :complexity: linear