/// <summary>
        /// Create a new cyclic vertex search for the provided graph.
        /// </summary>
        /// <param name="graph">adjacency list representation of a graph</param>
        internal RegularCyclicVertexSearch(IReadOnlyList <IReadOnlyList <int> > graph)
        {
            this.g = graph;
            int n = graph.Count;

            // skip search if empty graph
            if (n == 0)
            {
                return;
            }

            state = new long[n];

            // start from vertex 0
            Search(0, 0L, 0L);

            // if disconnected we have not visited all vertices
            int v = 1;

            while (Longs.BitCount(visited) != n)
            {
                // haven't visited v, start a new search from there
                if (!Visited(v))
                {
                    Search(v, 0L, 0L);
                }
                v++;
            }

            // no longer needed for the lifetime of the object
            state = null;
        }
 /// <summary>
 /// Find the next index that the <i>cycle</i> intersects with by at least two
 /// vertices. If the intersect of a vertex set with another contains more
 /// then two vertices it cannot be edge disjoint.
 /// </summary>
 /// <param name="start">start searching from here</param>
 /// <param name="cycle">test whether any current cycles are fused with this one</param>
 /// <returns>the index of the first fused after 'start', -1 if none</returns>
 private int IndexOfFused(int start, long cycle)
 {
     for (int i = start; i < cycles.Count(); i++)
     {
         long intersect = cycles[i] & cycle;
         if (intersect != 0 && Longs.BitCount(intersect) > 1)
         {
             return(i);
         }
     }
     return(-1);
 }
        /// <summary>
        /// Convert the bits of a <see cref="long"/> to an array of integers. The size of
        /// the output array is the number of bits set in the value.
        /// </summary>
        /// <param name="set">value to convert</param>
        /// <returns>array of the set bits in the long value</returns>
        internal static int[] ToArray(long set)
        {
            int[] vertices = new int[Longs.BitCount(set)];
            int   i        = 0;

            // fill the cyclic vertices with the bits that have been set
            for (int v = 0; i < vertices.Length; v++)
            {
                if (IsBitSet(set, v))
                {
                    vertices[i++] = v;
                }
            }

            return(vertices);
        }
        /// <summary>
        /// Add the cycle vertices to our discovered cycles. The cycle is first
        /// checked to see if it is isolated (shares at most one vertex) or
        /// <i>potentially</i> fused.
        /// </summary>
        /// <param name="cycle">newly discovered cyclic vertex set</param>
        private void Add(long cycle)
        {
            long intersect = cyclic & cycle;

            // intersect by more then 1 vertex, we 'may' have a fused cycle
            if (intersect != 0 && Longs.BitCount(intersect) > 1)
            {
                AddFused(cycle);
            }
            else
            {
                AddIsolated(cycle);
            }

            cyclic |= cycle;
        }