Union-Find and Set Intersection
First, we convert properties to sets so we can use set_intersection.Then, we go though each pair and check if they are already in the same set (find operation).
First, we convert properties to sets so we can use `set_intersection`.

Then, we go though each pair and check if they are already in the same set (find operation).

If not, we check for the set intersection, and join these two elements.  

# Code
```cpp []
int find(int i, vector<int> &ds) {
    return ds[i] < 0 ? i : ds[i] = find(ds[i], ds);
}
int numberOfComponents(vector<vector<int>>& props, int k) {
    int n = props.size(), m = props[0].size();
    vector<int> intersect(m);
    vector<set<int>> ps;
    for (const auto &p : props)
        ps.push_back(set<int>(begin(p), end(p)));
    vector<int> ds(n, -1);
    for (int i = 0; i < n; ++i)
        for (int j = i + 1; j < n; ++j)
            if (int a = find(i, ds), b = find(j, ds); a != b)
                if (set_intersection(begin(ps[i]), end(ps[i]), begin(ps[j]), end(ps[j]),
                                     begin(intersect)) - begin(intersect) >= k)
                    ds[b] = a;
    return count(begin(ds), end(ds), -1);
}
```
['C++']