union-find with path compression
Intuition
typical union-find with path compression
brute force to check edge/connection between two nodes/properties
Code
# Intuition
 - typical union-find with path compression
 - brute force to check edge/connection between two nodes/properties

# Code
```cpp []
class Solution {
public:
    int numberOfComponents(vector<vector<int>>& properties, int k) {
        int n = properties.size();
        int m = properties[0].size();
        vector<vector<bool>> masks(n, vector<bool>(101, false));
        for(int i = 0; i < n; ++i) {
            for(auto j : properties[i]) {
                masks[i][j] = true;
            }
        }
        vector<int> parent(n);
        function<int(int)> find;
        find = [&find, &parent] (int i) {
            if(parent[i] == i) return i;
            return ( parent[i] = find(parent[i]) );
        };
        iota(parent.begin(), parent.end(), 0);
        for(int j = 1; j < n; ++j) {
            for(int i = 0; i < j; ++i) {
                int common = 0;
                for(int k = 1; k <= 100; ++k) {
                    if(masks[i][k] && masks[j][k])
                        ++common;
                }
                if(common >= k) {
                    parent[find(j)] = find(i);
                }
            }
        }
        unordered_set<int> groupIds;
        for(int j = 0; j < n; ++j) {
            groupIds.insert(find(j));
        }
        return groupIds.size();
    }
};
```
['C++']