 
     return successful
   }
-
-  private func findAllCycles() -> [Cycle] {
-    return CycleFinder(in: self).findAllCycles()
-  }
-}
-
-/// Class need for optimization
-private final class CycleFinder {
-  typealias Cycle = DIGraph.Cycle
+}
+
+/// Class need for optimization - he containts local properties
+fileprivate final class CycleFinder {
+  fileprivate struct Cycle: Hashable {
+    let vertexIndices: [Int]
+    let edges: [DIEdge]
+
+    public func hash(into hasher: inout Hasher) {
+      // in real SET it's incorrect - because need order. but vertices + edges in all orders form unique
+      hasher.combine(Set(vertexIndices))
+      hasher.combine(Set(edges))
+    }
+    public static func ==(lhs: Cycle, rhs: Cycle) -> Bool {
+      return Set(lhs.vertexIndices) == Set(rhs.vertexIndices) && Set(lhs.edges) == Set(rhs.edges)
+    }
+  }
+
   private let graph: DIGraph
 
   private var startVertexIndex: Int = 0
-  private var result: [DIGraph.Cycle] = []
-  private var noCycleVertices: Set<Int> = [] // Optimization
-
-  private var reachability: [Set<Int>]
-
-  private var maxDepth: Int = 0
-  private var counterVertices: Int = 0
+  private var result: Set<Cycle> = []
+
+  private var reachability: [Set<Int>] // Optimization x100
 
   fileprivate init(in graph: DIGraph) {
     self.graph = graph
     reachability = Array(repeating: [], count: graph.vertices.count)
   }
 
-  fileprivate func findAllCycles() -> [Cycle] {
+  fileprivate func findAllCycles() -> Set<Cycle> {
     findAllReachableVertices()
 
-    var allCycles: [Cycle] = []
+    result = []
     for (index, vertex) in graph.vertices.enumerated() {
       guard case .component = vertex else {
         continue
       }
 
-      allCycles.append(contentsOf: findCycles(from: index))
-    }
-
-    return allCycles
+      startVertexIndex = index
+      // dfs
+      findCycles(currentVertexIndex: index,
+                 visitedVertices: [],
+                 visitedEdges: [])
+    }
+
+    return result
   }
 
   private func findAllReachableVertices() {

    return successful
  }

  private func checkGraphCyclesEdges(cycles: [Cycle]) -> Bool {
    var successful: Bool = true
    for cycle in cycles {
      assert(cycle.edges.count >= 1)

      return
    }

    // first check - current vertex find ALL cycles via current vertex.
    // Second check - current vertex guaranted not cycles via startVertexIndex.
    if currentVertexIndex < startVertexIndex || !reachability[currentVertexIndex].contains(startVertexIndex) {
      return
    }

    let visitedVertices = visitedVertices + [currentVertexIndex]

    for (edge, toIndices) in graph.adjacencyList[currentVertexIndex] {
      let visitedEdges = visitedEdges + [edge]
