public int[] FindRedundantConnection(int[][] edges)
        {
            if (edges.Length == 1)
            {
                return(Array.Empty <int>());
            }
            Span <int> id   = stackalloc int[edges.Length];
            Span <int> rank = stackalloc int[edges.Length];
            var        uf   = new SpanUF(id, rank);

            foreach (var edge in edges)
            {
                uf.Union(edge[0] - 1, edge[1] - 1);
            }
            return(uf.GetRedundantConnection());
        }
        public int NumIslands(char[][] grid)
        {
            if (grid is null || grid.Length == 0)
            {
                return(0);
            }

            var rowCount = grid.Length;
            var colCount = grid[0].Length;
            var n        = rowCount * colCount;

            // initialize UF
            Span <int> id    = stackalloc int[n];
            Span <int> sz    = stackalloc int[n];
            var        count = 0;

            for (var i = 0; i < rowCount; i++)
            {
                for (var j = 0; j < colCount; j++)
                {
                    if (grid[i][j] == '1')
                    {
                        var idx = i * colCount + j;
                        id[idx] = idx;
                        sz[idx] = 1;
                        count  += 1;
                    }
                }
            }
            var uf = new SpanUF(id, sz, count);

            for (var i = 0; i < rowCount; i++)
            {
                for (var j = 0; j < colCount; j++)
                {
                    if (grid[i][j] == '1')
                    {
                        // grid[i][j] = '0'; avoid duplicate Union action
                        var p = i * colCount + j;
                        uf.Union(p, grid, rowCount, colCount);
                    }
                }
            }
            return(uf.Count);
        }