docs: def walk(start, ofn, cyc=None):
      """ Non recursive DFS to detect cycles
  
      :param start: start vertex in graph
      :param ofn: function to get the list of outgoing edges of a vertex
      :param cyc: list of existing cycles, cycles are represented in a list started with minimum vertex.
      :return: cycles
      :rtype: list of lists
      """
      ctx, stk = {}, [start]
      cyc = [] if cyc == None else cyc
  
      while len(stk):
          top = stk[-1]
  
          if top not in ctx:
              ctx.update({top:list(ofn(top))})
  
          if len(ctx[top]):
              n = ctx[top][0]
              if n in stk:
                  # cycles found,
                  # normalize the representation of cycles,
                  # start from the smallest vertex, ex.
                  # 4 -> 5 -> 2 -> 7 -> 9 would produce
                  # (2, 7, 9, 4, 5)
                  nc = stk[stk.index(n):]
                  ni = nc.index(min(nc))
                  nc = nc[ni:] + nc[:ni] + [min(nc)]
                  if nc not in cyc:
                      cyc.append(nc)
  
                  ctx[top].pop(0)
              else:
                  stk.append(n)
          else:
              ctx.pop(top)
              stk.pop()
              if len(stk):
                  ctx[stk[-1]].remove(top)
  
      return cyc