/// <inheritdoc/>
            public UndirectedIndexedIncidenceGraph ToGraph()
            {
                int n = _vertexCount;
                int m = _tailByEdge.Count;

                Debug.Assert(_tailByEdge.Count == _headByEdge.Count, "_tailByEdge.Count == _headByEdge.Count");

                int dataLength = 2 + n + m + m + m + m;

#if NET5
                int[] data = GC.AllocateUninitializedArray <int>(dataLength);
#else
                int[] data = new int[dataLength];
#endif
                data[0] = n;
                data[1] = m;

                Span <int> destEdgesOrderedByTail = data.AsSpan(2 + n, m + m);
                int        invertedEdgeCount      = 0;
                for (int edge = 0; edge < m; ++edge)
                {
                    destEdgesOrderedByTail[edge] = edge;
                    int head = _headByEdge[edge];
                    int tail = _tailByEdge[edge];
                    if (head != tail)
                    {
                        destEdgesOrderedByTail[m + invertedEdgeCount++] = ~edge;
                    }
                }

                int directedEdgeCount = m + invertedEdgeCount;
                Array.Sort(data, 2 + n, directedEdgeCount,
                           new UndirectedIndexedEdgeComparer(_tailByEdge.Array, _headByEdge.Array));

                Span <int> destUpperBoundByVertex = data.AsSpan(2, n);
                destUpperBoundByVertex.Clear();
                for (int i = 0; i < directedEdgeCount; ++i)
                {
                    int edge = destEdgesOrderedByTail[i];
                    int tail = edge < 0 ? _headByEdge[~edge] : _tailByEdge[edge];
                    ++destUpperBoundByVertex[tail];
                }

                for (int vertex = 1; vertex < n; ++vertex)
                {
                    destUpperBoundByVertex[vertex] += destUpperBoundByVertex[vertex - 1];
                }

                Span <int> destHeadByEdge = data.AsSpan(2 + n + m + m, m);
                _headByEdge.AsSpan().CopyTo(destHeadByEdge);

                Span <int> destTailByEdge = data.AsSpan(2 + n + m + m + m, m);
                _tailByEdge.AsSpan().CopyTo(destTailByEdge);

                _headByEdge  = ArrayPrefixBuilder.Release(_headByEdge, false);
                _tailByEdge  = ArrayPrefixBuilder.Release(_tailByEdge, false);
                _vertexCount = 0;

                return(new UndirectedIndexedIncidenceGraph(data));
            }
            /// <inheritdoc/>
            public IndexedIncidenceGraph ToGraph()
            {
                int n = _vertexCount;
                int m = _tailByEdge.Count;

                Debug.Assert(_tailByEdge.Count == _headByEdge.Count, "_tailByEdge.Count == _headByEdge.Count");

                int dataLength = 2 + n + m + m + m;

#if NET5
                int[] data = GC.AllocateUninitializedArray <int>(dataLength);
#else
                int[] data = new int[dataLength];
#endif
                data[0] = n;
                data[1] = m;

                Span <int> destReorderedEdges = data.AsSpan(2 + n, m);
                for (int edge = 0; edge < m; ++edge)
                {
                    destReorderedEdges[edge] = edge;
                }

                if (NeedsReordering)
                {
                    Array.Sort(data, 2 + n, m, new IndexedEdgeComparer(_tailByEdge.Array));
                }

                Span <int> destUpperBoundByVertex = data.AsSpan(2, n);
                destUpperBoundByVertex.Clear();
                for (int edge = 0; edge < m; ++edge)
                {
                    int tail = _tailByEdge[edge];
                    ++destUpperBoundByVertex[tail];
                }

                for (int vertex = 1; vertex < n; ++vertex)
                {
                    destUpperBoundByVertex[vertex] += destUpperBoundByVertex[vertex - 1];
                }

                Span <int> destHeadByEdge = data.AsSpan(2 + n + m, m);
                _headByEdge.AsSpan().CopyTo(destHeadByEdge);

                Span <int> destTailByEdge = data.AsSpan(2 + n + m + m, m);
                _tailByEdge.AsSpan().CopyTo(destTailByEdge);

                _currentMaxTail = 0;
                _headByEdge     = ArrayPrefixBuilder.Release(_headByEdge, false);
                _tailByEdge     = ArrayPrefixBuilder.Release(_tailByEdge, false);
                _vertexCount    = 0;

                return(new IndexedIncidenceGraph(data));
            }