Easy to understand ...try once
IntuitionApproachComplexity
Time complexity:

Space complexity:
Code
# Intuition
<!-- Describe your first thoughts on how to solve this problem. -->

# Approach
<!-- Describe your approach to solving the problem. -->

# Complexity
- Time complexity:
<!-- Add your time complexity here, e.g. $$O(n)$$ -->

- Space complexity:
<!-- Add your space complexity here, e.g. $$O(n)$$ -->

# Code
```java []
import java.util.*;

class Solution {
    class DisjointSet {
        List<Integer> par;
        List<Integer> size;

        DisjointSet(int n) {
            par = new ArrayList<>();
            size = new ArrayList<>();
            for (int i = 0; i < n; i++) {
                par.add(i);
                size.add(1);
            }
        }

        public int findUPar(int node) {
            if (par.get(node) == node) {
                return node;
            }
            int ul_par = findUPar(par.get(node));
            par.set(node, ul_par); // Path Compression
            return ul_par;
        }

        public void unionBySize(int u, int v) {
            int ulp_u = findUPar(u);
            int ulp_v = findUPar(v);

            if (ulp_u == ulp_v) return; // Already in the same set

            if (size.get(ulp_u) >= size.get(ulp_v)) {
                size.set(ulp_u, size.get(ulp_u) + size.get(ulp_v));
                par.set(ulp_v, ulp_u); // Merge v into u
            } else {
                size.set(ulp_v, size.get(ulp_u) + size.get(ulp_v));
                par.set(ulp_u, ulp_v); // Merge u into v
            }
        }
    }

    public int numberOfComponents(int[][] properties, int k) {
        int n = properties.length;
        DisjointSet ds = new DisjointSet(n);

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j < n; j++) {
                if (intersect(properties[i], properties[j]) >= k) {
                    ds.unionBySize(i, j);
                }
            }
        }

        Set<Integer> components = new HashSet<>();
        for (int i = 0; i < n; i++) {
            components.add(ds.findUPar(i));
        }

        return components.size();
    }

    private int intersect(int[] a, int[] b) {
        Set<Integer> setA = new HashSet<>();
        for (int num : a) {
            setA.add(num);
        }

        int count = 0;
        Set<Integer> intersected = new HashSet<>();
        for (int num : b) {
            if (setA.contains(num) && !intersected.contains(num)) {
                count++;
                intersected.add(num);
            }
        }

        return count;
    }
}
```
['Hash Table', 'Union Find', 'Graph', 'Java']