code: def recursive_simple_cycles(G):
      """Find simple cycles (elementary circuits) of a directed graph.
  
      A `simple cycle`, or `elementary circuit`, is a closed path where
      no node appears twice. Two elementary circuits are distinct if they
      are not cyclic permutations of each other.
  
      This version uses a recursive algorithm to build a list of cycles.
      You should probably use the iterator version called simple_cycles().
      Warning: This recursive version uses lots of RAM!
      It appears in NetworkX for pedagogical value.
  
      Parameters
      ----------
      G : NetworkX DiGraph
         A directed graph
  
      Returns
      -------
      A list of cycles, where each cycle is represented by a list of nodes
      along the cycle.
  
      Example:
  
      >>> edges = [(0, 0), (0, 1), (0, 2), (1, 2), (2, 0), (2, 1), (2, 2)]
      >>> G = nx.DiGraph(edges)
      >>> nx.recursive_simple_cycles(G)
      [[0], [2], [0, 1, 2], [0, 2], [1, 2]]
  
      Notes
      -----
      The implementation follows pp. 79-80 in [1]_.
  
      The time complexity is $O((n+e)(c+1))$ for $n$ nodes, $e$ edges and $c$
      elementary circuits.
  
      References
      ----------
      .. [1] Finding all the elementary circuits of a directed graph.
         D. B. Johnson, SIAM Journal on Computing 4, no. 1, 77-84, 1975.
         https://doi.org/10.1137/0204007
  
      See Also
      --------
      simple_cycles, cycle_basis
      """
  
      # Jon Olav Vik, 2010-08-09
      def _unblock(thisnode):
          """Recursively unblock and remove nodes from B[thisnode]."""
          if blocked[thisnode]:
              blocked[thisnode] = False
              while B[thisnode]:
                  _unblock(B[thisnode].pop())
  
      def circuit(thisnode, startnode, component):
          closed = False  # set to True if elementary path is closed
          path.append(thisnode)
          blocked[thisnode] = True
          for nextnode in component[
              thisnode
          ]:  # direct successors of thisnode
              if nextnode == startnode:
                  result.append(path[:])
                  closed = True
              elif not blocked[nextnode]:
                  if circuit(nextnode, startnode, component):
                      closed = True
          if closed:
              _unblock(thisnode)
          else:
              for nextnode in component[thisnode]:
                  if (
                      thisnode not in B[nextnode]
                  ):  # TODO: use set for speedup?
                      B[nextnode].append(thisnode)
          path.pop()  # remove thisnode from path
          return closed
  
      path = []  # stack of nodes in current path
      blocked = defaultdict(bool)  # vertex: blocked from search?
      B = defaultdict(
          list
      )  # graph portions that yield no elementary circuit
      result = []  # list to accumulate the circuits found
  
      # Johnson's algorithm exclude self cycle edges like (v, v)
      # To be backward compatible, we record those cycles in advance
      # and then remove from subG
      for v in G:
          if G.has_edge(v, v):
              result.append([v])
              G.remove_edge(v, v)
  
      # Johnson's algorithm requires some ordering of the nodes.
      # They might not be sortable so we assign an arbitrary ordering.
      ordering = dict(zip(G, range(len(G))))
      for s in ordering:
          # Build the subgraph induced by s and following nodes in the ordering
          subgraph = G.subgraph(
              node for node in G if ordering[node] >= ordering[s]
          )
          # Find the strongly connected component in the subgraph
          # that contains the least node according to the ordering
          strongcomp = nx.strongly_connected_components(subgraph)
          mincomp = min(
              strongcomp, key=lambda ns: min(ordering[n] for n in ns)
          )
          component = G.subgraph(mincomp)
          if len(component) > 1:
              # smallest node in the component according to the ordering
              startnode = min(component, key=ordering.__getitem__)
              for node in component:
                  blocked[node] = False
                  B[node][:] = []
              dummy = circuit(startnode, startnode, component)
      return result
  
imports: from collections import Counter, defaultdict
  from itertools import combinations, product
  from math import inf
  import networkx
  from networkx.utils import not_implemented_for, pairwise
label_desc: Use image node_id 9 for calling a global function with example usage: recursive_simple_cycles(G) and returns: result, closed