Union Find + Bit Manipulation. Time O(n^2), space O(n)
```
class UnionFind:
    def __init__(self, n: int):
        self.parent = [*range(n)]
        self.rank = [1] * n

    def find(self, x: int) -> int:
        if self.parent[x] != x:
            self.parent[x] = self.find(self.parent[x])
        return self.parent[x]

    def union(self, x: int, y: int) -> bool:
        x, y = self.find(x), self.find(y)
        if x == y:
            return False
        if self.rank[x] < self.rank[y]:
            self.parent[x] = y
        else:
            self.parent[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
        return True
                 

class Solution:
    def numberOfComponents(self, properties: List[List[int]], k: int) -> int:
        masks, n = [], len(properties)
        for p in properties:
            mask = 0
            for num in p:
                mask |= 1 << num
            masks.append(mask)
        ans, uf = n, UnionFind(n)
        for u in range(n):
            for v in range(u):
                if (masks[u] & masks[v]).bit_count() >= k:
                    ans -= uf.union(u, v)
        return ans
```
['Bit Manipulation', 'Union Find', 'Python3']