Readable O(n^2) code using union find
Complexity

Time complexity:
O(n^2) (Assuming union and get_parent operations take O(1) in union find set)


Space complexity:
O(n)

Code
# Complexity
- Time complexity:
O(n^2) (Assuming `union` and `get_parent` operations take O(1) in union find set)

- Space complexity:
O(n)

# Code
```python3 []
class UnionSet:
    def __init__(self, keys):
        self.parent = {a: a for a in keys}
        self.size = {a: 1 for a in keys}

    def union(self, a, b):
        par_a = self.get_parent(a)
        par_b = self.get_parent(b)
        if self.size[par_a] < self.size[par_b]:
            self.parent[par_a] = par_b
            self.size[par_b] += self.size[par_a]
        else:
            self.parent[par_b] = par_a
            self.size[par_a] += self.size[par_b]
    
    def get_parent(self, a):
        if self.parent[a] == a:
            return a
        self.parent[a] = self.get_parent(self.parent[a])
        return self.parent[a]
    
    def get_size(self, a):
        par_a = self.get_parent(a)
        return self.size[par_a]
    

class Solution:
    def minMalwareSpread(self, graph: List[List[int]], initial: List[int]) -> int:
        n = len(graph)
        uset = UnionSet(range(n))
        initial = set(initial)
        for i in range(n):
            for j in range(i + 1, n):
                if (i not in initial) and (j not in initial) and graph[i][j] == 1:
                    uset.union(i, j)
        nbr_parents = {node: set() for node in initial}
        infect_cnt = {node: 0 for node in range(n)}
        for node in initial:
            for nbr in range(n):
                if nbr != node and (nbr not in initial) and graph[node][nbr] == 1:
                    nbr_par = uset.get_parent(nbr)
                    if nbr_par not in nbr_parents[node]:
                        nbr_parents[node].add(nbr_par)
                        infect_cnt[nbr_par] += 1
        sm_index = min(initial)
        max_cnt = 0
        for node in initial:
            cnt = 0
            for nbr in nbr_parents[node]:
                if infect_cnt[nbr] == 1:
                    cnt += uset.get_size(nbr)
            if max_cnt < cnt:
                max_cnt = cnt
                sm_index = node
            elif max_cnt == cnt:
                sm_index = min(sm_index, node)
        return sm_index
                


```
['Array', 'Hash Table', 'Union Find', 'Graph', 'Matrix', 'Ordered Set', 'Python3']