/// <summary>
        /// Podział grafu na cykle. Zakładamy, że dostajemy graf nieskierowany i wszystkie wierzchołki grafu mają parzyste stopnie
        /// (nie trzeba sprawdzać poprawności danych).
        /// </summary>
        /// <param name="G">Badany graf</param>
        /// <returns>Tablica cykli; krawędzie każdego cyklu powinny być uporządkowane zgodnie z kolejnością na cyklu, zaczynając od dowolnej</returns>
        /// <remarks>
        /// Metoda powinna działać w czasie O(m)
        /// </remarks>
        public static Edge[][] cyclePartition(this Graph G)
        {
            Graph        g        = G.Clone();
            int          v        = 0;
            Stark <int>  vertices = new Stark <int>();
            Stark <Edge> cycleL   = new Stark <Edge>();
            Stark <Edge> cycleLR  = new Stark <Edge>();

            List <Edge[]> cycles = new List <Edge[]>();

            bool[] visited = new bool[G.VerticesCount];
            bool   found = false;
            int    end = -1, first = -1;

            vertices.Put(-1);
            while (g.EdgesCount != 0)
            {
                found = g.DFSfc(v, v, ref end, ref first, ref vertices, ref visited, ref cycleL);
                if (!found)
                {
                    v = (v + 1) % g.VerticesCount;
                    while (vertices.Count() != 1)
                    {
                        visited[vertices.Get()] = false;
                    }
                    continue;
                }

                int ind = cycleL.Count() - 1;
                while (cycleL.Peek().From != first)
                {
                    g.DelEdge(cycleL.Peek());
                    cycleLR.Put(cycleL.Get());
                }

                g.DelEdge(cycleL.Peek());
                cycleLR.Put(cycleL.Get());


                while (vertices.Count() != 1)
                {
                    visited[vertices.Get()] = false;
                }

                cycles.Add(cycleLR.ToArray());
                v = end;
                //}
            }

            Edge[][] ccls = cycles.ToArray();
            return(ccls);
        }
        static bool DFSfc(this Graph g, int v, int w, ref int end, ref int first, ref Stark <int> vl, ref bool[] visited, ref Stark <Edge> cycleL)
        {
            int u;

            visited[w] = true;
            foreach (Edge e in g.OutEdges(w))
            {
                u = e.To;
                if (u != vl.Peek())
                {
                    vl.Put(w);
                    cycleL.Put(e);
                    if (visited[u])
                    {
                        end   = w;
                        first = u;
                        return(true);
                    }
                    if (!visited[u] && DFSfc(g, v, u, ref end, ref first, ref vl, ref visited, ref cycleL))
                    {
                        return(true);
                    }
                    vl.Get();
                }
            }
            return(false);
        }