class UnionFind {
public:
    UnionFind(int size) {
    	//初始化
        parent = vector<int>(size, -1);
        rank = vector<int>(size, 1);
        count = size;
        for (int i = 0; i < size; i++)
            parent[i] = i;
    }

    int find(int i) {
        int root = i;
        while (i != parent[i])
            i = parent[i];
        //路径压缩
        while (root != parent[root]) {
            int x = root;
            root = parent[root];
            parent[x] = i;
        }
        return i;
    }


    void unite(int i, int j) {
        int rooti = find(i);
        int rootj = find(j);
        if (rooti != rootj) {
            //尽可能的平衡
            if (rank[rooti] < rank[rootj])
                swap(rooti, rootj);
            parent[rootj] = rooti;
            rank[rootj] += rank[rooti];
            count--; 
        }         
    }


    int getCount() const {
        //返回 “孤岛”
        return count;
    }


private:
    vector<int> parent;
    vector<int> rank;
    int count;
};
class UnionSet {
public:
    UnionSet(vector<vector<char>>& grid) {
        int row = grid.size();
        int col = grid[0].size();
        count = 0;
        parent = vector<int>(row * col, 0);
        rank = vector<int>(row * col, 0);
        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {
                if (grid[i][j] == '1') {
                    parent[i * col + j] = i * col + j;
                    rank[i * col + j] = 1;
                    count++;
                }
                else
                    parent[i * col + j] = -1;
            }
        }
    }

    int find(int i) {
        int root = i;
        while (root != parent[root])
            root = parent[root];
        while (i != parent[i]) {
            int x = i;
            i = parent[i];
            parent[x] = i;
        }
        return root;
    }

    void unite(int i, int j) {
        int rooti = find(i);
        int rootj = find(j);
        if (rooti != rootj) {
            if (rank[rooti] < rank[rootj]) 
                swap(rooti, rootj);
            parent[rootj] = rooti;
            rank[rooti] += rank[rootj];
            count--;
        }
    }

    int getCount() {
        return count;
    }

private:
    int count;
    vector<int> parent;
    vector<int> rank;
};