Given a non-empty array of unique positive integers A, consider the following graph:

There are A.length nodes, labelled A[0] to A[A.length - 1];
There is an edge between A[i] and A[j] if and only if A[i] and A[j] share a common factor greater than 1.

Return the size of the largest connected component in the graph.
 



Example 1:
Input: [4,6,15,35]
Output: 4



Example 2:
Input: [20,50,9,63]
Output: 2



Example 3:
Input: [2,3,6,7,4,12,21,39]
Output: 8


Note:

1 <= A.length <= 20000
1 <= A[i] <= 100000

Difficulty: interview

Starter code:

class Solution:
    def largestComponentSize(self, A: List[int]) -> int:
        

Solutions:
["from collections import defaultdict\n\n\nclass Solution:\n    MAXPRIME=100001\n    isPrime=[0 for _ in range(MAXPRIME+1)]\n    isPrime[0]=-1;isPrime[1]=-1 #0 and 1 are not prime numbers\n    for i in range(2,MAXPRIME):\n        if isPrime[i]==0: #i is prime\n            for multiple in range(i*i,MAXPRIME+1,i):\n                if isPrime[multiple]==0:\n                    isPrime[multiple]=i\n            isPrime[i] = i\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n\n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            prime_factors = set()\n            while Solution.isPrime[x]!=-1:\n                p = Solution.isPrime[x]\n                root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                x //= p\n            label[root_id] -= 1\n        \n        return -min(label.values())\n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]  # parent array\n        self.s=[1]*n  # size array\n        \n    def find(self,x): # find the representative/root of x\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    M=100000\n    sieve=[0]*(M+1) # stores the largest prime divisor of integers up to M\n    for i in range(2,M+1):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,M//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:   \n        g=UF(len(A))\n        primes=defaultdict(list) # {q:[nums]} list of integers that's divisible by prime q\n        for i,num in enumerate(A):\n            while num>1:\n                q=self.sieve[num]\n                primes[q].append(i) # add the ith element to be divisible by q\n                while num%q==0:\n                    num//=q\n                    \n        for l in primes.values():\n            root=g.find(l[0]) # representative/root of the 1st integer divisible by q\n            for i in l[1:]: # joins all components with root\n                node=g.find(i)\n                if node!=root:\n                    if g.s[root]<g.s[node]: # connect the smaller set to the larger one (for efficiency)\n                        root,node=node,root\n                    g.p[node]=root\n                    g.s[root]+=g.s[node]\n        \n        return max(g.s)", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    MAXPRIME=100001\n    isPrime=[0 for _ in range(MAXPRIME+1)]\n    isPrime[0]=-1;isPrime[1]=-1 #0 and 1 are not prime numbers\n    for i in range(2,MAXPRIME):\n        if isPrime[i]==0: #i is prime\n            for multiple in range(i*i,MAXPRIME+1,i):\n                if isPrime[multiple]==0:\n                    isPrime[multiple]=i\n            isPrime[i] = i\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n\n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            prime_factors = set()\n            while Solution.isPrime[x]!=-1:\n                p = Solution.isPrime[x]\n                root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                x //= p\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class DSU:\n    def __init__(self, n):\n        self.p = list(range(n))\n        self.sz = [1]*(n)\n    \n    def find(self, x):\n        if x == self.p[x]:\n            return x\n        self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def unite(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        if x == y:\n            return\n        if self.sz[x] < self.sz[y]:\n            x, y = y, x\n        self.p[y] = x\n        self.sz[x] += self.sz[y]\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        N = max(a)+1\n        \n        idx = [-1]*N\n        for i, x in enumerate(a):\n            idx[x] = i\n            \n        dsu = DSU(N)\n        siv = [True]*N\n        \n        for i in range(2, N):\n            if siv[i]:\n                root = idx[i]\n                for j in range(2*i, N, i):\n                    siv[j] = False\n                    if idx[j] != -1:\n                        if root == -1:\n                            root = idx[j]\n                        dsu.unite(root, idx[j])\n\n        return max(dsu.sz)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())", "class ds:\n    def __init__(self, n):\n        self.arr = list(range(n))\n        self.size = [1] * n\n        \n    def find(self, x):\n        if self.arr[x] != x: self.arr[x] = self.find(self.arr[x])\n        return self.arr[x]\n\n    def union(self, x, y):\n        Ax= self.find(x)\n        Ay= self.find(y)\n        if Ax == Ay: \n            return False\n        if self.size[Ax] > self.size[Ay]: Ax, Ay = Ay, Ax\n        self.arr[Ax] = Ay\n        self.size[Ay] += self.size[Ax]\n        return True\n    \ndef primes(n):\n    odds = range(3, n+1, 2)\n    sieve = set(sum([list(range(q*q, n+1, q+q)) for q in odds], []))\n    return [2] + [p for p in odds if p not in sieve]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factors(n):\n            result = set()\n            for p in primeNumber:\n                while n % p == 0:\n                    n //= p\n                    result.add(p)\n            if n > 1: result.add(n)\n            return list(result) \n        \n        n, m = len(A), max(A)\n        dsa = ds(m+1)\n        primeNumber=primes(round(m**.5)+1)\n        for d in A:\n            rest = factors(d)\n            for i in rest:\n                dsa.union(d, i)\n        return Counter([dsa.find(x) for x in A]).most_common(1)[0][1]", "import math\nclass disjoint(object):\n    def __init__(self, size):\n        self.root_node_size = [1] * size\n        self.nodes = [n for n in range(size)]\n        \n    def findRoot(self, node):\n        while(self.nodes[node] != node):            \n            node = self.nodes[node]\n        return node\n    \n    def merge(self, val_one, val_two):\n        root_one = self.findRoot(val_one)\n        root_two = self.findRoot(val_two)\n        \n        if root_one == root_two:\n            return\n        \n        r1size = self.root_node_size[root_one]\n        r2size = self.root_node_size[root_two]\n        \n        new_root = None\n        old_root = None\n        if r1size <= r2size:\n            new_root = root_two\n            old_root = root_one\n        else:\n            new_root = root_one \n            old_root = root_two\n        self.root_node_size[new_root] += self.root_node_size[old_root]\n        self.root_node_size[old_root] = 0\n        self.nodes[old_root] = new_root\n        \nclass Solution:\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        def factors(n):\n            known_factors = set()\n            while n % 2 == 0:\n                known_factors.add(2)\n                n //= 2\n            for possible_factor in range(3, math.floor(math.sqrt(n))+1, 2):\n                while n % possible_factor == 0:\n                    known_factors.add(possible_factor)\n                    n //= possible_factor\n            if n > 2:\n                known_factors.add(n)\n            return known_factors\n        \n        dj = disjoint(len(A))\n        known_factors = dict()\n        for (i,v) in enumerate(A):\n            for p in factors(v):\n                if p in known_factors:\n                    dj.merge(i, known_factors[p])\n                known_factors[p] = i\n        return max(dj.root_node_size)\n", "class DSU:\n    def __init__(self, count):\n        self.parent = [i for i in range(count)]\n        self.size = [1 for _ in range(count)]\n        self.max = 0\n    \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        while x != root:\n            next_root = self.parent[x]\n            self.parent[x] = root\n            x = next_root\n        return root\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n        if r1 == r2:\n            return\n        if self.size[r1] < self.size[r2]:\n            self.size[r2] += self.size[r1]\n            self.parent[r1] = r2\n        else:\n            self.size[r1] += self.size[r2]\n            self.parent[r2] = r1\n        self.max = max(self.max, self.size[r1], self.size[r2])\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(len(A))\n        def getPrimeFactors( n):\n            res = set()\n            while n % 2 == 0:\n                res.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                while n % i == 0:\n                    res.add(i)\n                    n //= i\n            if n > 2:\n                res.add(n)\n            return res\n        prime_to_idx = {}\n        for i, n in enumerate(A):\n            primes = getPrimeFactors(n)\n            for prime in primes:\n                if prime in prime_to_idx:\n                    dsu.union(i, prime_to_idx[prime])\n                prime_to_idx[prime] = i\n        return dsu.max", "class UF(object):\n    def uf(self, n):\n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):\n        if x != self.uf[x]:\n            self.uf[x] = self.find(self.uf[x])\n        return self.uf[x]\n\n    def union(self, x, y):\n        xx = self.find(x)\n        yy = self.find(y)\n        if xx == yy:\n            return \n        self.uf[xx] = yy\n        self.size[yy] += self.size[xx]\n        # self.size[xx] = 0\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primefactors(n):\n            # \u66b4\u529b\u6c42\u53d6\u56e0\u5b50\n            out = set()\n            # \u7b2c\u4e00\u6b65\u662f\u63d0\u53d62\u4e14n\u53d8\u6210\u5947\u6570\n            while n % 2 == 0:\n                out.add(2)\n                n //= 2\n            # \u7b2c\u4e8c\u6b65\u662f\u4ece3\u5f00\u59cb\u904d\u5386\u5947\u6570\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                while n % i == 0:\n                    out.add(i)\n                    n //= i\n            # \u7b2c\u4e09\u6b65\u5173\u7167\u989d\u5916corner\u60c5\u51b5\n            if n > 2:\n                out.add(n)\n            return out\n        '''\n        idx_lookup = {A[i]: i for i in range(len(A))} \n        uf = UF()\n        uf.uf(len(A))\n        primeAndItsMultiples = collections.defaultdict(list)\n        for i in A:\n            factors = primefactors(i)\n            for f in factors:\n                primeAndItsMultiples[f].append(i)\n        for idx, multiples in primeAndItsMultiples.items():\n            if multiples:\n                root = multiples[0] # use the first multiple as their root\n                for node in multiples[1:]:\n                    uf.union(idx_lookup[node], idx_lookup[root]) # connect node with root             \n        return max(uf.size)\n        '''\n        uf = UF()\n        uf.uf(len(A))\n        \n        prime = {}\n        for i, v in enumerate(A):\n            factors = primefactors(v)\n            for p in factors:\n                if p in prime:\n                    uf.union(i, prime[p])\n                else:\n                    prime[p] = i\n        return max(uf.size)", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]  # parent array\n        self.s=[1]*n  # size array\n        \n    def find(self,x): # find the representative/root of x\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    M=100000\n    sieve=[0]*(M+1) # stores the minimum prime divisor of integers up to M\n    for i in range(2,M+1):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,M//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:   \n        g=UF(len(A))\n        primes=defaultdict(list) # {q:[nums]} list of integers that's divisible by prime q\n        for i,num in enumerate(A):\n            tmp=-1\n            while num>1:\n                q=self.sieve[num]\n                num//=q\n                if q!=tmp:\n                    primes[q].append(i) # add the element to be divisible by q\n                    tmp=q\n                    \n        for l in primes.values():\n            root=g.find(l[0]) # representative/root of the 1st integer divisible by q\n            for i in l[1:]: # joins all components with root\n                node=g.find(i)\n                if node!=root:\n                    if g.s[root]<g.s[node]: # connect the smaller set to the larger one\n                        root,node=node,root\n                    g.p[node]=root\n                    g.s[root]+=g.s[node]\n        \n        return max(g.s)", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gen_primes(n):\n            candidates = [1] * n\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if candidates[i]:\n                    for j in range(i ** 2, n, i):\n                        candidates[j] = 0\n            return [i for i in range(2, n) if candidates[i]]\n        primes = gen_primes(int(math.sqrt(max(A))) + 1)\n        def factor(n):\n            result = set()\n            for i in primes:\n                if i > int(math.sqrt(n)):\n                    break\n                if n % i == 0:\n                    result.add(i)\n                    while n % i == 0:\n                        n //= i\n            result.add(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            factors = factor(a)\n            for f in factors:\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class UnionFindSet:\n    def __init__(self, n):\n        self.parents = list(range(n))\n        self.ranks = [1] * n\n        \n    def find(self, u):\n        if u != self.parents[u]:\n            self.parents[u] = self.find(self.parents[u])\n        return self.parents[u]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu == pv:\n            return False\n        if self.ranks[pu] > self.ranks[pv]:\n            self.parents[pv] = pu\n            self.ranks[pu] += self.ranks[pv]\n        elif self.ranks[pu] < self.ranks[pv]:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        else:\n            self.parents[pu] = pv\n            self.ranks[pv] += self.ranks[pu]\n        return True\n            \n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_prime_factors(n):\n            ans = set()\n            while n % 2 == 0: \n                ans.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    ans.add(i) \n                    n //= i \n            if n > 2: \n                ans.add(n)\n            return ans\n        \n        n = len(A)\n        uf = UnionFindSet(n)\n        \n        dic = {}\n        for i, a in enumerate(A):\n            primes = get_prime_factors(a)\n            for p in primes:\n                if p in dic:\n                    uf.union(i, dic[p])\n                dic[p] = i\n        \n        return max(uf.ranks)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def decompose(n):\n            def rec(n, start):\n                for i in range(start, int(math.sqrt(n)) + 1, 2):\n                    if n % i == 0:\n                        return rec(n // i, i) | {i}\n                return {n}\n            if n % 2 == 0:\n                while n % 2 == 0:\n                    n //= 2\n                if n == 1:\n                    return {2}\n                return {2} | rec(n, 3)\n            return rec(n, 3)\n        prime_set = collections.defaultdict(list)\n        for i in range(len(A)):\n            for f in decompose(A[i]):\n                prime_set[f].append(i)\n        ls = list(range(len(A)))\n        def find(x):\n            if ls[x] != x:\n                ls[x] = find(ls[x])\n            return ls[x]\n        def union(x, y):\n            ls[find(x)] = find(y)\n        for v in prime_set.values():\n            for i in range(len(v) - 1):\n                union(v[i], v[i+1])\n        return max(Counter([find(i) for i in range(len(A))]).values())", "class UF(object):\n    def uf(self, n):\n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):\n        if x != self.uf[x]:\n            self.uf[x] = self.find(self.uf[x])\n        return self.uf[x]\n\n    def union(self, x, y):\n        xx = self.find(x)\n        yy = self.find(y)\n        if xx == yy:\n            return \n        self.uf[xx] = yy\n        self.size[yy] += self.size[xx]\n        # self.size[xx] = 0\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primefactors(n):\n            # \u66b4\u529b\u6c42\u53d6\u56e0\u5b50\n            out = set()\n            # \u7b2c\u4e00\u6b65\u662f\u63d0\u53d62\u4e14n\u53d8\u6210\u5947\u6570\n            while n % 2 == 0:\n                out.add(2)\n                n //= 2\n            # \u7b2c\u4e8c\u6b65\u662f\u4ece3\u5f00\u59cb\u904d\u5386\u5947\u6570\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                while n % i == 0:\n                    out.add(i)\n                    n //= i\n            # \u7b2c\u4e09\u6b65\u5173\u7167\u989d\u5916corner\u60c5\u51b5\n            if n > 2:\n                out.add(n)\n            return out\n        '''\n        idx_lookup = {A[i] : i for i in range(len(A))} \n        uf = UF()\n        uf.uf(len(A))\n        # \u4f7f\u7528\u56e0\u5b50\u4f5c\u4e3akey \u6765\u6536\u96c6index\u8868\u793a\u516c\u6709\u76f8\u540c\u56e0\u5b50\n        primeAndItsMultiples = collections.defaultdict(list)\n        for i in A:\n            factors = primefactors(i)\n            for f in factors:\n                primeAndItsMultiples[f].append(i)\n        for idx, multiples in primeAndItsMultiples.items():\n            if multiples:\n                root = multiples[0] # use the first multiple as their root\n                for node in multiples[1:]:\n                    uf.union(idx_lookup[node], idx_lookup[root]) # connect node with root             \n        return max(uf.size)\n        '''\n        uf = UF()\n        uf.uf(len(A))\n        \n        prime = {}\n        for i, v in enumerate(A):\n            factors = primefactors(v)\n            for p in factors:\n                if p in prime:\n                    uf.union(i, prime[p])\n                else:\n                    prime[p] = i\n        return max(uf.size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        rank = {i: 1 for i in range(len(A))}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                if rank[px] > rank[py]:\n                    px, py = py, px\n                rank[py] += rank[px]\n                uf[px] = py\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2: x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k:\n                    ans.add(k)\n                    while not x % k: x //= k\n                # if x == 1: break\n            if x > 1: ans.add(x)\n            return ans\n                \n        dic = {}\n        for i in range(len(A)):\n            for k in primeFactor(A[i]):\n                dic.setdefault(k, i)\n                union(i, dic[k])\n        # print(rank)\n        return max(Counter([find(i) for i in range(len(A))]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        rank = {i: 1 for i in range(len(A))}\n\n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n\n        def union(x, y):\n            px = find(x)\n            py = find(y)\n            if px != py:\n                if rank[px] > rank[py]:\n                    px, py = py, px\n                rank[py] += rank[px]\n                uf[px] = py\n\n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2: x //= 2\n            for i in range(3, int(math.sqrt(x)) + 1, 2):\n                if not x % i:\n                    ans.add(i)\n                    while not x % i: x //= i\n            if x > 1: ans.add(x)\n            return ans\n\n        dic = {}\n        for i in range(len(A)):\n            for j in primeFactor(A[i]):\n                dic.setdefault(j, i)\n                union(i, dic[j])\n        cnt = Counter()\n        for i in range(len(A)):\n            cnt[find(i)] += 1\n        return max(cnt.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def sieve():\n            i = 2\n            while i < len(spf):\n                spf[i] = 2\n                i += 2\n            i = 3\n            while i * i < len(spf):\n                if spf[i] == i:\n                    j = i\n                    while j < len(spf):\n                        if spf[j] == j:\n                            spf[j] = i\n                        j += i\n                i += 2\n        \n        spf, di, factors, visited_nums, visited_factors, ans = [i for i in range(max(A) + 1)], defaultdict(set), defaultdict(set), set(), set(), 1\n        \n        sieve()  # 1\n        \n        for num in A:\n            x = num\n            while x != 1:\n                di[spf[x]].add(num)\n                factors[num].add(spf[x])\n                x //= spf[x]\n        \n        for num in A:  # 2\n            if num in visited_nums:\n                continue\n                \n            visited_nums.add(num)\n            cur, queue = 1, deque([])\n            for factor in factors[num]:\n                queue.append(factor)\n                \n            while queue: \n                factor = queue.popleft()\n                visited_factors.add(factor)\n                for next_num in di[factor]:  # 3\n                    if next_num in visited_nums:\n                        continue\n                        \n                    visited_nums.add(next_num)\n                    cur += 1\n                    for next_factor in factors[next_num]:\n                        if next_factor in visited_factors:\n                            continue\n                        \n                        visited_factors.add(next_factor)\n                        queue.append(next_factor)\n                \n            ans = max(ans, cur)\n        \n        return ans", "class Solution:    \n    def get_prime_numbers(self, num_to_idx_dict, max_num: int) -> List[int]:\n        is_prime_list = [True] * (max_num + 1)        \n        prime_to_nums_dict = defaultdict(list)\n        \n        for i in range(2, max_num // 2 + 1):            \n            if is_prime_list[i] == False: continue\n            \n            num = i\n            while num <= max_num:\n                if num in num_to_idx_dict:\n                    prime_to_nums_dict[i].append(num_to_idx_dict[num])\n                is_prime_list[num] = False\n                num += i         \n        \n        return prime_to_nums_dict\n    \n    def find(self, union_list, index: int) -> int:\n        if index == union_list[index]: return index\n        #return self.find(union_list, union_list[index])    \n        parent = self.find(union_list, union_list[index])\n        union_list[index] = parent\n        return parent\n        \n    def union(self, union_list, index1: int, index2: int) -> None:\n        union1, union2 = self.find(union_list, index1), self.find(union_list, index2)                \n        #union_list[union1], union_list[index2] = union2, union2\n        union_list[union1] = union2\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        if len(A) == 0: return 0        \n        max_num = max(A)\n        union_list = [i for i in range(len(A))]\n        count_list = [0] * (len(A))\n        num_to_idx_dict = dict(list(zip(A, list(range(len(A))))))\n        \n        # get prime numbers\n        prime_to_nums_dict = self.get_prime_numbers(num_to_idx_dict, max_num) # prime numbers of A's numbers\n        \n        # linking numbers having the same prime \n        for prime, nums in list(prime_to_nums_dict.items()):\n            for i in range(len(nums) - 1):\n                self.union(union_list, nums[i], nums[i + 1])\n        \n        # counting numbers in a component        \n        for i, num in enumerate(A):\n            count_list[self.find(union_list, i)] += 1        \n            \n        return max(count_list)\n# Time complexity: O(n * p) where n is the maximum number of A and p is the number of prime numbers less than n\n# Space complexity: O(n + p) we can ignore p\n", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gen_primes(n):\n            candidates = [1] * n\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if candidates[i]:\n                    for j in range(i ** 2, n, i):\n                        candidates[j] = 0\n            return [i for i in range(2, n) if candidates[i]]\n        primes = gen_primes(int(math.sqrt(max(A))) + 1)\n        def factor(n):\n            result = []\n            for i in primes:\n                if i > int(math.sqrt(n)):\n                    break\n                if n % i == 0:\n                    result.append(i)\n                    while n % i == 0:\n                        n //= i\n            result.append(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            factors = factor(a)\n            for f in factors:\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class Solution:    \n    def get_prime_numbers(self, num_to_idx_dict, max_num: int) -> List[int]:\n        is_prime_list = [True] * (max_num + 1)        \n        prime_to_nums_dict = defaultdict(list)\n        \n        for i in range(2, max_num // 2 + 1):            \n            if is_prime_list[i] == False: continue \n            num = i\n            while num <= max_num:\n                if num in num_to_idx_dict: prime_to_nums_dict[i].append(num_to_idx_dict[num])\n                is_prime_list[num], num = False, num + i\n                \n        return prime_to_nums_dict\n    \n    def find(self, union_list, index: int) -> int:\n        if index == union_list[index]: return index\n        parent = self.find(union_list, union_list[index])\n        union_list[index] = parent\n        return parent\n        \n    def union(self, union_list, index1: int, index2: int) -> None:\n        union1, union2 = self.find(union_list, index1), self.find(union_list, index2)                \n        union_list[index2] = union2\n        union_list[union1] = union2\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        if len(A) == 0: return 0        \n        max_num = max(A)\n        union_list, count_list = [i for i in range(len(A))], [0] * (len(A))\n        num_to_idx_dict = dict(list(zip(A, list(range(len(A))))))\n        \n        # get prime numbers\n        prime_to_nums_dict = self.get_prime_numbers(num_to_idx_dict, max_num) # prime numbers of A's numbers\n        \n        # linking numbers having the same prime \n        for prime, nums in list(prime_to_nums_dict.items()):\n            for i in range(len(nums) - 1):\n                self.union(union_list, nums[i + 1], nums[i])\n        \n        # counting numbers in a component        \n        for i, num in enumerate(A):\n            count_list[self.find(union_list, i)] += 1        \n            \n        return max(count_list)\n# Time complexity: O(n * p) where n is the maximum number of A and p is the number of prime numbers less than n\n# Space complexity: O(n + p) we can ignore p\n", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xr = self.find(x)\n        yr = self.find(y)\n        \n        if xr == yr: return\n        \n        if self.size[xr] >= self.size[yr]:\n            self.size[xr] += self.size[yr]\n            self.size[yr] = self.size[xr]\n            self.parent[yr] = xr\n        else:\n            self.size[yr] += self.size[xr]\n            self.size[xr] = self.size[yr]\n            self.parent[xr] = yr\n\n\nclass Solution:\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        N = len(A)\n        max_A = max(A)\n        is_prime = [True] * (max_A+1)\n        index = {x: i for i, x in enumerate(A)}\n        dsu = DSU(N)\n        \n        for factor in range(2, max_A + 1):\n            if is_prime[factor]:\n                multiplier = factor << 1\n                previous = index.get(factor)\n                \n                while multiplier <= max_A:\n                    is_prime[multiplier] = False\n                    if multiplier in index:\n                        if previous is not None: \n                            dsu.union(previous, index.get(multiplier))\n                        previous = index[multiplier]\n                        \n                    multiplier += factor\n                    \n                    \n        # Browse DSU for result\n        return max(dsu.size)", "class DSU:\n    \n    def __init__(self, count):\n        self.size = [1 for _ in range(count)]\n        self.parent = [i for i in range(count)]\n        self.max_size = 0\n    \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        while x != root:\n            next_node = self.parent[x]\n            self.parent[x] = root\n            x = next_node\n        return root\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n        if r1 == r2:\n            return\n        if self.size[r1] < self.size[r2]:\n            self.size[r2] += self.size[r1]\n            self.parent[r1] = r2\n        else:\n            self.size[r1] += self.size[r2]\n            self.parent[r2] = r1\n        self.max_size = max(self.max_size, self.size[r1], self.size[r2])\n\nclass Solution:\n    \n    def getPrimeFactors(self, n):\n        res = set()\n        while n % 2 == 0:\n            res.add(2)\n            n //= 2\n        for i in range(3, int(math.sqrt(n)) + 1, 2):\n            while n % i == 0:\n                res.add(i)\n                n //= i\n        if n > 2:\n            res.add(n)\n        return res\n                \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(len(A))\n        prime_to_idx = {}\n        for i, n in enumerate(A):\n            primes = self.getPrimeFactors(n)\n            for prime in primes:\n                if prime in prime_to_idx:\n                    dsu.union(i, prime_to_idx[prime])\n                prime_to_idx[prime] = i\n        return dsu.max_size", "class UnionFind(object):\n    def uf(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return self.uf[x]\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primeFactors(n):  # Prime factor decomposition\n            out = set()\n            while n % 2 == 0: \n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    out.add(i) \n                    n //= i \n            if n > 2: \n                out.add(n)\n            return out\n        \n        idx_lookup = {A[i]: i for i in range(len(A))} # in order to find idx in uf\n        uf = UnionFind()\n        uf.uf(len(A))\n        primeAndItsMultiples = collections.defaultdict(list) # {2: [4, 6], 3: [6, 15], 5: [15, 35], 7: [35]})\n        \n        for i in A:\n            factors = primeFactors(i)\n            for f in factors:\n                primeAndItsMultiples[f].append(i)\n\n        # we don't need to connect all the multiples of a prime, \n        # just use the first multiple as their root\n        for idx, multiples in primeAndItsMultiples.items():\n            if multiples:\n                root = multiples[0] # use the first multiple as their root\n                for node in multiples[1:]:\n                    uf.union(idx_lookup[node], idx_lookup[root]) # connect node with root\n                    \n        return max(uf.size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        # rank = {i: 1 for i in range(len(A))}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                # if rank[px] > rank[py]:\n                #     px, py = py, px\n                # rank[py] += rank[px]\n                uf[px] = py\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2: x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k:\n                    ans.add(k)\n                    while not x % k: x //= k\n                # if x == 1: break\n            if x > 1: ans.add(x)\n            return ans\n                \n        dic = {}\n        for i in range(len(A)):\n            for k in primeFactor(A[i]):\n                dic.setdefault(k, i)\n                union(i, dic[k])\n        # print(rank)\n        return max(Counter([find(i) for i in range(len(A))]).values())", "from collections import defaultdict as d\nclass Solution:\n    MAXPRIME=100001\n    isPrime=[0 for _ in range(MAXPRIME+1)]\n    isPrime[0]=-1;isPrime[1]=-1 #0 and 1 are not prime numbers\n    for i in range(2,MAXPRIME//2):\n        if isPrime[i]==0: #i is prime\n            for multiple in range(i*i,MAXPRIME+1,i):\n                if isPrime[multiple]==0:\n                    isPrime[multiple]=i         \n    def largestComponentSize(self, A: List[int]) -> int:\n        arr=A\n        n=len(arr)\n        \n        primeConnections=d(set) #primeConnections[i]={connected prime numbers}\n        primeFactorCnts=d(lambda:0)\n        \n        for x in arr:\n            if x==1:continue\n            primeFactors=set()\n            while Solution.isPrime[x]!=0:\n                primeFactors.add(Solution.isPrime[x])\n                x//=Solution.isPrime[x]\n            primeFactors.add(x)\n            primeFactors=list(primeFactors)\n            if len(primeFactors)>0:\n                primeFactorCnts[primeFactors[0]]+=1 #only increment the smallest prime factor since all the prime factors will be linked\n                for i in range(len(primeFactors)-1):\n                    for j in range(i+1,len(primeFactors)):\n                        primeConnections[primeFactors[i]].add(primeFactors[j]) #create links between all prime factors for the number\n                        primeConnections[primeFactors[j]].add(primeFactors[i])\n        \n        def dfs(p,componentSize): #find the total size of each component\n            exploredSet.add(p)\n            componentSize[0]+=primeFactorCnts[p]\n            for nex in primeConnections[p]:\n                if nex not in exploredSet:\n                    dfs(nex,componentSize)\n                    \n        connectedComponentsSizes=[]\n        exploredSet=set()\n        for p in primeConnections.keys():\n            if p not in exploredSet:\n                componentSize=[0]\n                dfs(p,componentSize)\n                connectedComponentsSizes.append(componentSize[0])\n        ans=max(connectedComponentsSizes)\n        return ans", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A = set(A)\n        n = max(A)+1\n        p = [True]*n\n        p[0] = p[1] = False\n        dic1, dic2 = collections.defaultdict(set), collections.defaultdict(set)\n        for i in range(2, n):\n            if p[i]:\n                for j in range(i, n, i):\n                    p[j] = False if j != i else True\n                    if j in A:\n                        dic1[i].add(j)\n                        dic2[j].add(i)\n        \n        seen, res = set(), 0\n        for num in A:\n            if num not in seen:\n                seen.add(num)\n                cur, s = 0, [num]\n                while s:\n                    node = s.pop()\n                    cur +=1\n                    for m in dic2[node]:\n                        for nxt in dic1[m]:\n                            if nxt not in seen:\n                                seen.add(nxt)\n                                s.append(nxt)\n                        dic1.pop(m)\n                res = max(res, cur)\n        return res\n", "class DUS(object):\n    \n    def __init__(self, n):\n        self.p = [ *list(range(n)) ]\n        self.size = [1] * n\n        \n    def Find(self, x):\n        if self.p[x] == x:\n            return x\n        tmp = []\n        while self.p[x] != x:\n            tmp.append(x)\n            x = self.p[x]\n        for t in tmp:\n            self.p[t] = x\n        return x\n    \n    def Union(self, x, y):\n        xr = self.Find(x)\n        yr = self.Find(y)\n        if xr != yr:\n            self.p[yr] = xr\n            self.size[xr] += self.size[yr]\n            self.size[yr] = 0\n    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def PFD(num):\n            ret = set()\n            if num % 2 == 0:\n                ret.add(2)\n                while num % 2 == 0:\n                    num //= 2\n            for i in range(3, int(num ** 0.5)+1 , 2 ):\n                if num % i == 0:\n                    ret.add(i)\n                    while num % i == 0:\n                        num //= i\n            if num > 2:\n                ret.add(num)\n            return ret\n        \n        dic = {}\n        dus = DUS(len(A))\n        for idx, a in enumerate(A):\n            for p in PFD(a):\n                if p in dic:\n                    dus.Union(dic[p], idx)\n                dic[p] = idx\n        \n        return max(dus.size)\n        \n        \n", "class UFDS:\n    def __init__(self, n, nums):\n        self.p = list(range(n+1))\n        self.size = [0]*(n+1)\n        for num in nums:\n            self.size[num] = 1\n    \n    def find(self, n):\n        if n != self.p[n]:\n            self.p[n] = self.find(self.p[n])\n        return self.p[n]\n    \n    def union(self, i, j):\n        p1 = self.find(i)\n        p2 = self.find(j)\n        if p1 != p2:\n            if self.size[p1] > self.size[p2]:\n                self.p[p2] = p1\n                self.size[p1] += self.size[p2]\n            else:\n                self.p[p1] = p2\n                self.size[p2] += self.size[p1]                \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        hi = max(A)\n        ufds = UFDS(hi, A)\n        isPrime = [True]*(hi+1)\n        for i in range(2, hi+1):\n            if not isPrime[i]: continue\n            for j in range(2*i, hi+1, i):\n                isPrime[j] = False\n                if ufds.size[j]:\n                    ufds.union(i, j)\n        return max(ufds.size)\n", "class UnionFind(object):\n    def uf(self, n):\n        self.uf=[i for i in range(n)]\n        self.size = [1]*n\n       \n    def find(self, x):\n        while x!=self.uf[x]:\n            self.uf[x]=self.uf[self.uf[x]]\n            x=self.uf[x]\n        return self.uf[x]\n    \n    def union(self,x,y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root]=y_root\n        self.size[y_root]+=self.size[x_root]\n        self.size[x_root]=0\n        \nclass Solution:\n    def uf(self, n):\n        self.uf=[i for i in range(n)]\n        self.size = [1]*n\n        \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        def primeFactors(n): \n            out=set()\n            while n%2==0:\n                out.add(2)\n                n//=2\n            for i in range(3, int(math.sqrt(n))+1,2):\n                while n%i ==0:\n                    out.add(i)\n                    n//=i\n            if n>2:\n                out.add(n)\n            return out\n        \n        idx_lookup ={A[i]: i for i in range(len(A))} # in order to find idx in uf\n        uf=UnionFind()\n        uf.uf(len(A))\n        primeAndItsMultiples = collections.defaultdict(list) # {2: [4,6], 3: [6,15], 5: [15,35], 7:[35]}\n        \n        for i in A:\n            factors = primeFactors(i)\n            for f in factors:\n                primeAndItsMultiples[f].append(i)\n                \n        # we don't need to connec all the multiples of a prime,\n        # just use the first multiple as their root\n        for idx, multiples in list(primeAndItsMultiples.items()):\n            if multiples:\n                root=multiples[0] # use the first multiple as their root\n                for node in multiples[1:]:\n                    uf.union(idx_lookup[node], idx_lookup[root]) # connect node with root\n        return max(uf.size)\n", "class UnionFind(object):\n    def uf(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return self.uf[x]\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primeFactors(n):  # Prime factor decomposition\n            out = set()\n            while n % 2 == 0: \n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    out.add(i) \n                    n //= i \n            if n > 2: \n                out.add(n)\n            return out\n        \n        idx_lookup = {A[i]: i for i in range(len(A))} # in order to find idx in uf\n        uf = UnionFind()\n        uf.uf(len(A))\n        primeAndItsMultiples = collections.defaultdict(list) # {2: [4, 6], 3: [6, 15], 5: [15, 35], 7: [35]})\n        \n        for i in A:\n            factors = primeFactors(i)\n            for f in factors:\n                primeAndItsMultiples[f].append(i)\n\n        # we don't need to connect all the multiples of a prime, \n        # just use the first multiple as their root\n        for idx, multiples in list(primeAndItsMultiples.items()):\n            if multiples:\n                root = multiples[0] # use the first multiple as their root\n                for node in multiples[1:]:\n                    uf.union(idx_lookup[node], idx_lookup[root]) # connect node with root\n                    \n        return max(uf.size)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        graphs = {}\n\n        def prime_factors(n):\n            factors = set()\n            # Print the number of two's that divide n\n            while n % 2 == 0:\n                factors.add(2)\n                n = n // 2\n\n            # n must be odd at this point\n            # so a skip of 2 ( i = i + 2) can be used\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                # while i divides n , print i ad divide n\n                while n % i == 0:\n                    factors.add(i)\n                    n = n // i\n\n                    # Condition if n is a prime\n            # number greater than 2\n            if n > 2:\n                factors.add(n)\n            return factors\n\n        for num in A:\n            facts = prime_factors(num)\n\n            if num not in graphs:\n                graphs[num] = set()\n            for fact in facts:\n                if fact not in graphs:\n                    graphs[fact] = set()\n                graphs[fact].add(num)\n                graphs[num].add(fact)\n\n        groups, n_group = {}, 0\n\n        def dfs(factor, group_id):\n            groups[factor] = group_id\n            for next_factor in graphs[factor]:\n                if next_factor not in groups:\n                    dfs(next_factor, group_id)\n\n        for f in graphs:\n            if f not in groups:\n                n_group += 1\n                dfs(f, n_group)\n\n        group_count = {}\n        for num in A:\n            group_id = groups[num]\n            if group_id not in group_count:\n                group_count[group_id] = 0\n            group_count[group_id] += 1\n\n        return max(group_count.values())\n", "from typing import Deque, Dict, List, Set, Tuple\n'''\n952. Largest Component Size by Common Factor.  Hard\n\nGiven a non-empty array of unique positive integers A,\nconsider the following graph:\n\nThere are A.length nodes, labelled A[0] to A[A.length - 1];\nThere is an edge between A[i] and A[j] if and only if\nA[i] and A[j] share a common factor greater than 1.\nReturn the size of the largest connected component in the graph.\n\nExample 1:\nInput: [4,6,15,35]\nOutput: 4\n\nExample 2:\nInput: [20,50,9,63]\nOutput: 2\n\nExample 3:\nInput: [2,3,6,7,4,12,21,39]\nOutput: 8\n\nNote:\n1 <= A.length <= 20000\n1 <= A[i] <= 100000\n\nAccepted 18,093 / 53,552 submissions.\n'''\n\n\ndef gen_primes():\n    '''\n    Prime number generator, optimized to try only odd numbers.\n    How to populate a list with some range of generated values:\n        list(itertools.islice((p for p in gen_primes_opt()), beg_num, end_num)))\n    '''\n    yield 2                                     # return the first prime number\n    prime_divs = collections.defaultdict(list)  # map numbers to their prime divisors\n    candidate = 3\n    while True:\n        if candidate in prime_divs:\n            for prime_div in prime_divs[candidate]:\n                prime_divs[prime_div*2 + candidate].append(prime_div)\n            del prime_divs[candidate]           # sieve no longer needed for candidate\n        else:\n            yield candidate                     # yield the next prime number\n            prime_divs[candidate * candidate] = [candidate] # start sieve for sqaure\n        candidate += 2\n\n\n\nclass Solution:\n\n    def __init__(self):\n        self.prime_gen = gen_primes()\n        self.primes = [next(self.prime_gen) for _ in range(55)]\n\n\n    def get_primes(self, lower_bound: int) -> List[int]:\n        while self.primes[-1] < lower_bound:\n            self.primes.append(next(self.prime_gen))\n        return self.primes\n\n    def prime_fac_set(self, num: int):\n        pfs = set()\n        for prime in self.primes:\n            if num % prime == 0:\n                pfs.add(prime)\n\n            if prime >= num:\n                break\n        return pfs\n\n\n    def largestComponentSizeWip(self, A: List[int]) -> int:\n        return 0\n\n\n        pcomps = collections.defaultdict(set)\n        edges = collections.defaultdict(set)\n        for num in A:\n            pfs = self.prime_fac_set(num)\n            prv = None\n            for prime in pfs:\n                pcomps[prime].add(num)\n                if prv is None:\n                    prv = prime\n                else:\n                    edges[prv].add(prime)\n                    prv = prime\n        max_size = 0\n        print(edges)\n        for prm, num_set in list(pcomps.items()):\n            the_set = num_set\n            the_prm = prm\n            while the_prm in edges:\n                the_set.update(edges[the_prm])\n            max_size = max(max_size, len(the_set))\n\n\n        return max_size\n\n\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        '''\n        Step 1: get primes less than sqrt(max(A))\n        Step 2: compute factors for each number in A\n        Step 3: use union-find to link two primes\n                if they are factors of the same number in A\n        Step 4: for each number in A, add to its union\n                (the union represented by its smallest prime)\n                \n        Runtime: 1000 ms, faster than 99.35% of Python3 online submissions for Largest Component Size by Common Factor.\n        Memory Usage: 19.4 MB, less than 55.56% of Python3 online submissions for Largest Component Size by Common Factor.\n        '''\n        # primes = []\n        # for x in range(2, int(max(A)**0.5)+1):\n        #     for y in primes:\n        #         if x % y == 0:\n        #             break\n        #     else:\n        #         primes.append(x)\n\n        lowerb = int(max(A)**0.5) + 1\n        primes = self.get_primes(lowerb)\n\n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n\n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n\n        parent = [i for i in range(n)]                  # union-find on primes\n\n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n\n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n\n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "from math import sqrt, floor\n\nclass Solution:\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        def find(i, parent):\n            if parent[i] == i:\n                return i\n            return find(parent[i], parent)\n        \n        def union(i, j, parent, cnt):\n            p = find(i, parent)\n            q = find(j, parent)\n            if p == q:\n                return\n\n            if cnt[p] < cnt[q]:\n                p, q = q, p\n\n            cnt[p] += cnt[q]\n            parent[q] = p\n\n        m = max(A)\n        arr = [True] * (m + 1)\n        cnt = [1] * len(A)\n        parent = [*list(range(len(A)))]\n        \n        for i in range(2, floor(sqrt(m)) + 1):\n            if arr[i]:\n                k = -1\n                for j in range(len(A)):\n                    if A[j]%i == 0:\n                        while A[j]%i == 0:\n                            A[j] = floor(A[j]/i)\n                        if k == -1:\n                            k = j\n                        else:\n                            union(k, j, parent, cnt)\n                for j in range(i*i, m + 1, i):\n                    arr[j] = False\n        A = sorted([(x, i) for i, x in enumerate(A) if x > 1])\n        for i in range(1, len(A)):\n            if A[i-1][0]==A[i][0]:\n                union(A[i-1][1], A[i][1], parent, cnt)\n        \n        return max(cnt)\n", "class Solution:\n    def find(self, g,i):\n        # find the group id of element i\n        if i in g:   gid=g[i]\n        else: gid=g[i]=i\n            \n        if gid!=i:\n            new_gid=self.find(g,gid)\n            g[i]=new_gid\n        return g[i]\n            \n    def merge(self,g,i,j):\n        # merge two groups\n        gid=self.find(g,i)\n        gjd=self.find(g,j)\n        if gid!=gjd:\n            g[gid]=gjd\n\n    def prime_factors(self, x):\n        if x==1: return [1]\n        \n        primes=[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, \n               67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, \n               139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, \n               223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, \n               293, 307, 311, 313, 317 ]\n        \n        ans={x}\n        idx,p=0,primes[0]\n        while p*p<=x:\n            if x % p == 0:  \n                ans.add(p)\n                x//=p\n            else:\n                idx+=1\n                p=primes[idx]\n        if x>1: ans.add(x)\n        return ans\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        n=len(A)\n        print(n)\n        g=dict()\n        \n        for x in A:\n            pfs=list(self.prime_factors(x))\n            \n            for p in pfs[1:]:\n                self.merge(g, pfs[0], p)\n            \n        groups=[self.find(g,x) for x in A]\n        ans=collections.Counter(groups).most_common(1)\n        return ans[0][1]\n            \n        \n", "class UnionFind:\n  def __init__(self, nodes):\n    self.parents = [-1]* len(nodes)\n    self.map = {node: idx for idx, node in enumerate(nodes)}\n    \n  def find(self, node):\n    \n    idx = self.map[node]\n    \n    orig = idx\n    while(self.parents[idx] >= 0):\n      idx = self.parents[idx]\n      \n    parent, rank = idx, abs(self.parents[idx])\n    while(self.parents[orig] >= 0):\n      temp_parent = self.parents[orig]\n      self.parents[orig] = parent\n      orig = temp_parent\n    return parent, rank\n      \n  \n  def union(self, n1, n2):\n    idx1, idx2 = self.map[n1], self.map[n2]\n    parent1, rank1 = self.find(n1)\n    parent2, rank2 = self.find(n2)\n    \n    if parent1 == parent2:\n      return\n    \n    if rank1 >= rank2:\n      self.parents[parent1] -= rank2\n      self.parents[parent2] = parent1\n    else:\n      self.parents[parent2] -= rank1\n      self.parents[parent1] = parent2\n      \n  def get_max_rank(self):\n    return abs(min(self.parents))\n      \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        max_num = max(A)\n        primes_nodes = collections.defaultdict(set)\n        \n        def prime_factors(n):\n          original = n\n          result = set()\n          while n % 2 == 0: \n                 \n            n = n // 2\n            result.add(2)\n\n          # n must be odd at this point \n          # so a skip of 2 ( i = i + 2) can be used \n          for i in range(3,int(math.sqrt(n))+1,2): \n\n              # while i divides n , print i ad divide n \n              while n % i== 0: \n                  result.add(i)\n                  n = n // i \n\n          # Condition if n is a prime \n          # number greater than 2 \n          if n > 2: \n               result.add(n) \n              \n          return result\n          \n        uf_obj = UnionFind(A)\n        factor_first_multiple_map = {}\n        for node in A:\n          p_factors = prime_factors(node)\n          \n          for pf in p_factors:\n            #if pf already a prime factor of prev encountered num, union with that num the curr num\n            if pf in factor_first_multiple_map:\n              uf_obj.union(node, factor_first_multiple_map[pf])\n            else:\n              factor_first_multiple_map[pf] = node\n\n          \n        return uf_obj.get_max_rank()\n          \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5+1)):\n            #isPrime = True\n            for p in primes:\n                if x%p==0:\n                    isPrime = False\n                    break\n            else:\n                primes.append(x)\n                \n        factors = collections.defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p>x:\n                    break\n                if x%p == 0:\n                    factors[a].append(p)\n                    while x%p==0:\n                        x //= p\n            if x>1:\n                factors[a].append(x)\n                primes.append(x)\n        \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p:i for i,p in enumerate(primes)}\n        \n        parent = [i for i in range(n)]\n        \n        def find(i):\n            if i!=parent[i]:\n                parent[i]=find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi!=pj:\n                parent[pi]=pj\n        \n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    union(p2i[p0], p2i[p])\n                    \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])\n        \n        return max(count.values())\n", "from collections import defaultdict\n\nclass UnionFind:\n    def __init__(self, length):\n        self.parent = list(range(length))\n        self.size = [1] * length\n        \n    def find(self,i):\n        if self.parent[i] == i:\n            return i\n        if self.parent[i] != i:\n            return self.find(self.parent[i])\n\n    # A utility function to do union of two subsets\n    def union(self,x,y):\n        x_set, y_set = self.find(x), self.find(y)\n        if x_set == y_set:\n            return\n        self.parent[x_set] = y_set\n        self.size[y_set] += self.size[x_set]\n        self.size[x_set] = 0\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # brute force is look at each node and see if we can connect it to every other node\n        # after we are done connecting, we check every node and see keep track of longest path\n        \n        if len(A) <= 0:\n            return 0\n        \n        '''# key: node value\n        # values: list of connected components\n        nodes = defaultdict(list)\n        \n        gcf_cache = {}\n        def greatest_common_factor(a, b):\n            if (a,b) in gcf_cache:\n                return gcf_cache[(a,b)]\n            \n            if (b,a) in gcf_cache:\n                return gcf_cache[(b,a)]\n            \n            # euclidean algo\n            # Everything divides 0  \n            if (a == 0): \n                return b \n            if (b == 0): \n                return a \n\n            # base case \n            if (a == b): \n                return a \n\n            # a is greater \n            if (a > b): \n                gcf = greatest_common_factor(a-b, b)\n                gcf_cache[(a,b)] = gcf\n                gcf_cache[(b,a)] = gcf\n                return gcf\n            gcf = gcd(a, b-a)\n            gcf_cache[(a,b)] = gcf\n            gcf_cache[(b,a)] = gcf\n            return gcf\n        \n        def dfs(node):\n            visited = set()\n            stack = [(node,0)]\n            max_path = -float('inf')\n            while(stack):\n                current_node, current_path = stack.pop()\n                if current_node:\n                    visited.add(current_node)\n                    current_path += 1\n                    max_path = max(max_path, current_path)\n                    neighbors = nodes[current_node]\n\n                    for i in range(len(neighbors)):\n                        if neighbors[i] not in visited:\n                            stack.append((neighbors[i], current_path))\n            return max_path\n        \n        for i in range(len(A)):\n            for j in range(i+1, len(A)):\n                gcf = greatest_common_factor(A[i], A[j])\n                if gcf > 1:\n                    nodes[A[i]].append(A[j])\n                    nodes[A[j]].append(A[i])\n        \n        result = 1\n        for i in nodes.keys():\n            path = dfs(i)\n            print(path)\n            result = max(result, dfs(i))\n        return result'''\n        \n        # try union find\n        # reference: https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/200643/Python-1112-ms-beats-100-Union-Find-and-Prime-factor-decomposition-with-Optimization\n        def primeFactors(n):\n            out = set()\n            while n % 2 == 0: \n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    out.add(i) \n                    n //= i \n            if n > 2: \n                out.add(n)\n            return out\n        \n        uf = UnionFind(len(A))\n        \n        primeToIndex = {} \n        for i,a in enumerate(A):\n            primes = primeFactors(a)\n            for p in primes:\n                if p in primeToIndex:\n                    uf.union(i, primeToIndex[p])\n                primeToIndex[p] = i\n        return max(uf.size)\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n=len(A)\n        if n<2:\n            return n\n        A=set(A)\n        if 1 in A:\n            A.remove(1)\n        if len(A)==0:\n            return 1\n        #A=list(A)\n        #A.sort()\n        \n        def list_primes(m):\n            p=[True]*(m+1)\n            for i in range(2,m+1):\n                if p[i]:\n                    for j in range(2*i,m+1,i):\n                        p[j]=False\n            return [i for i in range(2,m+1) if p[i]]\n        \n        def find_prime_factors(x,prime_list,prime_set):\n            if x in prime_set:\n                return [x]\n            prime_factors=[]\n            for prime_num in prime_list:\n                if prime_num*prime_num>x:\n                    break\n                if x%prime_num==0:\n                    prime_factors.append(prime_num)\n                    while x%prime_num==0:\n                        x//=prime_num\n            if x!=1:\n                prime_factors.append(x)\n            return prime_factors\n        \n        def prime_decompose(x):\n            f=2\n            prime_factors=[]\n            while x>=f*f:\n                if x%f==0:\n                    prime_factors.append(f)\n                    x//=f\n                else:\n                    f+=1\n            prime_factors.append(x)\n            return prime_factors\n        #print(prime_decompose(60))\n        #print(prime_decompose(5120))\n        #return 0\n        \n        prime_list=list_primes(max(A))\n        prime_set=set(prime_list)\n        #print(prime_list)\n        d={x:find_prime_factors(x,prime_list,prime_set) for x in A}\n        #d={x:list(set(prime_decompose(x))) for x in A}\n        #print([len(d[x]) for x in A])\n        all_factors=set()\n        for x in A:\n            for f in d[x]:\n                all_factors.add(f)\n        #print(all_factors)\n        find_dict={f:f for f in all_factors}\n        sink_size={f:1 for f in all_factors}\n        def find(f):\n            if find_dict[f]!=f:\n                find_dict[f]=find(find_dict[f])\n            return find_dict[f]\n        \n        def union(fi,fj):\n            sink_i=find(fi)\n            sink_j=find(fj)\n            if sink_i==sink_j:\n                return\n            if sink_size[sink_i]>sink_size[sink_j]:\n                find_dict[sink_j]=sink_i\n                sink_size[sink_i]+=sink_size[sink_j]\n            else:\n                find_dict[sink_i]=sink_j\n                sink_size[sink_j]+=sink_size[sink_i]\n        \n        def union_hyperedge(hyperedge):\n            for i in range(1,len(hyperedge)):\n                union(hyperedge[i],hyperedge[0])\n            \n        def union_no_load_balance(hyperedge):\n            sink=find(hyperedge[0])\n            for f in hyperedge:\n                find_dict[find(f)]=sink\n                find(f)\n            \n        for x in A:\n            union_hyperedge(d[x])\n        #print('Union done.')\n        sinks=set()\n        for f in all_factors:\n            sinks.add(find(f))\n        \n        count={sink:0 for sink in sinks}\n        \n        for x in A:\n            count[find(d[x][0])]+=1\n        \n        return max(count.values())\n", "prime, idx = [2,3], [0,1,2,3]\ndef ensure(n):\n    n0 = len(idx)\n    if n <= n0: return\n    prime.extend([ x for i,x in enumerate(idx[prime[-1] + 1:], prime[-1] + 1)\n                 if i == x ])\n    idx.extend(range(n0, n))\n    for x in prime:\n        for j in range(max(x, (n0 - 1) // x + 1) * x, n, x): idx[j] = x\n    for i,x in enumerate(idx[n0:], n0):\n        if n <= i * i: break\n        if i != x: continue\n        prime.append(x)\n        for j in range(x * x, n, x): idx[j] = x\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        ensure(max(A) + 1)\n        best, src, dst, visited = 0, {}, {}, set()\n        for x in A:\n            x0, ps = x, set()\n            while x != 1:\n                p = idx[x]\n                if p not in ps:\n                    ps.add(p)\n                    if p in dst: dst[p].add(x0)\n                    else: dst[p] = {x0}\n                x //= p\n            if idx[x0] == x0: best = 1\n            else: src[x0] = ps\n        for p in dst:\n            if p in visited: continue\n            work, grp, xs = {p}, set(), set()\n            while work:\n                grp |= work\n                old, work = work, set()\n                for p in old:\n                    xs |= dst[p]\n                    for x in dst[p] - {p}: work |= src[x] - grp\n            visited |= grp\n            best = max(len(xs), best)\n        return best", "class DSU:\n  def __init__(self):\n    self.N = 0\n    self.map = {}\n    self.parent = []\n    self.count = []\n  \n  def __contains__(self, obj):\n    return obj in self.map\n  \n  def add(self, obj):\n    if obj in self:\n      return\n    i = self.N\n    self.N += 1\n    self.map[obj] = i\n    self.parent.append(i)\n    self.count.append(0)\n\n  def find(self, obj):\n    p = self.parent\n    \n    origI = self.map[obj]\n    \n    i = origI\n    while p[i] != i:\n      i = p[i]\n    root = i\n    \n    i = origI\n    while p[i] != i:\n        p[i], i = root, p[i]\n    \n    return root\n\n  def union(self, objA, objB):\n    rObjA = self.find(objA)\n    rObjB = self.find(objB)\n    if rObjA == rObjB:\n      return\n    self.count[rObjA] += self.count[rObjB]\n    self.parent[rObjB] = rObjA\n\n  def incCount(self, obj):\n    rObj = self.find(obj)\n    self.count[rObj] += 1\n    return self.count[rObj]\n\nclass Solution:\n  def largestComponentSize(self, nums) -> int:\n    UF = DSU()\n    max_ = 1\n    for num in nums:\n      if num == 1:\n        continue\n      pDs = self.primeDivisors(num)\n      pD0 = pDs.pop()\n      UF.add(pD0)\n      for pD in pDs:\n        UF.add(pD)\n        UF.union(pD0, pD)\n      count = UF.incCount(pD0)\n      max_ = max(max_, count)\n    return max_\n    \n  def primeDivisors(self, num: int):\n      x = num\n      \n      pDs = set()\n      \n      if x % 2 == 0:\n          pDs.add(2)\n          while x % 2 == 0:\n              x >>= 1\n          \n      if x % 3 == 0:\n          pDs.add(3)\n          while x % 3 == 0:\n              x //= 3\n      \n      div = 5\n      d2 = True\n      while x >= div*div:\n          if x % div == 0:\n              pDs.add(div)\n              while x % div == 0:\n                  x //= div\n          div += 2 if d2 else 4\n          d2 = not d2\n      \n      if x > 1:\n        pDs.add(x)\n      \n      return pDs\n", "class UnionFind(object):\n    def __init__(self, n, recursion = False):\n        self._par = list(range(n))\n        self._size = [1] * n\n        self._recursion = recursion\n\n    def root(self, k):\n        if self._recursion:\n            if k == self._par[k]:\n                return k\n            self._par[k] = self.root(self._par[k])\n            return self._par[k]\n        else:\n            root = k\n            while root != self._par[root]: root = self._par[root]\n            while k != root: k, self._par[k] = self._par[k], root\n            return root\n\n    def unite(self, i, j):\n        i, j = self.root(i), self.root(j)\n        if i == j: return False\n        if self._size[i] < self._size[j]: i, j = j, i\n        self._par[j] = i\n        self._size[i] += self._size[j]\n        return True\n\n    def is_connected(self, i, j):\n        return self.root(i) == self.root(j)\n\n    def size(self, k):\n        return self._size[self.root(k)]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        M = max(A)\n        \n        primes = []\n        sieve = list(range(M + 1))\n        for i in range(2, M + 1):\n            if sieve[i] == i:\n                primes.append(i)\n            for p in primes:\n                if i * p > M or sieve[i] < p:\n                    break\n                sieve[i * p] = p\n        \n        uf = UnionFind(n)\n        color = [-1] * (M + 1) \n        for i, a in enumerate(A):\n            while a != 1:\n                p = sieve[a]\n                if color[p] != -1:\n                    uf.unite(i, color[p])\n                else:\n                    color[p] = i\n                a //= p\n        \n        return max(uf.size(i) for i in range(n))", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5+1)):\n            isPrime = True\n            for p in primes:\n                if x%p==0:\n                    isPrime = False\n                    break\n            if isPrime:\n                primes.append(x)\n                \n        factors = collections.defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p>x:\n                    break\n                if x%p == 0:\n                    factors[a].append(p)\n                    while x%p==0:\n                        x //= p\n            if x>1:\n                factors[a].append(x)\n                primes.append(x)\n        \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p:i for i,p in enumerate(primes)}\n        \n        parent = [i for i in range(n)]\n        \n        def find(i):\n            if i!=parent[i]:\n                parent[i]=find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi!=pj:\n                parent[pi]=pj\n        \n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    union(p2i[p0], p2i[p])\n                    \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])\n        \n        return max(count.values())\n", "class Solution:\n    def largestComponentSize(self, nums: List[int]) -> int:\n        upper_p = max(nums)\n        is_prime = [1] * (upper_p + 1)\n        primes = []\n        for p in range(2, upper_p + 1):\n            if not is_prime[p]:\n                continue\n            primes.append(p)\n            for multi in range(2 * p, upper_p + 1, p):\n                is_prime[multi] = 0\n        primes_set = set(primes)\n        p_par = {p: p for p in primes}\n        p_cnt = {p: 0 for p in primes}\n        \n        def find_par(ind):\n            path = []\n            while p_par[ind] != ind:\n                path.append(ind)\n                ind = p_par[ind]\n            for mid in path:\n                p_par[mid] = ind\n                p_cnt[ind] += p_cnt[mid]\n                p_cnt[mid] = 0\n            return ind\n        \n        def union(p1, p2):\n            par1 = find_par(p1)\n            par2 = find_par(p2)\n            if par1 != par2:\n                p_par[par2] = par1\n                p_cnt[par1] += p_cnt[par2]\n                p_cnt[par2] = 0\n            return\n        \n        for num in nums:\n            if num == 1:\n                continue\n            factors = []\n            for p in primes:\n                if p * p > num:\n                    break\n                if num % p == 0:\n                    factors.append(p)\n                    while num % p == 0:\n                        num //= p\n            if num in primes_set:\n                factors.append(num)\n                \n            for other_p in factors[1:]:\n                union(factors[0], other_p)\n            p_cnt[find_par(factors[0])] += 1\n                                \n        return max(p_cnt.values())", "# class UnionFind:\n#     def __init__(self, nums):\n#         self.parents = {num: num for num in nums}\n#         self.ranks = {num: 1 for num in nums}\n    \n#     def find(self, src):\n#         if self.parents[src] == src:\n#             return src\n        \n#         self.parents[src] = self.find(self.parents[src])\n#         return self.parents[src]\n\n#     def union(self, src, dest):\n#         rootSrc, rootDest = self.find(src), self.find(dest)\n#         if rootSrc == rootDest:\n#             return -1\n        \n#         if self.ranks[rootSrc] > self.ranks[rootDest]:\n#             self.parents[rootDest] = rootSrc\n#             self.ranks[rootSrc] += self.ranks[rootDest]\n#             return self.ranks[rootSrc]\n#         else:\n#             self.parents[rootSrc] = rootDest\n#             self.ranks[rootDest] += self.ranks[rootSrc]\n#             return self.ranks[rootDest]\n        \n# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n#         def gcd(num1, num2):\n#             if num1 < num2:\n#                 return gcd(num2, num1)\n#             if num2 == 0:\n#                 return num1\n\n#             return gcd(num2, num1 % num2)\n\n#         uf = UnionFind(A)\n#         for i in range(len(A) - 1):\n#             for j in range(i + 1, len(A)):\n#                 if gcd(A[i], A[j]) > 1:\n#                     uf.union(A[i], A[j])\n#         return max(uf.ranks.values())\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        self.s=[1]*n\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n    \n    def unite(self,x,y): #x and y are roots\n        if self.s[x]<self.s[y]:\n            x,y=y,x\n        self.p[y]=x\n        self.s[x]+=self.s[y]\n        return x\n\nclass Solution:\n    M=100000\n    sieve=[0]*(M+1)\n    for i in range(2,M+1):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,M//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        n=len(A)        \n        g=UF(n)\n        primes=defaultdict(list)\n        for i,num in enumerate(A):\n            while num>1:\n                q=self.sieve[num]\n                primes[q].append(i)\n                while num%q==0:\n                    num//=q\n                    \n        for l in primes.values():\n            root=g.find(l[0])\n            for i in l[1:]:\n                node=g.find(i)\n                if node!=root:\n                    root=g.unite(root,node)\n        \n        return max(g.s)", "class Solution:\n    def largestComponentSize(self, nums: List[int]) -> int:\n        graph = defaultdict(list)\n        nodes = set(nums)\n        roots = set()\n        m, n = len(nums), max(nums)\n        primes = [True] * (n+1)\n        for i in range(2, n//2+1):\n            if not primes[i]:\n                continue\n            j = i*2\n            while j <= n:\n                primes[j] = False\n                if j in nodes:\n                    graph[i].append(j)\n                    graph[j].append(i)\n                    roots.add(i)\n                j += i\n        # print(graph)\n        ans = self.traverse(graph, roots, nodes)\n        # print(ans)\n        return max(ans)\n        \n        \n    def traverse(self, graph, roots, real_nodes):\n        counts = []\n        vztd = set()\n        for node in roots:\n            if node in vztd:\n                continue\n            cnt = 0\n            vztd.add(node)\n            q = [node]\n            while q:\n                next_q = []\n                for n in q:\n                    if n in real_nodes:\n                        cnt += 1\n                    for nab in graph[n]:\n                        if nab not in vztd:\n                            vztd.add(nab)\n                            next_q.append(nab)\n                q = next_q \n            counts.append(cnt)\n        return counts", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # discuss\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def find(v):\n            if parent[v] != v:\n                parent[v] = find(parent[v])\n            return parent[v]\n\n        def union(v1, v2):\n            p1 = find(v1)\n            p2 = find(v2)\n            if p1 not in rank:\n                rank[p1] = 0\n            if p2 not in rank:\n                rank[p2] = 0\n            if p1 != p2:\n                if rank[p1] > rank[p2]:\n                    parent[p2] = p1\n                else:\n                    parent[p1] = p2\n                    if rank[p1] == rank[p2]:\n                        rank[p2] += 1\n                        \n        def sieve(n):\n            primes = [True] * (n + 1)\n            p = 2\n            while p * p <= n:\n                if primes[p]:\n                    for i in range(p * 2, n + 1, p):\n                        primes[i] = False\n                p += 1\n            return [element for element in range(2, n) if primes[element]]\n\n        rank = {}\n        primes = sieve(max(A) // 2 + 1)\n        parent = {i: i for i in A + primes}\n        for num in A:\n            up = int(sqrt(num))\n            t = num\n            for p in primes:\n                if p > up:\n                    break\n                if num % p == 0:\n                    union(num, p)\n                while t % p == 0:\n                    t //= p\n            if t > 1:\n                union(num, t)\n\n        return max(Counter([find(n) for n in A]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        N = len(A)\n        maxi = max(A)\n        p = [i for i in range(N)]\n        size = [1] * N\n        ret = 1\n        primes, isPrime = [], [True] * (maxi + 1)\n        for i in range(2, maxi + 1):\n            if isPrime[i]: \n                primes.append(i)\n                for j in range(2, maxi // i + 1):\n                    isPrime[i * j] = False\n        prime2Id = {}\n        def find(x):\n            if p[x] != x: p[x] = find(p[x])\n            return p[x]\n        def union(x, y):\n            nonlocal ret\n            px, py = find(x), find(y)\n            if px == py: return\n            p[py] = px\n            size[px] += size[py]\n            size[py] = 0\n            ret = max(ret, size[px])\n            \n        for i in range(N):\n            a = A[i]\n            for f in primes:\n                if isPrime[a]:\n                    if a in prime2Id: \n                        union(prime2Id[a], i)\n                    prime2Id[a] = i\n                    break \n                if f*f > A[i]: break\n                if a % f == 0:\n                    if f in prime2Id: \n                        union(prime2Id[f], i)\n                    prime2Id[f] = i\n                    while a % f == 0: a //= f\n                if a == 1: break\n        \n        return ret\n        \n", "class UF(object):\n    def __init__(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return x\n\n    def union(self, x, y):  \n        xr = self.find(x)\n        yr = self.find(y)\n        if xr == yr:\n            return\n        self.uf[xr] = yr\n        self.size[yr] += self.size[xr]\n        self.size[xr] = 0\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pf(n):\n            F = set()\n            if n % 2 == 0:\n                F.add(2)\n                while n % 2 == 0:\n                    n //= 2\n            for f in range(3,int(n**0.5)+1,2):\n                if n % f == 0:\n                    F.add(f)\n                    while n % f == 0:\n                        n //= f\n            if n > 1:\n                F.add(n)\n            return F\n        \n        \n        uf = UF(len(A))\n        \n        pd = {}\n        for i,a in enumerate(A):\n            F = pf(a)\n            print((a, F))\n            for p in F:\n                if p in pd:\n                    uf.union(i, pd[p])\n                pd[p] = i\n        \n        return max(uf.size)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n=len(A)\n        if n<2:\n            return n\n        A=set(A)\n        if 1 in A:\n            A.remove(1)\n        if len(A)==0:\n            return 1\n        \n        def list_primes(m):\n            p=[True]*(m+1)\n            for i in range(2,m+1):\n                if p[i]:\n                    for j in range(2*i,m+1,i):\n                        p[j]=False\n            return [i for i in range(2,m+1) if p[i]]\n        \n        def find_prime_factors(x,prime_list,prime_set):\n            if x in prime_set:\n                return [x]\n            prime_factors=[]\n            for prime_num in prime_list:\n                if prime_num*prime_num>x:\n                    break\n                if x%prime_num==0:\n                    prime_factors.append(prime_num)\n                    while x%prime_num==0:\n                        x//=prime_num\n            if x!=1:\n                prime_factors.append(x)\n            return prime_factors\n        \n        prime_list=list_primes(max(A))\n        prime_set=set(prime_list)\n        d={x:find_prime_factors(x,prime_list,prime_set) for x in A}\n        \n        all_factors=set()\n        for x in A:\n            for f in d[x]:\n                all_factors.add(f)\n                \n        find_dict={f:f for f in all_factors}\n        sink_size={f:1 for f in all_factors}\n        def find(f):\n            if find_dict[f]!=f:\n                find_dict[f]=find(find_dict[f])\n            return find_dict[f]\n        \n        def union(fi,fj):\n            sink_i=find(fi)\n            sink_j=find(fj)\n            if sink_i==sink_j:\n                return\n            if sink_size[sink_i]>sink_size[sink_j]:\n                find_dict[sink_j]=sink_i\n                sink_size[sink_i]+=sink_size[sink_j]\n            else:\n                find_dict[sink_i]=sink_j\n                sink_size[sink_j]+=sink_size[sink_i]\n        \n        def union_hyperedge(hyperedge):\n            for i in range(1,len(hyperedge)):\n                union(hyperedge[i],hyperedge[0])\n                        \n        for x in A:\n            union_hyperedge(d[x])\n            \n        sinks=set()\n        for f in all_factors:\n            sinks.add(find(f))\n        \n        count={sink:0 for sink in sinks}\n        \n        for x in A:\n            count[find(d[x][0])]+=1\n        \n        return max(count.values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pfactorization(a):\n            N = a\n            if a >= 2 and a % 2 == 0:   #treat 2 alone\n                Gp[2].append(N)\n                Gn[N].append(2)\n                while a % 2 == 0:   a //= 2\n            for d in range(3, math.floor(a**(1/2)) + 1, 2): #possible odd numbers\n                if d > a:   break\n                if a % d == 0:\n                    Gn[N].append(d)\n                    Gp[d].append(N)\n                    while a % d == 0:   a //= d\n            if a > 1:   #check if what remains is itself a prime\n                Gp[a].append(N)\n                Gn[N].append(a)\n        def dfs(curr):\n            if curr in seenNodes:   return 0\n            seenNodes.add(curr)\n            total = 1\n            for p in Gn[curr]:\n                if p in seenPrimes: continue\n                seenPrimes.add(p)\n                for owner in Gp[p]: total += dfs(owner)\n            return total\n        Gp = collections.defaultdict(list)\n        Gn = collections.defaultdict(list)\n        for a in A: pfactorization(a)   #build our graphs\n        seenPrimes, seenNodes = set(), set()\n        return max([dfs(a) for a in A])\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        rank = {i: 1 for i in range(len(A))}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                if rank[px] > rank[py]:\n                    px, py = py, px\n                rank[py] += rank[px]\n                uf[px] = py\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2: x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k:\n                    ans.add(k)\n                    while not x % k: x //= k\n                if x == 1: break\n            if x > 1: ans.add(x)\n            return ans\n                \n        dic = {}\n        for i in range(len(A)):\n            for k in primeFactor(A[i]):\n                dic.setdefault(k, i)\n                union(i, dic[k])\n        # print(rank)\n        return max(Counter([find(i) for i in range(len(A))]).values())", "class UnionFind:\n    def __init__(self):\n        self.rblong = dict() # aRe BeLong to\n        \n    def find(self, n):\n        if n not in self.rblong:\n            self.rblong[n] = n\n            return n\n        \n        if n == self.rblong[n]:\n            return n\n        \n        self.rblong[n] = self.find(self.rblong[n])\n        return self.rblong[n]\n    \n    def union(self, n1, n2):\n        u1, u2 = self.find(n1), self.find(n2)\n        if u1 == u2:\n            return\n        \n        self.rblong[u1] = u2\n        return\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind()\n        prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313]\n    \n        for num in A:\n            if num == 1:\n                continue\n            \n            num2 = num\n            for i in prime:\n                if num2 < i:\n                    break\n                    \n                if num2 % i == 0:\n                    uf.union(num2, i)\n                    num2 = num2 // i\n                    if num2 > 1:\n                        uf.union(num2, i)\n                    while num2 % i == 0:\n                        num2 = num2 // i\n                        if num2 > 1:\n                            uf.union(num2, i)\n        \n            if num2 > 1:\n                uf.union(num, num2)\n                            \n        #print(uf.rblong)\n        count = dict()\n        for num in A:\n            tmp = uf.find(num)\n            #print('num == {}, tmp == {}'.format(num, tmp))\n        \n            if tmp not in count:\n                count[tmp] = 1\n            \n            else:\n                count[tmp] += 1\n                            \n        return max(count.values())", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        self.s=[1]*n\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    sieve=[0]*100001\n    for i in range(2,100001):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,100000//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        # def add_prime(q,i,primes):\n        #     if q not in primes:\n        #         primes[q]=[i]\n        #     else:\n        #         primes[q].append(i)\n        n=len(A)        \n        g=UF(n)\n        primes=defaultdict(list)\n        for i,num in enumerate(A):\n            while num>1:\n                q=self.sieve[num]\n                primes[q].append(i)\n                while num%q==0:\n                    num//=q\n        # print(primes)\n        for l in primes.values():\n            j,r=l[0],g.find(l[0])\n            for i in l[1:]:\n                nd=g.find(i)\n                if nd!=r:\n                    g.p[nd]=r\n                    g.s[r]+=g.s[nd]\n        \n        return max(g.s)", "import math\nfrom functools import lru_cache\n\n\n@lru_cache(None)\ndef get_primes(n):\n    for i in range(2, int(math.sqrt(n)) + 1):\n        if n % i == 0:\n            return get_primes(n // i) | set([i])\n        \n    return set([n])\n\n\nclass DSU:\n    def __init__(self, n):\n        self.store = list(range(n))\n        \n    def find(self, i):\n        assert 0 <= i < len(self.store)\n        \n        if i != self.store[i]:\n            self.store[i] = self.find(self.store[i])\n            \n        return self.store[i]\n    \n    def union(self, x, y):\n        x_idx = self.find(x)\n        y_idx = self.find(y)\n        \n        self.store[y_idx] = x_idx\n\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        \n        common_primes = defaultdict(list)\n        for i, num in enumerate(a):\n            for prime in get_primes(num):\n                common_primes[prime].append(i)\n                \n        # print(common_primes)\n        \n        dsu = DSU(len(a))\n        \n        for idxs in list(common_primes.values()):\n            for i in range(len(idxs) - 1):\n                dsu.union(idxs[i], idxs[i+1])\n                \n        return Counter(dsu.find(i) for i in range(len(a))).most_common(1)[0][1]\n                \n", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factor(n):\n            f = []\n            while True:\n                for i in range(2, int(math.sqrt(n)) + 1):\n                    if n % i == 0:\n                        f.append(i)\n                        n //= i\n                        break\n                else:\n                    f.append(n)\n                    break\n            return f\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            for f in factor(a):\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        def pfactorization(a):\n            N = a\n            if a >= 2 and a % 2 == 0:   #treat 2 alone\n                Gp[2].append(N)\n                Gn[N].append(2)\n                while a % 2 == 0:   a //= 2\n            for d in range(3, math.floor(a**(1/2)) + 1, 2): #possible odd numbers\n                if d > a:   break\n                if a % d == 0:\n                    Gn[N].append(d)\n                    Gp[d].append(N)\n                    while a % d == 0:   a //= d\n            if a > 1:   #check if what remains is itself a prime\n                Gp[a].append(N)\n                Gn[N].append(a)\n        def dfs(curr):\n            if curr in seenNodes:   return 0\n            seenNodes.add(curr)\n            total = 1\n            for p in Gn[curr]:\n                if p in seenPrimes: continue\n                seenPrimes.add(p)\n                for owner in Gp[p]: total += dfs(owner)\n            return total\n        Gp = collections.defaultdict(list)\n        Gn = collections.defaultdict(list)\n        for a in A: pfactorization(a)   #build our graphs\n        seenPrimes, seenNodes = set(), set()\n        return max([dfs(a) for a in A])", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent, size = {x: x for x in A}, {x: 1 for x in A}\n        \n        def find(a):\n            if parent[a] != a:\n                parent[a] = find(parent[a])\n            return parent[a]\n        \n        def union(a, b):\n            if b not in parent:\n                parent[b] = b\n                size[b] = 0\n            x, y = find(a), find(b)\n            if x != y:\n                if size[x] < size[y]:\n                    x, y = y, x\n                parent[y] = x\n                size[x] += size[y]\n\n        for x in A:\n            num = x\n            if not(x & 1):\n                union(x, -2)\n                x >>= 1\n                while not(x & 1):\n                    x >>= 1\n            i = 3\n            while i*i <= x:\n                if x % i == 0:\n                    union(num, -i)\n                    while x % i == 0:\n                        x //= i\n                i += 2\n            if x > 1:\n                union(num, -x)\n        \n        return max(size.values())\n", "from collections import defaultdict\n\nclass UnionFind():\n    def __init__(self, n):\n        self.n = n\n        self.parents = [-1] * n\n\n    def find(self, x):\n        if self.parents[x] < 0:\n            return x\n        else:\n            self.parents[x] = self.find(self.parents[x])\n            return self.parents[x]\n\n    def union(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        if x == y:\n            return\n        if self.parents[x] > self.parents[y]:\n            x, y = y, x\n        self.parents[x] += self.parents[y]\n        self.parents[y] = x\n\n    def size(self, x):\n        return -self.parents[self.find(x)]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def prime_factorize(n):\n            a = set()\n            while n % 2 == 0:\n                a.add(2)\n                n //= 2\n            f = 3\n            while f * f <= n:\n                if n % f == 0:\n                    a.add(f)\n                    n //= f\n                else:\n                    f += 2\n            if n != 1:\n                a.add(n)\n            return a\n\n        uf = UnionFind(len(A))\n        res = 0\n        primes = defaultdict(list)\n\n        for i, a in enumerate(A):\n            for p in prime_factorize(a):\n                primes[p].append(i)\n\n        for _, indices in primes.items():\n            i0 = indices[0]\n            for i1 in indices[1:]:\n                uf.union(i0, i1)\n\n        return -min(uf.parents)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(len(A))\n        prime_index = {}\n        for i, n in enumerate(A):\n            pfs = get_prime_factors(n)\n            for p in pfs:\n                if p in prime_index:\n                    uf.union(i, prime_index[p])\n                prime_index[p] = i\n        return max(uf.size)\nclass UnionFind:\n    def __init__(self, N):\n        self.uf = [i for i in range(N)]\n        self.size = [1] * N\n    \n    def find(self, x):\n        while x != self.uf[x]:\n            x = self.uf[x]\n        return x\n    \n    def union(self, x, y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n\n        if x_root == y_root:\n            return\n        \n        if self.size[x_root] > self.size[y_root]:\n            self.uf[y_root] = x_root\n            self.size[x_root] += self.size[y_root]\n            self.size[y_root] = 0\n        else:\n            self.uf[x_root] = y_root\n            self.size[y_root] += self.size[x_root]\n            self.size[x_root] = 0\n\ndef get_prime_factors(n):\n    prime_factors = set()\n    while n % 2 == 0:\n        prime_factors.add(2)\n        n //=2\n    \n    for d in range(3, int(math.sqrt(n))+1, 2 ):\n        while n % d == 0:\n            prime_factors.add(d)\n            n //= d\n    \n    if n > 2:\n        prime_factors.add(n)\n\n    return prime_factors", "class Solution:\n    def primeFactors(self, n):\n        pset = set()\n        # While n is even, divide by two\n        while n % 2 == 0:\n            pset.add(2)\n            n = n // 2\n        \n        # For every odd i between 3 and sqrt(n), check if it's a factor\n        for i in range(3, int(math.sqrt(n))+1, 2):\n            while n % i == 0:\n                pset.add(i)\n                n = n // i\n        \n        # If n is still greater than 2, it's a prime\n        if n > 2:\n            pset.add(n)\n            \n        return pset\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        # Creates a disjoint set (union find) for the list A\n        ds = DisjointSet(A)\n        \n        # Dict to keep the index of the disjoint set root for every prime divisor set found\n        primeRoots = {}\n        \n        # Iterate over A and find it's prime divisors\n        for i, a in enumerate(A):\n            primes = self.primeFactors(a)\n            # For every prime, set the index of a as it's root\n            for p in primes:\n                # If already have a set for this prime, join the current element to it\n                if p in primeRoots:\n                    ds.union(i, primeRoots[p])\n                primeRoots[p] = i\n\n        return max(ds.sizes)\n    \n\nclass DisjointSet:\n    def __init__(self, elements):\n        self.parents = [x for x in range(len(elements))]\n        self.sizes = [1] * len(elements)\n        \n    # Path splitting find algorithm.\n    def find(self, x):\n        while x != self.parents[x]:\n                x, self.parents[x] = self.parents[x], self.parents[self.parents[x]]\n        return x\n        \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return px\n        \n        if self.sizes[px] > self.sizes[py]:\n            py, px = px, py\n            \n        self.parents[px] = py\n        self.sizes[py] += self.sizes[px]", "class UF:\n    def __init__(self, n):\n        self.f = list(range(n))\n        self.cc = [1] * n\n        \n    def find(self, x):\n        while x != self.f[x]: # while, not if\n            x = self.f[x]\n        return x\n\n    def union(self, x, y):\n        fx, fy = self.find(x), self.find(y)\n        if fx != fy: #\n            if self.cc[fx] <= self.cc[fy]: # path compression?\n                self.f[fx] = fy\n                self.cc[fx], self.cc[fy] = 0, self.cc[fx] + self.cc[fy]\n            else:\n                self.f[fy] = fx\n                self.cc[fy], self.cc[fx] = 0, self.cc[fx] + self.cc[fy]\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        n = len(A)\n        uf = UF(n)\n        \n        '''\n        def gcd(a, b):\n            while b != 0:\n                a, b = b, a % b\n            return a\n        \n        for i in range(n):\n            for j in range(n):\n                if i == j:\n                    continue\n                if gcd(A[i], A[j]) > 1:\n                    uf.union(i, j)\n        '''\n        def getPrimeSets(num, num2primes):\n            if num2primes[num]:\n                return num2primes[num]\n            \n            for i in range(2, int(math.sqrt(num)) + 1):\n                if num % i == 0:\n                    num2primes[num] = getPrimeSets(i, num2primes) | getPrimeSets(num // i, num2primes)\n                    return num2primes[num]\n                \n            num2primes[num] = set([num]) # num is prime\n            return num2primes[num]\n            \n        num2primes = collections.defaultdict(set)\n        for num in sorted(A):\n            getPrimeSets(num, num2primes)\n        \n        prime2numIdxs = collections.defaultdict(list)\n        for idx, num in enumerate(A):\n            ps = num2primes[num]\n            for p in ps:\n                prime2numIdxs[p].append(idx)\n                \n        for _, idxs in list(prime2numIdxs.items()):\n            for i in range(len(idxs) - 1):\n                uf.union(idxs[i], idxs[i+1])\n            \n        # print(uf.f)\n        # print(uf.cc)\n        res = 1\n        for i in range(n):\n            res = max(uf.cc[i], res)\n        return res\n", "from collections import defaultdict\nfrom math import sqrt\nclass DSU(object):\n    def __init__(self, n):\n        self.ds = list(range(n))\n    \n    \n    def find(self, v):\n        if self.ds[v] != v:\n            self.ds[v] = self.find(self.ds[v])\n        return self.ds[v]\n\n    def union(self, p1, p2):\n        pp1, pp2 = self.find(p1), self.find(p2)\n        self.ds[pp1] = pp2\n    \nclass Solution(object):    \n    def uniqPrime(self, n):\n        l = []\n        while n % 2 == 0:\n            l.append(2)\n            n = n//2\n        \n        for i in range(3, int(sqrt(n)) + 1, 2):\n            while n % i == 0:\n                l.append(i)\n                n = n//i\n        if n > 2:\n            l.append(n)\n        \n        return list(set(l))\n        \n    def largestComponentSize(self, A):\n        primes = defaultdict(list)\n        n = len(A)\n        for i in range(n):\n            p = self.uniqPrime(A[i])\n            for x in p:\n                primes[x].append(i)\n        \n        #now we need to merge the disjoint sets and see which is the longest\n        uf = DSU(n)\n        for i in list(primes.items()):\n            vals = i[1]\n            for j in range(len(vals) - 1):\n                uf.union(vals[j], vals[j+1])\n        \n        return max(Counter([uf.find(i) for i in range(n)]).values())\n# class Dis_set_node:\n#     def __init__(self):\n#         self.parent = None\n#         self.size = 1\n        \n# class Dis_set:\n#     def __init__(self):\n#         self.forest = {}\n        \n#     def addSet(self, node, key):\n#         self.forest[key] = node\n        \n#     def find(self, p):\n#         while self.forest[p].parent is not None:\n#             self.forest[p].parent = self.forest[self.forest[p].parent].parent\n#             p = self.forest[p].parent\n        \n#         return p\n    \n#     def union(self, x, y):\n#         x = self.find(x)\n#         y = self.find(y)\n        \n#         if x != y:\n#             if self.forest[x].size < self.forest[y].size:\n#                 x, y = y, x\n            \n#             self.forest[y].parent = x\n#             self.forest[x].size += self.forest[y].size\n            \n\n# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n#         prime_factors = {key:value for key, value in zip([n for n in A], [[] for _ in range(len(A))])}\n        \n#         up_to = max(A)\n        \n#         primes = set()\n#         comps = set()\n        \n#         for i in range(2, up_to + 1):\n#             if i not in comps:\n#                 primes.add(i)\n#                 comp = i * 2\n                \n#                 if i in prime_factors:\n#                         prime_factors[i].append(i)\n                \n#                 while comp <= up_to:\n#                     comps.add(comp)\n                    \n#                     if comp in prime_factors:\n#                         prime_factors[comp].append(i)\n                        \n#                     comps.add(comp)\n#                     comp += i \n        \n#         djus = Dis_set()\n        \n#         for p in primes:\n#             djus.addSet(Dis_set_node(), p)\n            \n#         for pf in prime_factors.values():\n#             if not pf:\n#                 continue\n            \n#             for p1, p2 in zip(pf, pf[1:]):\n#                 djus.forest[djus.find(p1)].size += 1\n#                 djus.union(p1, p2)\n                \n            \n#         print([node.size for node in djus.forest.values()])\n        \n        \n        \n        # print(self.prime_factors)\n        \n#         groups = []\n        \n#         for n in A:\n#             i = 0\n#             to_merge = []\n            \n#             while i < len(groups):\n#                 if groups[i][0] & (self.prime_factors[n]):\n#                     to_merge.append(groups.pop(i))\n#                 else:\n#                     i += 1\n                    \n#             to_add = [self.prime_factors[n], 1]\n            \n            \n#             for merge in to_merge:\n#                 to_add = [merge[0] | to_add[0], merge[1] + to_add[1]]\n                    \n                \n#             groups.append(to_add)\n            \n\n                \n\n#         return max(groups, key=lambda x:x[1])[1]\n        \n        \n                \n#     def seive(self, up_to):\n#         primes = set()\n#         comps = set()\n        \n#         for i in range(2, up_to + 1):\n#             if i not in comps:\n#                 primes.add(i)\n#                 comp = i * 2\n                \n#                 if i in self.prime_factors:\n#                         self.prime_factors[i].add(i)\n                \n#                 while comp <= up_to:\n#                     comps.add(comp)\n                    \n#                     if comp in self.prime_factors:\n#                         self.prime_factors[comp].add(i)\n                        \n#                     comps.add(comp)\n#                     comp += i\n        \n#         return primes\n        \n", "import math\nfrom collections import defaultdict\n\nclass UnionFind():\n    def __init__(self, n):\n        self.n = n\n        self.parents = [-1] * n\n\n    def find(self, x):\n        if self.parents[x] < 0:\n            return x\n        else:\n            self.parents[x] = self.find(self.parents[x])\n            return self.parents[x]\n\n    def union(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n\n        if x == y:\n            return\n\n        if self.parents[x] > self.parents[y]:\n            x, y = y, x\n\n        self.parents[x] += self.parents[y]\n        self.parents[y] = x\n\n    def size(self, x):\n        return -self.parents[self.find(x)]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def prime_factorize(n):\n            a = []\n            while n % 2 == 0:\n                a.append(2)\n                n //= 2\n            f = 3\n            while f * f <= n:\n                if n % f == 0:\n                    a.append(f)\n                    n //= f\n                else:\n                    f += 2\n            if n != 1:\n                a.append(n)\n            return a\n\n        uf = UnionFind(len(A))\n        res = 0\n        primes = defaultdict(list)\n        \n        for i, a in enumerate(A):\n            for p in set(prime_factorize(a)):\n                primes[p].append(i)\n\n        for _, indices in primes.items():\n            i0 = indices[0]\n            for i1 in indices[1:]:\n                uf.union(i0, i1)\n\n        return -min(uf.parents)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        cnt = dict([(num, 1) for num in A])\n        par = dict([(num, num) for num in A])\n \n        def find(num):\n            nonlocal par\n            if par[num] != num:\n                par[num] = find(par[num])\n            return par[num]\n \n        def union(num, num2):\n            root, root2 = find(num), find(num2)\n            if root == root2:\n                return\n            if root > root2:\n                root, root2 = root2, root\n            par[root2] = root\n            cnt[root] = cnt[root] + cnt[root2]\n            cnt[root2] = 0\n \n        primes = [2]\n        i = 3\n        maxA = max(A)\n        while i*i <= 100000:\n            is_prime = True\n            for prime in primes:\n                if i % prime == 0:\n                    is_prime = False\n                    break\n            if is_prime:\n                primes.append(i)\n            i += 1\n        A = sorted(A)\n        prime_set = {}\n        for num in A:\n            prime_set[num] = set()\n            tmp = num\n            for prime in primes:\n                can_div = False\n                while tmp % prime == 0:\n                    tmp /= prime\n                    can_div = True\n                if can_div:\n                    prime_set[num].add(prime)\n                if prime*prime > num:\n                    break\n            if tmp > 1:\n                prime_set[num].add(tmp)\n        prime_nums = {}\n        for num in prime_set:\n            for p in prime_set[num]:\n                prime_nums.setdefault(p, [])\n                prime_nums[p].append(num)\n\n        for prime, nums in prime_nums.items():\n            roots = set(find(num) for num in nums)\n            if len(roots) <= 1: continue\n            roots = sorted(list(roots))\n            for root in roots[1:]:\n                union(roots[0], root)\n        return max(cnt.values())", "class UF:\n    def __init__(self, n):\n        self.f = list(range(n))\n        self.cc = [1] * n\n        \n    def find(self, x):\n        while x != self.f[x]: # while, not if\n            x = self.f[x]\n        return x\n\n    def union(self, x, y):\n        fx, fy = self.find(x), self.find(y)\n        if fx != fy: #\n            if self.cc[fx] <= self.cc[fy]: # path compression?\n                self.f[fx] = fy\n                self.cc[fx], self.cc[fy] = 0, self.cc[fx] + self.cc[fy]\n            else:\n                self.f[fy] = fx\n                self.cc[fy], self.cc[fx] = 0, self.cc[fx] + self.cc[fy]\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        n = len(A)\n        uf = UF(n)\n        \n        '''\n        # TLE\n        def gcd(a, b):\n            while b != 0:\n                a, b = b, a % b\n            return a\n        \n        for i in range(n):\n            for j in range(n):\n                if i == j:\n                    continue\n                if gcd(A[i], A[j]) > 1:\n                    uf.union(i, j)\n        '''\n        \n        def getPrimeSets(num, num2primes):\n            if num2primes[num]:\n                return num2primes[num]\n            \n            for i in range(2, int(math.sqrt(num)) + 1):\n                if num % i == 0:\n                    num2primes[num] = getPrimeSets(i, num2primes) | getPrimeSets(num // i, num2primes)\n                    return num2primes[num]\n                \n            num2primes[num] = set([num]) # num is prime\n            return num2primes[num]\n            \n        num2primes = collections.defaultdict(set)\n        for num in sorted(A):\n            getPrimeSets(num, num2primes)\n        \n        prime2numIdxs = collections.defaultdict(list)\n        for idx, num in enumerate(A):\n            ps = num2primes[num]\n            for p in ps:\n                prime2numIdxs[p].append(idx)\n                \n        for _, idxs in list(prime2numIdxs.items()):\n            for i in range(len(idxs) - 1):\n                uf.union(idxs[i], idxs[i+1])\n            \n        # print(uf.f)\n        # print(uf.cc)\n        res = 1\n        for i in range(n):\n            res = max(uf.cc[i], res)\n        return res\n", "class DSU:\n    def __init__(self,n):\n        self.sets=list(range(n))\n        self.sizes=[1]*n\n    \n    def union(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        if x!=y:\n            if self.sizes[x]<self.sizes[y]:\n                x,y=y,x\n            self.sets[y]=x\n            self.sizes[x]+=self.sizes[y]\n        \n    def find(self,x):\n        group = self.sets[x]\n        \n        while group!=self.sets[group]:\n            group=self.sets[group]\n        self.sets[x]=group\n        return group\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n       \n        f={}\n        for a in A:\n            factors=[]\n            _a = a\n            for prime in primes:\n                if prime*prime>a:\n                    break\n                if a%prime==0:\n                    factors.append(prime)\n                while a%prime==0:\n                    a//=prime\n            if a>1:\n                factors.append(a)\n                primes.append(a)\n            f[_a]=factors\n            \n        # print(f)\n        prime_lookup={p:i for i,p in enumerate(primes)}\n        dsu = DSU(len(primes))\n        for n,prime_factors in list(f.items()):\n            if prime_factors:\n                p0=prime_factors[0]\n            for prime in prime_factors[1:]:\n                dsu.union(prime_lookup[p0],prime_lookup[prime])\n        counter = collections.Counter(dsu.find(prime_lookup[f[a][0]]) for a in A if f[a]) \n        return max(counter.values())\n        \n                    \n", "import math\nclass UnionFind():\n    def __init__(self, n):  \n        self.uf = [i for i in range(n)] \n        self.size = [1] * n\n         \n    def find(self, x):     \n        if self.uf[x] != x:\n            self.uf[x] = self.find(self.uf[x])\n        return self.uf[x]\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        d = {}\n        uf = UnionFind(len(A))\n        \n        for indx, num in enumerate(A):\n            primes = self.primeFactors(num)\n            for prime in primes:\n                if prime in d:\n                    uf.union(indx, d[prime])\n                d[prime] = indx\n        return max(uf.size)\n    \n    def primeFactors(self, n): \n        out = set()\n        while n % 2 == 0: \n            out.add(2)\n            n /= 2\n\n        for i in range(3,int(math.sqrt(n))+1,2): \n            while n % i== 0: \n                out.add(i)\n                n /= i \n\n        if n > 2: \n            out.add(n)\n        return out\n", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if p > sqrt(x) + 1:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class DSU:\n  def __init__(self):\n    self.N = 0\n    self.map = {}\n    self.parent = []\n    self.count = []\n  \n  def __contains__(self, obj):\n    return obj in self.map\n  \n  def add(self, obj):\n    if obj in self:\n      return\n    i = self.N\n    self.N += 1\n    self.map[obj] = i\n    self.parent.append(i)\n    self.count.append(0)\n\n  def find(self, obj):\n    p = self.parent\n    \n    origI = self.map[obj]\n    \n    i = origI\n    while p[i] != i:\n      i = p[i]\n    root = i\n    \n    i = origI\n    while p[i] != i:\n        p[i], i = root, p[i]\n    \n    return root\n\n  def union(self, objA, objB):\n    rObjA = self.find(objA)\n    rObjB = self.find(objB)\n    if rObjA == rObjB:\n      return\n    self.count[rObjA] += self.count[rObjB]\n    self.parent[rObjB] = rObjA\n\n  def incCount(self, obj):\n    rObj = self.find(obj)\n    self.count[rObj] += 1\n    return self.count[rObj]\n\nclass Solution:\n  def largestComponentSize(self, nums) -> int:\n    UF = DSU()\n    max_ = 1\n    for num in nums:\n      if num == 1:\n        continue\n      pDs = self.primeDivisors(num)\n      pD0 = pDs[0]\n      UF.add(pD0)\n      for pD in pDs:\n        UF.add(pD)\n        UF.union(pD0, pD)\n      count = UF.incCount(pD0)\n      max_ = max(max_, count)\n    return max_\n    \n  def primeDivisors(self, num: int):\n      x = num\n      \n      pDs = []\n      \n      if x % 2 == 0:\n          pDs.append(2)\n          while x % 2 == 0:\n              x >>= 1\n          \n      if x % 3 == 0:\n          pDs.append(3)\n          while x % 3 == 0:\n              x //= 3\n      \n      div = 5\n      d2 = True\n      while x >= div*div:\n          if x % div == 0:\n              pDs.append(div)\n              while x % div == 0:\n                  x //= div\n          div += 2 if d2 else 4\n          d2 = not d2\n      \n      if x > 1:\n        pDs.append(x)\n      \n      return pDs\n", "class Solution:\n    def primeFactors(self, n):\n        pset = set()\n        # While n is even, divide by two\n        while n % 2 == 0:\n            pset.add(2)\n            n = n // 2\n        \n        # For every odd i between 3 and sqrt(n), check if it's a factor\n        for i in range(3, int(math.sqrt(n))+1, 2):\n            while n % i == 0:\n                pset.add(i)\n                n = n // i\n        \n        # If n is still greater than 2, it's a prime\n        if n > 2:\n            pset.add(n)\n            \n        return pset\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        # Creates a disjoint set (union find) for the list A\n        ds = DisjointSet(A)\n        \n        # Dict to keep the index of the disjoint set root for every prime divisor set found\n        primeRoots = {}\n        \n        # Iterate over A and find it's prime divisors\n        for i, a in enumerate(A):\n            primes = self.primeFactors(a)\n            # For every prime, set the index of a as it's root\n            for p in primes:\n                # If already have a set for this prime, join the current element to it\n                if p in primeRoots:\n                    ds.union(i, primeRoots[p])\n                else:\n                    primeRoots[p] = i\n\n        return max(ds.sizes)\n    \n\nclass DisjointSet:\n    def __init__(self, elements):\n        self.parents = [x for x in range(len(elements))]\n        self.sizes = [1] * len(elements)\n        \n    # Path splitting find algorithm.\n    def find(self, x):\n        while x != self.parents[x]:\n                x, self.parents[x] = self.parents[x], self.parents[self.parents[x]]\n        return x\n        \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return px\n        \n        if self.sizes[px] > self.sizes[py]:\n            py, px = px, py\n            \n        self.parents[px] = py\n        self.sizes[py] += self.sizes[px]", "class UnionFind:\n    def __init__(self,A):\n        self._arr = {v:-1 for v in A}\n    \n    def union(self,u,v):\n        p1 = self.find(u)\n        p2 = self.find(v)\n        \n        if p1 != p2:\n            self._arr[p1] = p2\n            return True\n        return False\n    def find(self,u):\n        if self._arr.get(u,-1) == -1:\n            return u\n        self._arr[u] = self.find(self._arr[u])\n        return self._arr[u]\n    \nclass Solution:\n    def factorsOf(self,n):\n        factors = set()\n        \n        while n % 2 == 0:\n            factors.add(2)\n            n = n//2\n        \n        for i in range(3,int(sqrt(n))+1,2):\n            while n % i == 0:\n                factors.add(i)\n                n = n // i\n        \n        if n > 2:\n            factors.add(n)\n            \n        return factors\n            \n            \n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = UnionFind(A)\n        \n        for n in A:\n            for factor in self.factorsOf(n):\n                dsu.union(n,factor)\n        \n        cnt_map = collections.Counter()\n        ans = 0\n        \n        for v in A:\n            p = dsu.find(v)\n            cnt_map[p]+=1\n            ans = max(cnt_map[p],ans)\n            \n        return ans\n                \n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        self.s=[1]*n\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    sieve=[0]*100001\n    for i in range(2,100001):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,100000//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        def add_prime(q,i,primes):\n            if q not in primes:\n                primes[q]=[i]\n            else:\n                primes[q].append(i)\n        n=len(A)        \n        g=UF(n)\n        primes={}\n        for i,k in enumerate(A):\n            while k>1:\n                q=self.sieve[k]\n                add_prime(q,i,primes)\n                while k%q==0:\n                    k//=q\n        # print(primes)\n        for l in primes.values():\n            j,r=l[0],g.find(l[0])\n            for i in l[1:]:\n                nd=g.find(i)\n                if nd!=r:\n                    g.p[nd]=r\n                    g.s[r]+=g.s[nd]\n        # print(g.p)\n        # print(g.s)\n        return max(g.s)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n    #https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/581394/Python-1032ms-beat-100-time-and-space\n", "mxn=10**5 +5\npri=[1]*(mxn)\nfor i in range(2,mxn):\n    if pri[i]==1:\n        pri[i]=i\n        j=2\n        while(i*j<mxn):\n            if pri[i*j]==1:\n                pri[i*j]=i\n            j+=1\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dct=[0]*mxn\n        res=0\n        def root(i):\n            while(i!=arr[i]):\n                i=arr[i]\n                arr[i]=arr[arr[i]]\n            return i\n        def update(i,j):\n            r1=root(i)\n            r2=root(j)\n            arr[r1]=r2\n            size[r2]+=size[r1]\n        for num in A:\n            dct[pri[num]]+=1\n        \n        arr=[i for i in range(mxn)]\n        size=[dct[i] for i in range(mxn)]\n        \n        for num in A:\n            ls=[]\n            while(num!=1):\n                ls.append(pri[num])\n                num=num//pri[num]\n            if len(ls)==1:continue\n            for i in range(1,len(ls)):\n                if root(ls[0])!=root(ls[i]):\n                    update(ls[0],ls[i])\n    \n                    \n            \n        return max(size)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def find(v):\n            if parent[v] != v:\n                parent[v] = find(parent[v])\n            return parent[v]\n        \n        def union(v1, v2):\n            p1 = find(v1)\n            p2 = find(v2)\n            if p1 not in rank:\n                rank[p1] = 0\n            if p2 not in rank:\n                rank[p2] = 0\n            if p1 != p2:\n                if rank[p1] > rank[p2]:\n                    parent[p2] = p1\n                else:\n                    parent[p1] = p2\n                    if rank[p1] == rank[p2]:\n                        rank[p2] += 1\n        def sieve(n):\n            primes = [True] * (n + 1)\n            p = 2\n            while p * p <= n:\n                if primes[p]:\n                    for i in range(p * 2, n + 1, p):\n                        primes[i] = False\n                p += 1\n            return [element for element in range(2, n) if primes[element]]\n        \n        rank = {}\n        primes = sieve(max(A) // 2 + 1)\n        parent = {i: i for i in A + primes}\n        for num in A:\n            up = int(sqrt(num))\n            t = num\n            for p in primes:\n                if p > up:\n                    break\n                if num % p == 0:\n                    union(num, p)\n                while t % p == 0:\n                    t //= p\n            if t > 1:\n                union(num, t)\n        return max(Counter([find(n) for n in A]).values())", "class DS:\n    def __init__(self, n):\n        self.par = list(range(n))\n        \n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self, x, y):\n        self.par[self.find(x)] = self.find(y)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        @lru_cache(None)\n        def find_prime_factors(num):\n            if num == 1:\n                return []\n            \n            if num <= 3:\n                return [num]\n            \n            for prime in range(2, int(sqrt(num))+1):\n                if num % prime == 0:\n                    break\n            else:\n                prime = num\n                    \n            while num % prime == 0:\n                num //= prime\n            return [prime] + find_prime_factors(num)\n        \n        s = {}\n        for i,num in enumerate(A):\n            if num == 1:\n                continue\n            primes = find_prime_factors(num)\n            for prime in primes:\n                if prime not in s:\n                    s[prime] = []\n                s[prime] += [i]\n\n        ds = DS(len(A))\n        for prime in s:\n            for i in range(len(s[prime])-1):\n                ds.union(s[prime][i], s[prime][i+1])\n            \n        counter = Counter([ds.find(i) for i in range(len(A))])\n        return max(counter.values() or [1])", "class node:\n    def __init__(self,val):\n        self.val=val\n        self.next=[]\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # l=[node(i) for i in A]\n        # for i in range(len(l)):\n        #     for j in range(len(l)):\n        #         if math.gcd(l[i].val,l[j].val)>1 and i!=j:\n        #             l[j].next.append(i)\n        # # for i in range(len(l)):\n        # #     print(l[i].next)\n        # # print(l)\n        # # def bfs(n,m):\n        # #     nonlocal l,vis\n        # #     # print(n,m,vis)\n        # #     vis[n]=True\n        # #     m+=1\n        # #     # k=m\n        # #     for i in l[n].next:\n        # #         if not vis[i]:\n        # #             m=dfs(i,m)\n        # #     return m\n        # def bfs(n):\n        #     nonlocal l,vis\n        #     q=[n]\n        #     # vis[n]=True\n        #     m=0\n        #     while q:\n        #         # print(q,vis)\n        #         k=[]\n        #         for i in q:\n        #             if not vis[i]:\n        #                 vis[i]=True\n        #                 k.extend(l[i].next)\n        #                 m+=1\n        #         q=k\n        #     return m\n        # mi=0\n        # vis=[False for i in range(len(l))]\n        # for i in range(len(l)):\n        #     if not vis[i]:\n        #         mi=max(mi,bfs(i))\n        # return mi\n        p=[2]\n        for i in range(3,int(max(A)**0.5)+1,2):\n            for y in p:\n                if i%y==0:\n                    break\n            else:\n                p.append(i)\n        f=collections.defaultdict(list)\n        for a in A:\n            x=a\n            for pp in p:\n                if pp**2>x:\n                    break\n                if x%pp==0:\n                    f[a].append(pp)\n                    while x%pp==0:\n                        x=x//pp\n            if x>1:\n                f[a].append(x)\n                p.append(x)\n        # print(p,f)\n        p=list(set(p))\n        n=len(p)\n        p2i={pp:i for i,pp in enumerate(p)}\n        par=[i for i in range(n)]\n        def find(i):\n            if i!=par[i]:\n                par[i]=find(par[i])\n            return par[i]\n        def union(i,j):\n            pi,pj=find(i),find(j)\n            if pi!=pj:\n                par[pi]=pj\n        for a in A:\n            if f[a]:\n                p0=f[a][0]\n                for pp in f[a][1:]:\n                    union(p2i[p0],p2i[pp])\n        # l=[find(p2i[f[a][0]]) for a in A]\n        c=collections.Counter(find(p2i[f[a][0]]) for a in A if f[a])\n        return max(c.values())\n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n        \n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class UFS:\n    def __init__(self, N):\n        self._parent = list(range(N))\n\n    def find(self, x):\n        if self._parent[x] != x:\n            self._parent[x] = self.find(self._parent[x])\n        return self._parent[x]\n\n    def union(self, x, y):\n        xroot, yroot = self.find(x), self.find(y)\n        if xroot != yroot:\n            self._parent[xroot] = yroot\n        \n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # from time import time\n        # start_time = time()\n        \n        \n        def primeFactors(k):  # Prime factor decomposition\n            out = set()\n            while k % 2 == 0: \n                out.add(2)\n                k //= 2\n            for i in range(3, int(math.sqrt(k))+1, 2): \n                while k % i== 0: \n                    out.add(i) \n                    k //= i \n            if k > 2: \n                out.add(k)\n            return out\n        \n        \n        n = len(A)\n        maxa = max(A)\n        # print(f\\\"{maxa=}, {len(A)=}\\\")\n            \n        ufs = UFS(maxa+1)\n        \n        for cur in A:\n            factors = primeFactors(cur)\n            # print(f\\\"{cur=}, {factors=}\\\")\n\n            for f in factors:\n                ufs.union(f, cur)\n                \n        # union_time = time() - start_time\n        # print(f\\\"{union_time=}\\\")\n        \n        count = [0] * (maxa+1)\n        for cur in A:\n            count[ufs.find(cur)] += 1\n        \n        return max(count)", "class Primes:\n    def __init__(self, N):\n        self.N = N\n        self.primes = [0]*(N+1)\n        self.get_primes()\n    \n    def get_primes(self):\n        for i in range(2, self.N+1):\n            if self.primes[i]==0:\n                self.primes[i] = i\n                upto = self.N//i\n                for j in range(2, upto+1):\n                    if self.primes[i*j] == 0:\n                        self.primes[i*j] = i\n    \n    def __call__(self, n):\n        # num = n\n        if n<=2:\n            return {n}\n        p = []\n        while n>=2:\n            lp = self.primes[n]\n            p.append(lp)\n            n =  n//lp\n        # print(num,\\\":\\\", p)\n        return set(p)\n\nclass DisjointSet:\n    def __init__(self, primes):\n        self.primes = primes\n        self.count = 1\n        \n    def union(self, setB):\n        # print(\\\"org:\\\", self.primes)\n        # print(\\\"union with:\\\", setB.primes)\n        self.primes |= setB.primes\n        self.count += setB.count\n        # print(\\\"after union:\\\", self.primes)\n        \n        \n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        disjoint_sets = []\n        Factors = Primes(max(A))\n        rank = [1]*(len(A)+1)\n        parent = [-1]*(len(A)+1)\n        m = dict()\n        curr_count = 0\n        \n        def get_parent(x):\n            if parent[x]==-1: return x\n            parent[x] = get_parent(parent[x])\n            # print(f\\\"parent of {x} is {parent[x]}\\\")\n            return parent[x]\n        \n        def union(x, y):\n            parx = get_parent(x)\n            pary = get_parent(y)\n            if parx==pary: return\n            if rank[parx]>=rank[pary]:\n                rank[parx] += rank[pary]\n                parent[pary] = parx\n            else:\n                rank[pary] += rank[parx]\n                parent[parx] = pary\n            # print(x,\\\":\\\",\\\"parent\\\", paar)\n        \n            \n        for i,val in enumerate(A):\n            # union = []\n            val_primes = Factors(val)\n            # for i, ds in enumerate(disjoint_sets):\n            #     diff_set = val_primes - ds.primes\n            #     if len(diff_set) < len(val_primes):\n            #         union.append(i)\n            #         val_primes = diff_set\n            # # if len(val_primes)>0:\n            # #     new_set = DisjointSet(val_primes)\n            # #     disjoint_sets.append(new_set)\n            # #     union.append(-1)\n            # temp_set = DisjointSet(val_primes)\n            # for ds in union:\n            #     temp_set.union(disjoint_sets[ds])\n            #     # disjoint_sets[union[-1]].union(disjoint_sets[ds])\n            #     # curr_count = max(curr_count, disjoint_sets[union[-1]].count)\n            # for ds in reversed(union):\n            #     disjoint_sets.pop(ds)\n            # disjoint_sets.append(temp_set)\n            \n            for prime in val_primes:\n                if prime in m:\n                    union(m[prime],i)\n                else:\n                    m[prime]=i\n                    # print(prime, \\\":\\\", i)\n        curr_count = max(rank)\n        return curr_count\n                \n                \n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]  # parent array\n        self.s=[1]*n  # size array\n        \n    def find(self,x): # find the representative/root of x\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self,x,y):\n        xr,yr=self.find(x),self.find(y)\n        if xr!=yr:\n            if self.s[x]<self.s[y]:\n                xr,yr=yr,xr\n            self.p[yr]=xr\n            self.s[xr]+=self.s[yr]\n\nclass Solution:\n    M=100000\n    sieve=[0]*(M+1) # stores the largest prime divisor of integers up to M\n    for i in range(2,M+1):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,M//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:   \n        g=UF(len(A))\n        primes=defaultdict(list) # {q:[nums]} list of integers that's divisible by prime q\n        for i,num in enumerate(A):\n            while num>1:\n                q=self.sieve[num]\n                primes[q].append(i) # add the ith element to be divisible by q\n                while num%q==0:\n                    num//=q\n                    \n        for l in primes.values():\n            x=l[0]\n            for y in l[1:]: \n                g.union(x,y)\n        \n        return max(g.s)", "from typing import List, Set, Tuple\n\ndef prime_factors(n: int) -> Set[int]:\n    f = set()\n    i = 1\n    while n % 2 == 0 and n:\n        f.add(2)\n        n //= 2\n    while n % 3 == 0 and n:\n        f.add(3)\n        n //= 3\n    root = int(n ** 0.5) + 1\n    while True and n:\n        a, b = 6 * i + 1, 6 * i - 1\n        while n % a == 0:\n            n //= a\n            f.add(a)\n        while n % b == 0:\n            n //= b\n            f.add(b)\n        if a > root:\n            break\n        i += 1\n    if n > 1:\n        f.add(n)\n    return f\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A.sort(reverse=True)\n        islands: List[Tuple[Set[int], int]] = []\n        primes: Set[int] = set()\n        for n in A:\n            factors = prime_factors(n)\n            first_merged = None\n            to_delete: Set[int] = set()\n            for i, (g, v) in enumerate(islands):\n                if factors.isdisjoint(g):\n                    continue\n                if first_merged is None:\n                    g.update(factors)\n                    islands[i] = (g, v + 1)\n                    first_merged = i\n                else:\n                    gf, vf = islands[first_merged]\n                    gf.update(g)\n                    islands[first_merged] = (gf, vf + v)\n                    to_delete.add(i)\n            primes_inside = factors & primes\n            if primes_inside:\n                if first_merged is None:\n                    new_v = len(primes_inside) + 1\n                    islands.append((factors, new_v))\n                else:\n                    gf, vf = islands[first_merged]\n                    islands[first_merged] = (gf, vf + len(primes_inside))\n                primes.difference_update(primes_inside)\n            elif first_merged is None:\n                if n in factors:\n                    primes.add(n)\n                else:\n                    islands.append((factors, 1))\n            islands = [g for i, g in enumerate(islands) if i not in to_delete]\n        return max(v for g, v in islands)\n            \n            \n            \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        max_p = int(2 + max(A) ** 0.5)\n        primes = [2,3,5,7,11,13,17,19]\n        \n        for num in range(20, max_p):\n            for p in primes:\n                if p * p > num:\n                    primes.append(num)\n                    break\n                if num % p == 0:\n                    break\n        \n        \n        prime_factors = collections.defaultdict(list)\n        members = collections.defaultdict(list)\n        \n        for num in A:\n            num0 = num \n            for prime in primes:\n                if prime ** 2 > num:\n                    if num > 1:\n                        prime_factors[num0].append(num)\n                        members[num].append(num0)\n                    break\n                if num % prime == 0:\n                    prime_factors[num0].append(prime)\n                    members[prime].append(num0)\n                while num % prime == 0:\n                    num //= prime\n        \n        # bipartite graph\n        # print(prime_factors)\n        # print(members)\n         \n        visited_primes = set()\n        ans = 0\n        for p in members.keys():\n            if p in visited_primes:\n                continue\n            visited_members = set()\n            \n            q_prime = collections.deque([p])\n            \n            while q_prime:\n                pp = q_prime.popleft()\n                \n                for m in members[pp]:\n                    \n                    if m in visited_members:\n                        continue\n                    visited_members.add(m)\n                    \n                    for ppp in prime_factors[m]:\n                        \n                        if ppp in visited_primes:\n                            continue\n                        visited_primes.add(ppp)\n                        \n                        q_prime.append(ppp)\n                     \n            \n            ans = max(ans, len(visited_members))\n        return ans", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def find(n):\n            if n not in root:\n                return n\n            root[n] = find(root[n])\n            return root[n]\n        \n        def union(n1, n2):\n            root1, root2 = find(n1), find(n2)\n            if root1 == root2:\n                return\n            rank1, rank2 = rank[root1], rank[root2]\n            if rank1 > rank2:\n                root[root2] = root1\n                size[root1] += size[root2]\n            elif rank1 < rank2:\n                root[root1] = root2\n                size[root2] += size[root1]\n            else:\n                root[root1] = root2\n                size[root2] += size[root1]\n                rank[root2] += 1\n                \n        def find_prime_factors(n):\n            factors = set()\n            while n % 2 == 0:\n                factors.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2):\n                while n % i == 0:\n                    factors.add(i)\n                    n //= i\n            if n > 2:\n                factors.add(n)\n            return factors\n        \n        factor_to_num = collections.defaultdict(list)\n        for n in A:\n            for factor in find_prime_factors(n):\n                factor_to_num[factor].append(n)\n        \n        root = {}\n        rank = {n: 1 for n in A}\n        size = {n: 1 for n in A}\n        \n        for factor in factor_to_num:\n            first_root = find(factor_to_num[factor][0])\n            for i in range(1, len(factor_to_num[factor])):\n                union(first_root, factor_to_num[factor][i])\n\n        return max(size.values())\n        \n", "class UnionFind(object):\n    def uf(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return self.uf[x]\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primeFactors(n):  # Prime factor decomposition\n            out = set()\n            while n % 2 == 0: \n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    out.add(i) \n                    n //= i \n            if n > 2: \n                out.add(n)\n            return out\n        \n        uf = UnionFind()\n        uf.uf(len(A))\n        \n        primeToIndex = {} \n        for i,a in enumerate(A):\n            primes = primeFactors(a)\n            for p in primes:\n                if p in primeToIndex:\n                    uf.union(i, primeToIndex[p])\n                primeToIndex[p] = i\n        return max(uf.size)", "class DSU:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.rank = [1 for i in range(n)]\n    \n    def find(self,x):\n        if x!=self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self,x,y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return\n        if self.rank[px] > self.rank[py]:\n            self.parent[py] = px\n            self.rank[px]+=self.rank[py]\n        else:\n            self.parent[px] = py\n            self.rank[py]+=self.rank[px]\n            \n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dsu = DSU(n)\n        \n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: \n                primes[q].append(i)\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n\n        \n        # for i in range(n):\n        #     for j in range(i+1,n):\n        #         if A[i]!=A[j] and self.gcd(A[i],A[j]) > 1:\n        #             dsu.union(i,j)\n        return max(dsu.rank)\n    \n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n    def gcd(self,x,y):\n        return gcd(y,x%y) if y!=0 else 0\n                \n                \n        \n        \n", "class UnionFind:\n    def __init__(self, num: int):\n        self.parents = [i for i in range(num)]\n        self.size = [1] * num\n        self.max = 1\n    \n    def find(self, number: int) -> int:\n        if self.parents[number] != number:\n            self.parents[number] = self.find(self.parents[number])\n        return self.parents[number]\n    \n    def merge(self, x: int, other: int):\n        parentX = self.find(x)\n        parentOther = self.find(other)\n        \n        if parentX != parentOther:\n            size_x, size_y = self.parents[parentX], self.parents[parentOther]\n\n            self.parents[parentX] = parentOther\n            self.size[parentOther] += self.size[parentX]\n\n            if self.size[parentOther] > self.max:\n                self.max = self.size[parentOther]\n            \n\nclass Solution:\n    def primesBefore(self, value: int) -> List[int]:\n        candidates = [True] * (value + 1)\n        primeList = []\n        \n        for i in range(2, value + 1):\n            if not candidates[i]:\n                continue\n            primeList.append(i)\n            for j in range(i, value + 1, i):\n                candidates[j] = False\n        \n        return primeList\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        union_find = UnionFind(len(A))\n        cache = {}\n        primes = self.primesBefore(max(A))\n        primeset = set(primes)\n        \n        for index, value in enumerate(A):\n            svalue = value\n            primeIndex = 0\n            \n            while svalue not in primeset and primes[primeIndex] <= svalue:\n                j = primes[primeIndex]\n                if svalue % j != 0:\n                    primeIndex += 1\n                    continue\n\n                if j not in cache:\n                    cache[j] = index\n                else:\n                    union_find.merge(index, cache[j])\n                if value // j not in cache:\n                    cache[value // j] = index\n                else:\n                    union_find.merge(index, cache[value // j])\n                \n                while svalue % j == 0:\n                    svalue //= j\n                primeIndex += 1\n            \n            if svalue == 1:\n                continue\n            if svalue not in cache:\n                cache[svalue] = index\n            else:\n                union_find.merge(index, cache[svalue])\n        \n        return union_find.max\n        \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        n = len(A)\n        index = list(range(n))\n        size = [1]*n\n        \n        def find(i):\n            while index[i] != i:\n                i = index[i]\n            return i\n        \n        def setPrimes(i):\n            for j in range(2, int(math.sqrt(i))+1):\n                if i % j == 0:\n                    return setPrimes(i // j) | set([j])\n            return set([i])\n        \n        primes = defaultdict(list)\n        for i in range(n):\n            s = setPrimes(A[i])\n            for prime in s:\n                primes[prime].append(i)\n        \n        for _, indices in primes.items():\n            for i in range(len(indices)-1):\n                k, l = find(indices[i]), find(indices[i+1])\n                if k == l:\n                    continue\n                if size[l] > size[k]:\n                    k, l = l, k\n                index[l] = k\n                size[k] += size[l]\n        return max(size)\n        \n    \n    \n        \n        \n        '''\n        n = len(A)\n        A.sort()\n        adj = [[] for _ in range(n)]\n        for i in range(n-1):\n            for j in range(i+1,n):\n                a, b = A[i], A[j]\n                while b:\n                    a, b = b, a%b\n                if a > 1:\n                    adj[i].append(j)\n                    adj[j].append(i)\n                    \n        visited = [False]*n\n        connected = [False]*n\n        \n        def dfs(i):\n            if visited[i]:\n                return 0\n            visited[i] = True\n            connected[i] = True\n            s = 1\n            for j in adj[i]:\n                s += dfs(j)\n            return s\n        \n        M = 0\n        for i in range(n):\n            if not connected[i]:\n                M = max(M, dfs(i))\n        return M\n        '''", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pfactorization(a):\n            N = a\n            if a >= 2 and a % 2 == 0:\n                Gp[2].append(N)\n                Gn[N].append(2)\n                while a % 2 == 0:\n                    a //= 2\n            for d in range(3, math.floor(a**(1/2)) + 1, 2):\n                if a % d == 0:\n                    Gn[N].append(d)\n                    Gp[d].append(N)\n                    while a % d == 0:   a //= d\n            if a > 1:\n                Gp[a].append(N)\n                Gn[N].append(a)\n        def dfs(curr):\n            if curr in seenNodes:   return 0\n            seenNodes.add(curr)\n            total = 1\n            for p in Gn[curr]:\n                if p in seenPrimes: continue\n                seenPrimes.add(p)\n                for owner in Gp[p]: total += dfs(owner)\n            return total\n        Gp = collections.defaultdict(list)\n        Gn = collections.defaultdict(list)\n        for a in A: pfactorization(a)   #build our graphs\n        seenPrimes, seenNodes = set(), set()\n        return max([dfs(a) for a in A])", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pfactorization(a):\n            N = a\n            if a >= 2 and a % 2 == 0:   #treat 2 alone\n                Gp[2].append(N)\n                Gn[N].append(2)\n                while a % 2 == 0:   a //= 2\n            for d in range(3, math.floor(a**(1/2)) + 1, 2): #possible odd numbers\n                if d > a:   break\n                if a % d == 0:\n                    Gn[N].append(d)\n                    Gp[d].append(N)\n                    while a % d == 0:   a //= d\n            if a > 1:   #check if what remains is itself a prime\n                Gp[a].append(N)\n                Gn[N].append(a)\n        def dfs(curr):\n            if curr in seenNodes:   return 0\n            seenNodes.add(curr)\n            total = 1\n            for p in Gn[curr]:\n                if p in seenPrimes: continue\n                seenPrimes.add(p)\n                for owner in Gp[p]: total += dfs(owner)\n            return total\n        Gp = collections.defaultdict(list)\n        Gn = collections.defaultdict(list)\n        for a in A: pfactorization(a)   #build our graphs\n        seenPrimes, seenNodes = set(), set()\n        return max([dfs(a) for a in A])", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pfactorization(a):\n            N = a\n            if a >= 2 and a % 2 == 0:   #treat 2 alone\n                Gp[2].append(N)\n                Gn[N].append(2)\n                while a % 2 == 0:\n                    a //= 2\n            for d in range(3, math.floor(a**(1/2)) + 1, 2): #possible odd numbers\n                if d > a:   break\n                if a % d == 0:\n                    Gn[N].append(d)\n                    Gp[d].append(N)\n                    while a % d == 0:\n                        a //= d\n            if a > 1:   #check if what remains is itself a prime\n                Gp[a].append(N)\n                Gn[N].append(a)\n        #Find the prime factors of the current number using Gn,\n        #For each prime factor, find all the numbers excluding self who have this prime factor\n        #They should all be connected\n        def dfs(curr):\n            if curr in seenNodes:\n                return 0\n            seenNodes.add(curr)\n            total = 1\n            for p in Gn[curr]:\n                if p in seenPrimes:\n                    continue\n                seenPrimes.add(p)\n                for owner in Gp[p]:\n                    total += dfs(owner)\n            return total\n        #This graph contains numbers in the list sharing the a prime factor, the key is that prime factor\n        Gp = defaultdict(list)\n        #This graph stores prime factors of each number in the list\n        Gn = defaultdict(list)\n        for a in A:\n            pfactorization(a)\n        seenPrimes, seenNodes = set(), set()\n        return max([dfs(a) for a in A])\n#Time Complexity : O(sqrt(max(A)*max(A))\n", "class Solution:\n    def largestComponentSize(self, A):\n        n = len(A)\n        primes = collections.defaultdict(list)\n        parents = [i for i in range(n)]\n        def find(x):\n            if parents[x] != x:\n                return find(parents[x])\n            return parents[x]\n        def union(x, y):\n            xr, yr = find(x), find(y)\n            if xr > yr:\n                parents[xr] = yr\n            else:\n                parents[yr] = xr\n        def primeSet(N):\n            for i in range(2, int(math.sqrt(N))+1):\n                if N%i == 0:\n                    return {i} | primeSet(N//i)\n            return {N}\n        for i, num in enumerate(A):\n            for q in primeSet(num):\n                primes[q] += [i]\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                union(indexes[i], indexes[i+1])\n        return max(Counter([find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def prime_factors(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return prime_factors(n//i) | set([i])\n            return set([n])\n            # i = 2\n            # while i ** 2 <= n:\n            #     if n % i == 0:\n            #         return prime_factors(n // i) | set([i])\n            #     i += 1\n            # return set([n])\n\n        f = list(range(len(A)))\n\n        def find(x):\n            # if x not in f:\n            #     f[x] = x\n            if f[x] != x:\n                f[x] = find(f[x])\n            return f[x]\n\n        def union(x, y):\n            f[find(x)] = find(y)\n\n        p2i = dict()\n        for i, a in enumerate(A):\n            primes = prime_factors(a)\n            # print(i, primes)\n            for p in primes:\n                # if p not in p2i:\n                #     p2i[p] = []\n                # p2i[p].append(i)\n                if p in p2i:\n                    union(i, p2i[p])\n                else:\n                    p2i[p] = find(i)\n        # for indexes in p2i.values():\n        #     for i in range(len(indexes) - 1):\n        #         union(indexes[i], indexes[i + 1])\n        # print(p2i)\n        # print(list(map(find, range(len(A)))))\n        counts = Counter(map(find, range(len(A))))\n        return counts.most_common(1)[0][1]", "import math\n\nclass UnionFind:\n    \n    def __init__(self, n):\n        self.data = list(range(n))\n        self.size = [1] * n\n        \n    def find(self, x):\n        if self.data[x] != x:\n            self.data[x] = self.find(self.data[x])\n        return self.data[x]\n    \n    def union(self, x, y):\n        ix, iy = self.find(x), self.find(y)\n        if ix != iy:\n            self.data[ix] = iy\n            self.size[iy] += self.size[ix]\n            self.size[ix] = 0\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def prime_set(num):\n            res = set()\n            while num % 2 == 0:\n                res.add(2)\n                num //= 2\n            for i in range(3, int(math.sqrt(num)) + 1, 2):\n                while num % i == 0:\n                    res.add(i)\n                    num //= i\n            if num > 2:\n                res.add(num)\n            return res\n        \n        n = len(A)\n        uf = UnionFind(n)\n        primes_dict = collections.defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = prime_set(num)\n            for p in pr_set:\n                primes_dict[p].append(i)\n        for indices in primes_dict.values():\n            for j in range(1, len(indices)):\n                uf.union(indices[j - 1], indices[j])\n                \n        return max(collections.Counter(uf.find(i) for i in range(n)).values())\n        \n        \n    def gcd_with_bfs(self, A: List[int]) -> int:\n        graph = collections.defaultdict(set)\n        \n        for i in range(len(A)):\n            for j in range(i, len(A)):\n                if math.gcd(A[i], A[j]) > 1:\n                    graph[A[i]].add(A[j])\n                    graph[A[j]].add(A[i])\n        \n        res = 0\n        seen = set()\n        for a in A:\n            if a not in seen:\n                node_count = 0\n                q = collections.deque([a])\n                seen.add(a)\n                while q:\n                    node = q.popleft()\n                    node_count += 1\n                    seen.add(node)\n                    for child in graph[node]:\n                        if child not in seen:\n                            seen.add(child)\n                            q.append(child)\n                res = max(res, node_count)\n        return res", "class DSU:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.rank = [1 for i in range(n)]\n    \n    def find(self,x):\n        if x!=self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self,x,y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return\n        if self.rank[px] > self.rank[py]:\n            self.parent[py] = px\n            self.rank[px]+=self.rank[py]\n        else:\n            self.parent[px] = py\n            self.rank[py]+=self.rank[px]\n            \n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dsu = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: \n                primes[q].append(i)\n        \n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n\n        \n        # for i in range(n):\n        #     for j in range(i+1,n):\n        #         if self.gcd(A[i],A[j]) > 1:\n        #             dsu.union(i,j)\n        return max(dsu.rank)\n    \n    def primes_set(self,n):\n        # 35\n        # i in range(2,6) --> 2,3,4,5 return func(7) | {5}\n        # 7\n        # i in range(2,3) --> 3,3 , return {7}\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return set([i]).union(self.primes_set(n//i))\n        return set([n])\n    \n    def gcd(self,x,y):\n        return gcd(y,x%y) if y!=0 else 0\n                \n                \n        \n        \n", "class DSU:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.rank = [1 for i in range(n)]\n    \n    def find(self,x):\n        if x!=self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self,x,y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return\n        if self.rank[px] > self.rank[py]:\n            self.parent[py] = px\n            self.rank[px]+=self.rank[py]\n        else:\n            self.parent[px] = py\n            self.rank[py]+=self.rank[px]\n            \n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dsu = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: \n                primes[q].append(i)\n        \n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n\n        \n        # for i in range(n):\n        #     for j in range(i+1,n):\n        #         if self.gcd(A[i],A[j]) > 1:\n        #             dsu.union(i,j)\n        return max(dsu.rank)\n    \n    def primes_set(self,n):\n        # 35\n        # i in range(2,6) --> 2,3,4,5 return func(7) | {5}\n        # 7\n        # i in range(2,3) --> 3,3 , return {7}\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return set([i]) | (self.primes_set(n//i))\n        return set([n])\n    \n    def gcd(self,x,y):\n        return gcd(y,x%y) if y!=0 else 0\n                \n                \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}\n        \n        parent = [i for i in range(n)]\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])\n        return max(count.values())\n                             \n\n", "max_num = 100000\nsmallest_prime_factors = [None] * (max_num + 1)\nsmallest_prime_factors[1] = 1\n\nfor num in range(2, max_num+1):\n    if smallest_prime_factors[num] is not None:\n        continue\n    smallest_prime_factors[num] = num\n    for multiple in range(num*num, max_num+1, num):\n        if smallest_prime_factors[multiple] is None:\n            smallest_prime_factors[multiple] = num\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parents = {}\n        \n        def find(x):\n            if x not in parents:\n                parents[x] = x\n            elif parents[x] != x:\n                parents[x] = find(parents[x])\n            return parents[x]\n        \n        def union(x, y):\n            xx, yy = find(x), find(y)\n            if xx != yy:\n                parents[xx] = yy\n        \n        def decompose(num):\n            if num == 1:\n                return [1]\n            prime_factor_set = set()\n            while num != 1:\n                prime_factor_set.add(smallest_prime_factors[num])\n                num //= smallest_prime_factors[num]\n            return list(prime_factor_set)\n        \n        factor = {}\n        \n        for num in A:\n            prime_factors = decompose(num)\n            factor[num] = prime_factors[0]\n            for i in range(1, len(prime_factors)):\n                union(prime_factors[i-1], prime_factors[i])\n        \n        counts = Counter(find(factor[num]) for num in A)\n        return max(counts.values() or [0])", "class Solution:\n    def largestComponentSize(self, A):\n        n = len(A)\n        primes = collections.defaultdict(list)\n        parents = [i for i in range(n)]\n        def find(x):\n            if parents[x] != x:\n                return find(parents[x])\n            return parents[x]\n        def union(x, y):\n            xr, yr = find(x), find(y)\n            if xr > yr:\n                parents[xr] = yr\n            else:\n                parents[yr] = xr\n        def primeSet(N):\n            for i in range(2, int(math.sqrt(N))+1):\n                if N%i == 0:\n                    return {i} | primeSet(N//i)\n            return {N}\n        for i, num in enumerate(A):\n            for q in primeSet(num):\n                primes[q] += [i]\n        for group in primes.values():\n            for i in range(len(group)-1):\n                union(group[i], group[i+1])\n        return max(Counter([find(i) for i in range(n)]).values())", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        self.parent[py] = px\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def primeSet(n):\n            for i in range(2, int(sqrt(n))+1):\n                if n % i == 0:\n                    return primeSet(n//i) | {i}\n            return {n}\n        \n        table = collections.defaultdict(list)\n        \n        for i, num in enumerate(A):\n            primes = primeSet(num)\n            for p in primes:\n                table[p].append(i)\n        \n        N = len(A)\n        dsu = DSU(N)\n        \n        for _, indexes in list(table.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n        \n        return max(Counter([dsu.find(x) for x in range(N)]).values())\n                \n", "\nfrom collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def getFactors(n):\n            if n==1:\n                return [1]\n            factor_set=[]\n            if n%2==0:\n                factor_set.append(2)\n                while n%2==0:\n                    n=n//2\n            if n>1:\n                for i in range(3,math.floor(math.sqrt(n))+1,2):\n                    if n%i==0:\n                        factor_set.append(i)\n                        while n%i==0:\n                            n=n//i\n                    if n==1:\n                        break\n            if n>2:\n                factor_set.append(n)\n            return factor_set\n                    \n        \n        def find(parent,n):\n            result=parent[n]\n            if result!=n:\n                parent[n]=find(parent,result)\n            return parent[n]\n        \n        def union(parent,n1,n2):\n            r1=rank[n1]\n            r2=rank[n2]\n            x1=find(parent,n1)\n            x2=find(parent,n2)\n            if x1!=x2:\n                if r1>=r2:\n                    parent[x2]=parent[x1]\n                    rank[x1]+=1\n                else:\n                    parent[x1]=parent[x2]\n                    rank[x2]+=1\n            \n        # print(\\\"--------------\\\")\n \n        max_elem=max(A)\n        parent=[i for i in range(max_elem+1)]\n        rank=[0]*(max_elem+1)\n        \n        for item in A:\n            factor_set=getFactors(item)\n            # print(item,factor_set)\n            v1=find(parent,item)\n            if v1==item:\n                union(parent,factor_set[0],v1)\n                for factor in factor_set[1:]:\n                    union(parent,factor_set[0],factor)\n        count=defaultdict(int)\n        for item in A:\n            count[find(parent,item)]+=1\n        # print(count)\n        # print(parent)\n        return max(count.values())\n                \n                \n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        self.sz = [1] * N\n        self.max_sz = 1\n\n    def find(self, x):\n        while self.p[x] != x:\n            self.p[x] = self.p[self.p[x]]\n            x = self.p[x]\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        if xr == yr: \n            return\n        if self.sz[xr] < self.sz[yr]:\n            x, y, xr, yr = y, x, yr, xr\n        self.p[yr] = xr\n        self.sz[xr] += self.sz[yr]\n        self.max_sz = max(self.max_sz, self.sz[xr])\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factorize(n):\n            result = set()\n            if n % 2 == 0:\n                result.add(2)\n                while n % 2 == 0: n //= 2\n            for i in range(3, int(sqrt(n)) + 1, 2):\n                if n % i == 0:\n                    result.add(i)\n                    while n % i == 0: n //= i\n            if n > 1:\n                result.add(n)\n            return result\n\n        if not A:\n            return 0\n        dsu = DSU(len(A))\n        primes = dict()\n        for i, a in enumerate(A):\n            for prime in factorize(a):\n                primes.setdefault(prime,[]).append(i)\n\n        for indices in primes.values():\n            for i in range(len(indices)-1):\n                dsu.union(indices[i], indices[i+1])\n        return dsu.max_sz", "\ndef get_prime_factors(num,):\n    for i in range(2, int(math.sqrt(num)) + 1):\n        if num % i == 0:\n            return list(set(get_prime_factors(num // i) + [i]))\n                \n            \n    return [num]\n\n\nclass DisjointSet:\n    def __init__(self):        \n        self.prime_parents = {}\n        self.parent_to_count = {}\n        \n    def get_parent(self, prime):\n        if prime not in self.prime_parents:\n            self.prime_parents[prime] = -1\n            return prime\n        \n        current = prime\n        while self.prime_parents[current] > 0:\n            current = self.prime_parents[current]\n            \n        return current\n    \n    def join(self, left, right):\n        left_parent = self.get_parent(left)\n        right_parent = self.get_parent(right)\n\n        if left_parent == right_parent:\n            return\n        \n        if self.prime_parents[left_parent] < self.prime_parents[right_parent]:\n            larger = left_parent\n            smaller = right_parent\n        else:\n            larger = right_parent\n            smaller = left_parent\n            \n        self.prime_parents[larger] += self.prime_parents[smaller]\n        self.parent_to_count[larger] = self.parent_to_count.get(larger, 0) + self.parent_to_count.get(smaller, 0)\n        self.prime_parents[smaller] = larger\n            \n    \n    def add(self, val):\n        prime_factors = get_prime_factors(val)\n        for l, r in zip(prime_factors, prime_factors[1:]):\n            self.join(l, r)\n            \n        parent = self.get_parent(prime_factors[0])\n        self.parent_to_count[parent] = self.parent_to_count.get(parent, 0) + 1\n           \n\n    \n    def get_largest_set_size(self):\n        return max(self.parent_to_count.values())\n    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dj_set = DisjointSet()\n        for val in A:\n            dj_set.add(val)\n            \n        return dj_set.get_largest_set_size()", "def get_primes(max_num):\n    return []\n#     primes = []\n#     possible_primes = [True for _ in range(max_num + 1)]\n#     value = 2\n#     while value <= max_num:\n#         if possible_primes[value]:\n#             primes.append(value)\n#             for multiplier in range(2, max_num // value + 1):\n#                 possible_primes[multiplier * value] = False\n                \n#         value += 1\n        \n#     return primes\n\n\ndef get_prime_factors(num, primes):\n    for i in range(2, int(math.sqrt(num)) + 1):\n        if num % i == 0:\n            return list(set(get_prime_factors(num // i, primes) + [i]))\n                \n            \n    return [num]\n#     if num == 1:\n#         return [1]\n    \n#     prime_factors = set()\n    \n#     for prime in primes:\n#         if num < prime:\n#             break\n#         while num % prime == 0:\n#             num = num // prime\n#             prime_factors.add(prime)\n            \n#     return list(prime_factors)\n\n\nclass DisjointSet:\n    def __init__(self, primes):\n        self.primes = primes\n        self.prime_parents = {}\n        self.parent_to_count = {}\n        \n    def get_parent(self, prime):\n        if prime not in self.prime_parents:\n            self.prime_parents[prime] = -1\n            return prime\n        \n        current = prime\n        while self.prime_parents[current] > 0:\n            current = self.prime_parents[current]\n            \n        return current\n    \n    def join(self, left, right):\n        left_parent = self.get_parent(left)\n        right_parent = self.get_parent(right)\n\n        if left_parent == right_parent:\n            return\n        \n        if self.prime_parents[left_parent] < self.prime_parents[right_parent]:\n            larger = left_parent\n            smaller = right_parent\n        else:\n            larger = right_parent\n            smaller = left_parent\n            \n        self.prime_parents[larger] += self.prime_parents[smaller]\n        self.parent_to_count[larger] = self.parent_to_count.get(larger, 0) + self.parent_to_count.get(smaller, 0)\n        self.prime_parents[smaller] = larger\n            \n    \n    def add(self, val):\n        prime_factors = get_prime_factors(val, self.primes)\n        for l, r in zip(prime_factors, prime_factors[1:]):\n            self.join(l, r)\n            \n        parent = self.get_parent(prime_factors[0])\n        self.parent_to_count[parent] = self.parent_to_count.get(parent, 0) + 1\n           \n\n    \n    def get_largest_set_size(self):\n        return max(self.parent_to_count.values())\n    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        max_val = max(A)\n        primes = get_primes(max_val)\n        \n        dj_set = DisjointSet(primes)\n        for val in A:\n            dj_set.add(val)\n            \n        return dj_set.get_largest_set_size()", "from collections import defaultdict\nfrom math import sqrt\nclass DSU(object):\n    def __init__(self, n):\n        self.ds = list(range(n))\n    \n    \n    def find(self, v):\n        if self.ds[v] != v:\n            self.ds[v] = self.find(self.ds[v])\n        return self.ds[v]\n\n    def union(self, p1, p2):\n        pp1, pp2 = self.find(p1), self.find(p2)\n        self.ds[pp1] = pp2\n    \nclass Solution(object):    \n    def uniqPrime(self, n):\n        l = []\n        while n % 2 == 0:\n            l.append(2)\n            n = n//2\n        \n        for i in range(3, int(sqrt(n)) + 1, 2):\n            while n % i == 0:\n                l.append(i)\n                n = n//i\n        if n > 2:\n            l.append(n)\n        \n        return list(set(l))\n        \n    def largestComponentSize(self, A):\n        primes = defaultdict(list)\n        n = len(A)\n        for i in range(n):\n            p = self.uniqPrime(A[i])\n            for x in p:\n                primes[x].append(i)\n        \n        #now we need to merge the disjoint sets and see which is the longest\n        uf = DSU(n)\n        for i in primes.items():\n            vals = i[1]\n            for j in range(len(vals) - 1):\n                uf.union(vals[j], vals[j+1])\n        \n        return max(Counter([uf.find(i) for i in range(n)]).values())", "import math\nfrom collections import deque\n\nclass UnionFind:\n    def __init__(self, n):\n        self.parent = [-1]*n\n        \n    def find(self, a):\n        if self.parent[a] < 0:\n            return a\n        self.parent[a] = self.find(self.parent[a])\n        return self.parent[a]\n    \n    def union(self, a, b):\n        root_a = self.find(a)\n        root_b = self.find(b)\n        if root_a != root_b:\n            if self.parent[root_a] <= self.parent[root_b]:\n                self.parent[root_a] += self.parent[root_b]\n                self.parent[root_b] = root_a\n            else:\n                self.parent[root_b] += self.parent[root_a]\n                self.parent[root_a] = root_b\n                \n########################## Solution inspired by discussion O(n sqrt(max(A))) ################\n# The main idea of this is to use prime factorization for each number in A which takes O(n sqrt(max(A))) and build a dictionary with the key of prime number and value of list of indices of A that have that prime factor. Then connect the indices in each list with union find.\n\nimport math\nfrom collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def prime_factors(num):\n            for i in range(2, int(math.sqrt(num))+1):\n                if num%i == 0:\n                    return set([i]) | prime_factors(num//i)\n            return set([num])\n        \n        uf = UnionFind(len(A))\n        d = defaultdict(list)\n        for i, a in enumerate(A):\n            for p in prime_factors(a):\n                d[p].append(i)\n        \n        for p, idx_list in list(d.items()):\n            for i in range(len(idx_list)-1):\n                uf.union(idx_list[i], idx_list[i+1])\n        return -min(uf.parent)\n        \n    \n                \n                \n                \n\n                \n                \n########################### My O(n^2) solution which is TLE #############################         \n# class Solution:\n    # def largestComponentSize(self, A: List[int]) -> int:\n    #     uf = UnionFind(len(A))\n    #     for i in range(len(A)-1):\n    #         for j in range(i+1, len(A)):\n    #             p1 = uf.find(i)\n    #             p2 = uf.find(j)\n    #             if p1 != p2 and math.gcd(A[i], A[j]) > 1:\n    #                 uf.union(i, j)\n    #     return -min(uf.parent)\n    \n    \n            \n########################### My simple bfs solution which is O(n^2) ##############################\n# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n#         max_so_far = 0\n#         seen = [0]*len(A)\n#         first_unseen = 0\n#         while first_unseen is not None:\n#             tmp = 0\n#             seen[first_unseen] = 1\n#             q = deque([(first_unseen, A[first_unseen])])\n#             first_unseen = None\n#             while q:\n#                 idx, num1 = q.popleft()\n#                 tmp += 1\n#                 for i, a in enumerate(A):\n#                     if not seen[i]:\n#                         if math.gcd(a, num1) > 1:\n#                             seen[i] = 1\n#                             q.append((i, a))\n#                         else:\n#                             first_unseen = i\n#             max_so_far = max(max_so_far, tmp)\n#         return max_so_far\n", "class UnionFind:\n    def __init__(self, val):\n        self.val = val\n        self.parent = self\n        \n    def union(self, uf):\n        uf.find().parent = self.find()\n        \n    def find(self):\n        if self.parent == self:\n            return self\n        self.parent = self.parent.find()\n        return self.parent\n    \nclass Solution:\n    def primeSet(self, n, cache):\n        if n in cache:\n            return cache[n]\n        for i in range(2, int(sqrt(n)) + 1):\n            if n % i == 0:\n                cache[n] = self.primeSet(n // i, cache) | set([i])\n                return cache[n]\n        cache[n] = set([n])\n        return cache[n]\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        unionFinds = {x: UnionFind(x) for x in A}\n        cache = {}\n        numbersThatThisPrimeIsAFactor = defaultdict(list)\n        for x in A:\n            primes = self.primeSet(x, cache)\n            for p in primes:\n                numbersThatThisPrimeIsAFactor[p].append(x)\n        \n        for _, p in numbersThatThisPrimeIsAFactor.items():\n            for i in range(len(p) - 1):\n                unionFinds[p[i]].union(unionFinds[p[i + 1]])\n        \n        return max(Counter([unionFinds[x].find().val for x in A]).values())", "from collections import defaultdict, Counter\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        parent = list(range(len(primes)))\n        p2i = {p:i for i,p in enumerate(primes)}\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n            \n        for a in A:\n            if factors[a]:\n                pf0 = factors[a][0]\n                for pf in factors[a][1:]:\n                    union(p2i[pf0], p2i[pf])\n                \n        count = Counter(find(p2i[factors[a][0]]) for a in A if factors[a])\n        return max(count.values())", "class UnionFind(object):\n    def uf(self, n):\n        self.root = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):\n        while x != self.root[x]:\n            self.root[x] = self.root[self.root[x]]\n            x = self.root[x]\n        return x\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.root[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primeFactors(n):\n            primes = set()\n            while n % 2 == 0:\n                primes.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n)+1), 2):\n                while n % i == 0:\n                    primes.add(i)\n                    n //= i\n            if n > 2: #incase 3\n                primes.add(n)\n            return primes\n        uf = UnionFind()\n        uf.uf(len(A))\n        pF = {}\n        for i, num in enumerate(A):\n            primes = primeFactors(num)\n            for p in primes:\n                if p in pF:\n                    uf.union(i, pF[p])\n                pF[p] = i\n        return max(uf.size)", "class UnionFind(object):\n    def uf(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return x\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n\ndef primeFactors(n):  # Prime factor decomposition\n    out = set()\n    while n % 2 == 0: \n        out.add(2)\n        n //= 2\n    for i in range(3, int(math.sqrt(n))+1, 2): \n        while n % i== 0: \n            out.add(i) \n            n //= i \n    if n > 2: \n        out.add(n)\n    return out\n\nclass Solution(object):\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind()\n        uf.uf(len(A))\n        \n        primeToIndex = {} \n        for i,a in enumerate(A):\n            primes = primeFactors(a)\n            for p in primes:\n                if p in primeToIndex:\n                    uf.union(i, primeToIndex[p])\n                primeToIndex[p] = i\n        return max(uf.size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [i for i in range(len(A))]\n        rank = [0 for i in range(len(A))]\n        \n        def prime_factors(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return prime_factors(n//i) | set([i])\n            return set([n])\n            # primes = set()\n            # d = 2\n            # while d <= sqrt(n):\n                # if n % d == 0:\n                    # primes.add(d)\n                    # n //= d\n                # else:    \n                    # d += 1\n            # if n > 1:\n                # primes.add(n)\n            # return primes        \n                    \n        def find(n):    \n            p = parent[n]\n            if p == n:\n                return p\n            parent[n] = find(parent[n])\n            return parent[n]\n\n        def merge(n1, n2):\n            r1 = find(n1)\n            r2 = find(n2)\n            \n            if r1 == r2:\n                return\n            \n            if rank[r1] < rank[r2]:\n                parent[r1] = r2\n            elif rank[r1] > rank[r2]:\n                parent[r2] = r1\n            else:    \n                parent[r1] = r2\n                rank[r2] += 1\n                \n        prime_indeces = defaultdict(list)\n        for i, n in enumerate(A):\n            primes = prime_factors(n)\n            for p in primes:\n                prime_indeces[p].append(i)\n            \n        print(prime_indeces)    \n        # print(parent)\n        for p, indeces in list(prime_indeces.items()):\n            for i in range(len(indeces)-1):\n                # print('merging', A[indeces[i]], A[indeces[i+1]])\n                merge(indeces[i], indeces[i+1])\n                # print(parent)        \n                \n                \n        count_map = dict()\n        best = 0        \n        \n        for i in parent:\n            i = find(i)\n            if i in count_map:\n                count_map[i] += 1\n            else:\n                count_map[i] = 1\n                \n            best = max(best, count_map[i])\n        # print(count_map)    \n            \n        return best\n", "import numpy as np\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # second attempt, going factor-wise using disjoint set structure\n        # A = np.array(A)\n        # start with parent pointing to themselves\n        parents = np.arange(len(A))\n        \n        # count of each node starting at 1 (itself)\n        counts = np.ones_like(parents)\n        \n        def find(i):\n            if parents[i] == i:\n                return i\n            else:\n                return find(parents[i])\n        \n        def combine(i, j):\n            pi = find(i)\n            pj = find(j)\n            \n            # only do something if not already linked\n            if pi != pj:\n                # merge under the biggest root\n                if counts[pi] > counts[pj]:\n                    parents[pj] = pi\n                    counts[pi] += counts[pj]\n                else:\n                    parents[pi] = pj\n                    counts[pj] += counts[pi]\n        \n        max_prime = int(np.floor(np.sqrt(max(A))))+1\n        # max_prime = max(A)\n        \n#         def get_primes(value: int) -> List[int]:\n#             ret = []\n#             sieve = [True]*(value+1)\n#             for p in range(2, value+1):\n#                 if sieve[p]:\n#                     ret.append(p)\n#                     for k in range(p, value+1, p):\n#                         sieve[k] = False\n#             return ret\n        \n#         primes = get_primes(max_prime)\n        \n#         for prime in primes:\n#             match = -1\n#             for i in range(len(A)):\n#                 if A[i] % prime == 0:\n#                     while A[i] % prime == 0:\n#                         A[i] = A[i] // prime  # keep factoring out\n#                     if match != -1:\n#                         # do the merge\n#                         combine(match, i)\n#                     else:\n#                         match = i # first one found, merge from now on\n        \n        \n        sieve = [True]*(max_prime+1)\n        for prime in range(2, max_prime+1):\n            if sieve[prime]:\n                match = -1\n                for i in range(len(A)):\n                    if A[i] % prime == 0:\n                        while A[i] % prime == 0:\n                            A[i] = A[i] // prime  # keep factoring out\n                        if match != -1:\n                            # do the merge\n                            combine(match, i)\n                        else:\n                            match = i # first one found, merge from now on\n                for k in range(prime, max_prime+1, prime):\n                    sieve[k] = False\n        \n        # leftover values of A are now higher primes (or 1)\n        # if any match, they need to be merged\n        inds = np.argsort(A)\n        \n        # print(A)\n        # print(inds)\n        # print(A[inds])\n        for i in range(1,len(A)):\n            if (A[inds[i]] != 1) and (A[inds[i-1]] == A[inds[i]]):\n                combine(inds[i-1], inds[i])\n        \n        return np.max(counts)\n        \n        # first attempt\n        # TLE at 78/100\n#         # note: a value of 1 cannot be connected to anything\n#         # can clump things together based on factors\n        \n#         def get_factors(value: int) -> List[int]:\n#             if value == 1:\n#                 return set()\n#             # ret = [value]\n#             ret = set([value])\n            \n#             # if value % 2 == 0:\n#             #     ret.append(2)\n#             #     ret.append(value // 2)\n            \n#             for i in range(2, int(np.floor(np.sqrt(value)))+1):\n#                 if value % i == 0:\n#                     ret.add(i)\n#                     ret.add(value // i)\n#                     # ret.append(i)\n#                     # ret.append(value // i)\n            \n#             return ret\n#             # return set(ret)\n        \n        \n#         # def get_primes(value: int) -> List[int]:\n#         #     ret = []\n#         #     sieve = [True]*(value+1)\n#         #     for p in range(2, value+1):\n#         #         if sieve[p]:\n#         #             ret.append(p)\n#         #             for k in range(p, value+1, p):\n#         #                 sieve[k] = False\n#         #     return ret\n        \n#         # trying more efficient get_primes implementation\n#         # def get_primes(n: int) -> List[int]:\n#         #     # modified from\n#         #     # https://stackoverflow.com/questions/2068372/fastest-way-to-list-all-primes-below-n-in-python/3035188#3035188\n#         #     sieve = np.ones(n//3 + (n%6==2), dtype=np.bool)\n#         #     sieve[0] = False\n#         #     for i in range(int(n**0.5)//3+1):\n#         #         if sieve[i]:\n#         #             k=3*i+1|1\n#         #             sieve[      ((k*k)//3)      ::2*k] = False\n#         #             sieve[(k*k+4*k-2*k*(i&1))//3::2*k] = False\n#         #     return np.r_[2,3,((3*np.nonzero(sieve)[0]+1)|1)]\n        \n#         def get_primes(n: int) -> List[int]:\n#             sieve = [True] * n\n#             for i in range(3,int(n**0.5)+1,2):\n#                 if sieve[i]:\n#                     sieve[i*i::2*i]=[False]*((n-i*i-1)//(2*i)+1)\n#             return [2] + [i for i in range(3,n,2) if sieve[i]]\n        \n#         primes = get_primes(int(np.floor(np.sqrt(max(A))))+1)\n#         # primes = get_primes(max(A))\n        \n#         def get_factors(value: int) -> List[int]:\n#             ret = set([value])\n#             for prime in primes:\n#                 if prime > value:\n#                     return ret\n#                 else:\n#                     if value % prime == 0:\n#                         ret.add(prime)\n#                         while value % prime == 0:\n#                             value /= prime\n                        \n#                         # ret.add(value//prime)\n#                         # value /= prime  # factor out prime for efficiency\n#                         # while value % prime == 0:\n#                         #     ret.add(value//prime)\n#                         #     value /= prime\n                        \n#                         # if value // prime in primes:\n#                         # ret.add(value//prime)\n#                         # value /= prime  # factor out prime for efficiency\n#                         # if value > 1:\n#                         #     ret.add(value)\n#                         # else:\n#                         #     break\n#                         # while value % prime == 0:\n#                         #     # if value // prime in primes:\n#                         #     # ret.add(value//prime)\n#                         #     value /= prime\n#                         #     if value > 1:\n#                         #         ret.add(value)\n#                         #     else:\n#                         #         break\n#             if value > 1:\n#                 ret.add(value)\n#             return ret\n        \n#         clusters = []\n#         sizes = []\n        \n#         for value in A:\n#             factors = get_factors(value)\n#             # check cluster matches, all that get matched get merged\n#             matches = []\n#             for j, cluster in enumerate(clusters):\n#                 if not cluster.isdisjoint(factors):\n#                     matches.append(j)\n#             # if not in any cluster, make a new cluster\n#             if len(matches) == 0:\n#                 clusters.append(factors)\n#                 sizes.append(1)\n#             elif len(matches) == 1:\n#                 clusters[matches[0]].update(factors)\n#                 sizes[matches[0]] += 1\n#             else:\n#                 base = matches[0]\n#                 # iterate backwards so they can be deleted safely\n#                 for match in matches[-1:0:-1]:\n#                     clusters[base].update(clusters[match])\n#                     sizes[base] += sizes[match]\n#                     del clusters[match]\n#                     del sizes[match]\n                \n#                 # add the new factors\n#                 clusters[base].update(factors)\n#                 sizes[base] += 1      \n\n#         return max(sizes)\n            \n        \n", "class UFS: \n    def __init__(self, n):\n        self.p = list(range(n))\n    \n    def find(self, x):\n        if self.p[x] != x: \n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr \n\nclass Solution:\n    def prime_sets(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.prime_sets(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = UFS(len(A))\n        primes = collections.defaultdict(list) \n        \n        for i, n in enumerate(A):\n            prime_set = self.prime_sets(n) \n            for q in prime_set: primes[q].append(i) \n                \n        for _, items in primes.items():\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n        \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())", "'''\nIdea: 1. Prime factorize the given numbers\n      2. Map the factors to the indices in which they take part\n      3. Perform union operations on the list of indices belonging to same factor\n      4. Perform union operation to find the largest component\n\nTime complexity: O(n * sqrt(m)) where prime factorization 'sqrt(m)' is applied n times \nSpace complexity: O(n * log(m)) to keep all prime factors and maintain DSU\n'''\n\nimport collections, math\n\nclass DSU:\n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.sizeOf = [1] * n  \n    \n\n    def find(self, p):\n        # Find parent of given node\n        root = p\n        while self.parent[root] != root:\n            root = self.parent[root]\n\n        # Path compression\n        while p != root:\n            next_node = self.parent[root]    \n            self.parent[p] = root\n            p = next_node\n        \n        return root \n\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n\n        if r1 == r2:\n            return \n        if self.sizeOf[r1] > self.sizeOf[r2]:\n            self.sizeOf[r1] += self.sizeOf[r2]\n            self.parent[r2] = r1 \n        else:\n            self.sizeOf[r2] += self.sizeOf[r1]\n            self.parent[r1] = r2\n\n\nclass Solution:\n    def largestComponentSize(self, A):\n\n        def primeFactorization(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return primeFactorization(n//i) | set([i]) \n            return set([n])\n\n\n        n = len(A)\n        dsu = DSU(n)\n        primes = collections.defaultdict(list)\n\n        for i in range(n):\n            prime_factors = primeFactorization(A[i])\n            for factor in prime_factors:\n                primes[factor] += i, \n        \n        for factor in primes:\n            indices = primes[factor]\n            size = len(indices)\n            for i in range(size-1):\n                dsu.union(indices[i], indices[i+1]) \n        \n        components = collections.defaultdict(int)\n        \n        for index in range(n):\n            components[dsu.find(index)] += 1\n        \n        return max(components.values())\n\n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/819919/Python-Union-find-solution-explained\n        # This question feels like union find but u cannot link together\n        # First, find the primes factor of each number\n        # And then group together same prime factore\n        # The largest group is the largest component\n        # But the way to find primes set is a little confusing \n        # It loop from small to large and find the first factor and the other (larger factor)\n        # If two numbers share the same prime factor, they belong to the same group\n        # Then use union find to grouo together\n        n = len(A)\n        record = [-1]*n\n        primes = collections.defaultdict(list)\n        def get_primes(i):\n            for j in range(2,int(math.sqrt(i)+1)):\n                if i%j == 0:\n                    return get_primes(i//j) | set([j])\n            return set([i])\n                \n            return res\n        def find(a):\n            if record[a] < 0:return a\n            record[a] = find(record[a])\n            return record[a]\n        \n        \n        # U have been wrong on this several times\n        # When merge, it is the record[i] == root index, not root val\n        def union(i,j):\n            a,b = find(i),find(j)\n            if a!=b:\n                if a<b:\n                    record[a] = b\n                else:\n                    record[b] = a\n                \n            \n        for i, v in enumerate(A):\n            primes_set = get_primes(v)\n            for j in primes_set:\n                primes[j].append(i)\n            \n        for _,indexes in list(primes.items()):\n            for i in range(len(indexes)):\n                union(indexes[0],indexes[i])\n        \n        res = 0\n        mapping = collections.defaultdict(set)\n        for i in range(n):\n            root = find(i)\n            mapping[root].add(i)\n            if len(mapping[root]) > res:res = len(mapping[root])\n        return res\n", "class Solution:  # Sieve + BFS \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def sieve():\n            i = 2\n            while i < len(spf):\n                spf[i] = 2\n                i += 2\n            i = 3\n            while i * i < len(spf):\n                if spf[i] == i:\n                    j = i\n                    while j < len(spf):\n                        if spf[j] == j:\n                            spf[j] = i\n                        j += i\n                i += 2\n        \n        spf, di, factors, visited_nums, visited_factors, ans = [i for i in range(max(A) + 1)], defaultdict(set), defaultdict(set), set(), set(), 1\n        \n        sieve()  # 1\n        \n        for num in A:\n            x = num\n            while x != 1:\n                di[spf[x]].add(num)\n                factors[num].add(spf[x])\n                x //= spf[x]\n        \n        for num in A:  # 2\n            if num in visited_nums:\n                continue\n                \n            visited_nums.add(num)\n            cur, queue = 1, deque([])\n            for factor in factors[num]:\n                queue.append(factor)\n                \n            while queue: \n                factor = queue.popleft()\n                visited_factors.add(factor)\n                for next_num in di[factor]:  # 3\n                    if next_num in visited_nums:\n                        continue\n                        \n                    visited_nums.add(next_num)\n                    cur += 1\n                    for next_factor in factors[next_num]:\n                        if next_factor in visited_factors:\n                            continue\n                        \n                        visited_factors.add(next_factor)\n                        queue.append(next_factor)\n                \n            ans = max(ans, cur)\n        \n        return ans", "class UnionFind:\n    def __init__(self, n):\n        self.reps = [i for i in range(n)]\n        self.size = [1]*n\n    def find(self, x):\n        while self.reps[x] != x:\n            self.reps[x] = self.reps[self.reps[x]]\n            x = self.reps[x]\n        return x\n    def union(self, x, y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.reps[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_prime_factor(n):\n            factors = set()\n            while n % 2 == 0:\n                n //= 2\n                factors.add(2)\n            while n % 3 == 0:\n                n //= 3\n                factors.add(3)\n            for i in range(5, int(sqrt(n))+1):\n                while n % i == 0:\n                    factors.add(i)\n                    n //= i\n            if n > 1:\n                factors.add(n)\n            return factors\n        \n        factor2idx = collections.defaultdict(list)    \n        for i in range(len(A)):\n            for factor in get_prime_factor(A[i]):\n                factor2idx[factor].append(i)\n        \n        uf = UnionFind(len(A))\n        for factor, indices in list(factor2idx.items()):\n            for idx in indices[1:]:\n                uf.union(indices[0], idx)\n                \n\n            \n        return max(uf.size)\n        \n        \n            \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/819919/Python-Union-find-solution-explained\n        # This question feels like union find but u cannot link together\n        # First, find the primes factor of each number\n        # And then group together same prime factore\n        # The largest group is the largest component\n        # But the way to find primes set is a little confusing \n        # It loop from small to large and find the first factor and the primes set for the larger factor\n        # If two numbers share the same prime factor, they belong to the same group\n        # Then use union find to grouo together\n        n = len(A)\n        record = [-1]*n\n        primes = collections.defaultdict(list)\n        def get_primes(i):\n            for j in range(2,int(math.sqrt(i))+1):\n                if i%j == 0:\n                    # And find the primes set for the larger factor\n                    return get_primes(i//j) | set([j])\n            return set([i])\n                \n            return res\n        def find(a):\n            if record[a] < 0:return a\n            record[a] = find(record[a])\n            return record[a]\n        \n        \n        # U have been wrong on this several times\n        # When merge, it is the record[i] == root index, not root val\n        def union(i,j):\n            a,b = find(i),find(j)\n            if a!=b:\n                if a<b:\n                    record[a] = b\n                else:\n                    record[b] = a\n                \n            \n        for i, v in enumerate(A):\n            primes_set = get_primes(v)\n            for j in primes_set:\n                primes[j].append(i)\n            \n        for _,indexes in list(primes.items()):\n            for i in range(len(indexes)):\n                union(indexes[0],indexes[i])\n        \n        res = 0\n        mapping = collections.defaultdict(set)\n        for i in range(n):\n            root = find(i)\n            mapping[root].add(i)\n            if len(mapping[root]) > res:res = len(mapping[root])\n        return res\n", "class UnionFind:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = UnionFind(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class DSU:\n    def __init__(self, size):\n        self.indexes = {i:i for i in range(size)}\n        self.sizes = {i:1 for i in range(size)}\n    \n    def root(self, i):\n        node = i\n        while i!=self.indexes[i]:\n            i = self.indexes[i]\n        \n        while node!=i:\n            nnode = self.indexes[node]\n            self.indexes[node] = i\n            node = nnode\n        return i\n    \n    def unite(self, i, j):\n        ri, rj = self.root(i), self.root(j)\n        if ri==rj:\n            return\n        else:\n            self.indexes[rj] = ri\n            self.sizes[ri]+=self.sizes[rj]\n        \n\nclass Solution:\n    def primeSet(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primeSet(n//i) | set([i])\n        return set([n])\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # Note, that if two numbers has common factor more than 1, it means that they have prime common factor.\n        d = collections.defaultdict(list)  # primeNum -> [indexes of A]\n        for i in range(len(A)):\n            s = self.primeSet(A[i])\n            for v in s:\n                d[v].append(i)\n        \n        dsu = DSU(len(A))\n        for k in d:\n            for ind in d[k][1:]:\n                dsu.unite(d[k][0], ind)\n        \n        ans = 1\n        for i in range(len(A)):\n            ans = max(ans, dsu.sizes[i])\n        \n        return ans\n    \n            \n        \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        fa = [i for i in range(len(A))]\n        sz = [1]*len(A)\n        def find(x):\n            if fa[x] != x:\n                fa[x] = find(fa[x])\n            return fa[x]\n        factor = defaultdict(list)\n        for i in range(len(A)):\n            x = A[i]\n            for y in range(2, int(math.sqrt(x))+1):\n                if not x%y:\n                    factor[y].append(i)\n                    while not x%y:\n                        x //= y\n            if x>1:\n                factor[x].append(i)\n        for k,v in list(factor.items()):\n            for j in range(1, len(v)):\n                x, y = v[0], v[j]\n                fx, fy = find(x), find(y)\n                if fx != fy:\n                    if sz[fx] > sz[fy]:\n                        sz[fy] += sz[fx]\n                        fa[fx] = fy\n                    else:\n                        sz[fx] += sz[fy]\n                        fa[fy] = fx\n        ans = 0        \n        for i in range(len(fa)):\n            if i == fa[i]:\n                ans = max(ans, sz[i])\n        return ans\n", "class UnionFind:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = UnionFind(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: \n                primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # [99,68,70,77,35,52,53,25,62]\n        n = len(A)\n        dsu = DSU(n)\n        prime_dict = defaultdict(list)\n        for i, num in enumerate(A):\n            primes = self.find_p(num)\n            for p in primes:\n                prime_dict[p].append(i)\n        for _, p_list in list(prime_dict.items()):\n            for j in range(len(p_list)):\n                dsu.union(p_list[0], p_list[j])\n        return max(Counter(dsu.find(x) for x in range(n)).values())\n    \n    def find_p(self, x):\n        for i in range(2, int(math.sqrt(x))+1):\n            if x % i == 0:\n                return self.find_p(x // i) | set([i])\n        return set([x])\n    \n    \n\n\nclass DSU:\n    def __init__(self, n):\n        self.sets = list(range(n))\n        \n    def find(self, x):\n        if self.sets[x] != x:\n            root = self.find(self.sets[x])\n            self.sets[x] = root\n            return root\n        return x\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.sets[yr] = xr\n        \n        \n                \n            \n        \n            \n        \n   \n    \n\n   \n", "class UFD: \n    def __init__(self, n):\n        self.p = list(range(n))\n    \n    def find(self, x):\n        if self.p[x] != x: \n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr \n\nclass Solution:\n    def prime_sets(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.prime_sets(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = UFD(len(A))\n        primes = collections.defaultdict(list)\n        \n        for i, n in enumerate(A):\n            p = self.prime_sets(n)\n            for q in p: primes[q].append(i)\n                \n        for _, items in list(primes.items()):\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n        \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())\n", "class Solution:\n    # O(n x sqrt(max)) time, O(n x sqrt(max)) space\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # def find_prime_factors(num):\n        #     result = set()\n        #     candidate = 2\n        #     cur_num = num\n        #     while candidate <= min(cur_num, int(math.sqrt(num))):\n        #         while cur_num % candidate == 0:\n        #             result.add(candidate)\n        #             cur_num //= candidate\n        #         candidate += 1\n        #     if cur_num != 1:\n        #         result.add(cur_num)\n        #     return result\n        \n        def find_prime_factors(num):\n            for i in range(2, int(math.sqrt(num))+1):\n                if num % i == 0:\n                    return find_prime_factors(num//i) | set([i])\n            return set([num])\n        \n        def find_root(x):\n            if root[x] != x:\n                root[x] = find_root(root[x])\n            return root[x]\n        \n        def union(x, y):\n            root[find_root(x)] = root[find_root(y)]\n        \n        root = [i for i in range(len(A))]\n        prime_factor_to_index = defaultdict(list)\n        # O(n x sqrt(max))\n        for i, num in enumerate(A):\n            prime_factors = find_prime_factors(num)\n            for factor in prime_factors:\n                prime_factor_to_index[factor].append(i)\n        \n        # O(n x sqrt(max))\n        for indices in list(prime_factor_to_index.values()):\n            for i in range(1, len(indices)):\n                union(indices[i - 1], indices[i])\n        \n        # O(n)\n        root_count = Counter(find_root(i) for i in range(len(A)))\n        return max(root_count.values())\n        \n\n", "class DSU:\n    def __init__(self, nums):\n        # self.idx = {v:i for i, v in enumerate(nums)}\n        self.nums = [i for i in range(len(nums))]\n        self.cnt = [1] * len(nums)\n    \n    def find(self, idx):\n        # idx = self.idx[x]\n        if self.nums[idx] == idx:\n            return idx\n        pidx = self.find(self.nums[idx])\n        self.nums[idx] = pidx\n        return pidx\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            self.nums[px] = self.nums[py]\n            self.cnt[py] += self.cnt[px]\n        return self.cnt[py]\n        \n        \nclass Solution:\n    def primes_set(self, x):\n        for i in range(2, int(x**0.5)+1):\n            if x % i == 0:\n                return self.primes_set(x//i) | set([i])\n        return set([x])\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(A)\n        primes = {}\n        for i, x in enumerate(A):\n            for prime in self.primes_set(x):\n                if prime not in primes:\n                    primes[prime] = []\n                primes[prime].append(i)\n        ans = 0\n        for _, idxs in list(primes.items()):\n            for i in range(len(idxs)-1):\n                ans = max(ans, dsu.union(idxs[i], idxs[i+1]))\n        return ans\n                \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        rank = {i: 1 for i in range(len(A))}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                if rank[px] > rank[py]:\n                    px, py = py, px\n                rank[py] += rank[px]\n                uf[px] = py\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2: x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k: ans.add(k)\n                while not x % k: x //= k\n                if x == 1: break\n            if x > 1: ans.add(x)\n            return ans\n                \n        dic = {}\n        for i in range(len(A)):\n            for k in primeFactor(A[i]):\n                dic.setdefault(k, i)\n                union(i, dic[k])\n        return max(Counter([find(i) for i in range(len(A))]).values())", "class Solution:\n       def largestComponentSize(self, A):\n           def getUniqueDivisors(x:int)->set():\n              result = set()\n              while x % 2 == 0:\n                 result .add(2)\n                 x >>= 1\n              i = 3\n              while i * i <= x:\n                 while x % i == 0:\n                    result.add(i)\n                    x //= i\n                 i += 2\n              if x > 1:\n                 result.add(x)\n       \n              if x > 1:\n                 result.add(x)\n              return result\n           def findParent(parents:List[int],x:int)->int:\n              if parents[x] != x:\n                 parents[x]=findParent(parents,parents[x])\n              return parents[x]\n           n = len(A)\n           parents = [i for i in range(n)]\n           parentByDivisor = {}\n           for i in range(n):\n             divisors = getUniqueDivisors(A[i])\n             for div in divisors:\n                if div in parentByDivisor:\n                   root = findParent(parents,parentByDivisor[div])\n                   parents[root] = i\n                parentByDivisor[div] = i\n           counter = [0 for i in range(n)]\n           for i in range(n):\n              root = findParent(parents,i)\n              counter[root] += 1\n           return max(counter)\n                \n           \n", "class DisjointSet:\n    def __init__(self, num):\n        self.forest = list(range(num))\n\n    def find(self, x):\n        if self.forest[x] != x:\n            self.forest[x] = self.find(self.forest[x])\n        return self.forest[x]\n\n    def union(self, x, y):\n        self.forest[self.find(x)] = self.find(y)\n\n\nclass Solution:\n    def largestComponentSize(self, arr):\n        n = len(arr)\n        ds = DisjointSet(n)\n        primesDict = defaultdict(list)\n        for i, num in enumerate(arr):\n            primes = self.getPrimes(num)\n            for p in primes:\n                primesDict[p].append(i)\n\n        for li in primesDict.values():\n            for i in range(len(li)-1):\n                ds.union(li[i], li[i+1])\n\n        return max(Counter([ds.find(i) for i in range(n)]).values())\n\n    def getPrimes(self, num):\n        for i in range(2, int(math.sqrt(num)) + 1):\n            if num % i == 0:\n                return self.getPrimes(num // i) | {i}\n        return {num}", "from math import sqrt\nimport collections\nclass Solution:\n    def primes(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes(n//i) | set([i])\n        return set([n])\n    \n    def find(self, i):\n        if self.root[i]==i: return i \n        self.root[i]=self.find(self.root[i])\n        return self.root[i]\n    \n    def union(self, i, j): \n        ri=self.find(i)\n        rj=self.find(j)\n        if ri==rj: return \n        if self.rank[ri]>self.rank[rj]:\n            self.root[rj]=ri\n        else:\n            self.root[ri]=rj\n            if self.rank[ri]==self.rank[rj]:\n                self.rank[rj]+=1\n        return \n            \n   \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        self.root={i:i for i in range(len(A))}\n        self.rank={i:0 for i in range(len(A))}\n        d=collections.defaultdict(set)\n        for i in range(len(A)):\n            for key in self.primes(A[i]):\n                d[key].add(i)\n        for key in d:\n            temp=list(d[key])\n            for x in temp:\n                self.union(temp[0],x)\n        return max([val for key, val in list(collections.Counter([self.find(i) for i in range(len(A))]).items())])\n            \n        \n       \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        rank = {a: 1 for a in A}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            px, py = find(x), find(y)\n            if px != py:\n                if rank[px] > rank[py]:\n                    px, py = py, px\n                rank[py] += rank[px]\n                uf[px] = py\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2:\n                    x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k:\n                    ans.add(k)\n                while not x % k:\n                    x //= k\n                if x == 1:\n                    break\n            if x > 1:\n                ans.add(x)\n            return ans\n                \n        dic = {}\n        for a in A:\n            for k in primeFactor(a):\n                dic.setdefault(k, a)\n                union(a, dic[k])\n        return max(Counter([find(a) for a in A]).values())", "class DFS:\n    def __init__(self, n):\n        self.p = list(range(n))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr \n\nclass Solution:\n    def prime_sets(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.prime_sets(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = DFS(len(A))\n        primes = collections.defaultdict(list)\n        \n        for i, n in enumerate(A):\n            prime_sets = self.prime_sets(n) \n            for q in prime_sets: primes[q].append(i) \n        \n        for _, items in primes.items():\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n        \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())", "class UnionFind:\n    def __init__(self, N):\n        self.indices = list(range(N)) # each elem belongs to diff index\n        \n    def find(self, x):\n        if x == self.indices[x]:\n            return x\n        \n        # Was unioned with a diff number, find that number's index\n        # Set ans to elem, makes subsequent queries faster\n        self.indices[x] = self.find(self.indices[x]) \n            \n        return self.indices[x]\n\n    def union(self, x, y):\n        x_i,y_i = self.find(x), self.find(y)\n        \n        # Set x's index to y's index, unions both number's sets\n        self.indices[x_i] = y_i\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        UF = UnionFind(n)\n        \n        primes_set = defaultdict(list)\n        \n        def get_primes(num):\n            for i in range(2, int(math.sqrt(num))+1):\n                if num % i == 0:\n                    return get_primes(num // i) | set([i])\n            return set([num])\n                    \n        \n        for i,num in enumerate(A):\n            for factor in get_primes(num):\n                primes_set[factor].append(i)\n                \n        for vals in primes_set.values():\n            for i in range(len(vals) - 1):\n                UF.union(vals[i], vals[i+1])\n        \n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        mp={} # for union find\n        ans=0\n        \n        def find(a):\n            if a not in mp: mp[a]=a\n            if mp[a]!=a:\n                mp[a]=find(mp[a])\n            return mp[a]\n            \n        def union(a,b): # b is smaller\n            pa=find(a)\n            pb=find(b)\n            if pa!=pb:\n                mp[pa]=pb\n            \n        for a in A:\n            for factor in self.primes_set(a):\n                union(a,factor)\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]\n    \n    def primes_set(self,n): # much fast using this primes set\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])                ", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        import math\n        n = len(A)\n        G = collections.defaultdict(set)\n        def get_prime_list(target):\n            dest = int(math.sqrt(target))\n            target_list = list(range(2, target + 1))\n            prime_list = []\n\n            while True:\n                num_min = min(target_list)\n                if num_min >= dest:\n                    prime_list.extend(target_list)\n                    break\n                prime_list.append(num_min)\n\n\n                i = 0\n\n                while True:\n                    if i >= len(target_list):\n                        break\n                    elif target_list[i] % num_min == 0:\n                        target_list.pop(i)\n                    i += 1\n\n            return prime_list\n        def primes_set(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return primes_set(n//i) | set([i])\n            return set([n])\n        #primes = get_prime_list(min(100000,max(A)))\n        #primes = primes_set\n        def find(x):\n            if p[x] != x:\n                p[x] = find(p[x])\n            return p[x]\n        def union(x,y):\n            x = find(x)\n            y = find(y)\n            p[y] = x\n            \n        for a in A:\n            G[a] = set()\n        pdic = collections.defaultdict(set)\n        p = list(range(len(A)))\n        for idx,i in enumerate(A):\n            for j in primes_set(i):\n                    pdic[j].add(idx)\n        for k,v in  list(pdic.items()):\n            n = len(v)\n            tmp = list(v)\n            for i in range(n-1):\n                union(tmp[i],tmp[i+1])  \n        tmp = []\n        for i in range(len(A)):\n            tmp.append(find(i))\n        c = Counter(tmp)\n        return max(c.values())\n                    \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        f = {}\n        \n        def find(x):\n            f.setdefault(x,x)\n            if x != f[x]:\n                f[x] = find(f[x])\n            \n            return f[x]\n        \n        def union(x,y):\n            px, py = find(x), find(y)\n            if px != py:\n                f[px] = py\n        \n        #we can break down any number into prime divisors mutiplication\n        \n        def get_primes(n):\n            for i in range(2, int(sqrt(n))+1):\n                if n % i == 0:\n                    return get_primes(n//i) | {i}\n            \n            return {n}\n        \n        primes_dict = collections.defaultdict(list)\n        \n        for i,a in enumerate(A):\n            primes = get_primes(a)\n            \n            for p in primes:\n                primes_dict[p].append(i)\n        \n        for k,indexes in list(primes_dict.items()):\n            for j in range(len(indexes)-1):\n                union(indexes[j],indexes[j+1])\n        \n        return max(collections.Counter(find(i) for i in range(len(A))).values())\n        \n        \n            \n", "        \nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n        \n        \nclass Solution:\n    def findPrime(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.findPrime(n//i) | set([i])\n        return set([n])\n    \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        uf = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pset = self.findPrime(num)\n            for q in pset:\n                primes[q].append(i)\n        \n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes) - 1):\n                uf.union(indexes[i], indexes[i+1])\n        return max(Counter([uf.find(i) for i in range(n)]).values())\n        \n        \n\n        \n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self, d):\n        for i in range(2, int(math.sqrt(d)) + 1):\n            if d % i == 0:\n                return self.primes_set(d // i) | set([i])\n        return set([d])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n            \n        for _, indexes in primes.items():\n            for i in range(len(indexes) - 1):\n                UF.union(indexes[i], indexes[i + 1])\n        \n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        # rank\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            uf[find(x)] = find(y)\n            \n        def primeFactor(x):\n            ans = set()\n            if not x % 2:\n                ans.add(2)\n                while not x % 2:\n                    x //= 2\n            for k in range(3, int(sqrt(x)) + 1, 2):\n                if not x % k:\n                    ans.add(k)\n                while not x % k:\n                    x //= k\n                if x == 1:\n                    break\n            if x > 1:\n                ans.add(x)\n            return ans\n                \n        # dic = {}\n        for a in A:\n            for k in primeFactor(a):\n                # dic.setdefault(k, a)\n                union(a, k)\n        return max(Counter([find(a) for a in A]).values())", "class DSU:\n    def __init__(self, n):\n        self.parent = list(range(n))\n\n    def find(self, target):\n        if self.parent[target] != target:\n            self.parent[target] = self.find(self.parent[target])\n        return self.parent[target]\n\n    def union(self, c, p):\n        self.parent[self.find(c)] = self.find(p)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(len(A))\n        \n        def prime_factorize(n):\n            for i in range(2, int(sqrt(n))+1):\n                if n%i == 0:\n                    return [i] + prime_factorize(n//i)\n            return [n]\n        \n        prime2indices = defaultdict(list)\n        \n        for i, n in enumerate(A):\n            for p in prime_factorize(n):\n                prime2indices[p].append(i)\n        \n        for arr in list(prime2indices.values()):\n            for i in range(1, len(arr)):\n                dsu.union(arr[0], arr[i])\n        \n        aggregate = defaultdict(int)\n        \n        for i in range(len(A)):\n            aggregate[dsu.find(i)] += 1\n        \n        return max(aggregate.values())\n", "import collections as clc\nimport math\nimport time\n\n\nclass UnionFind:\n    \n    def __init__(self, n: int):\n        self.repr = list(range(n))\n    \n    def find(self, num: int) -> int:\n        if num != self.repr[num]:\n            self.repr[num] = self.find(self.repr[num])\n        return self.repr[num]\n    \n    def union(self, num1: int, num2: int) -> bool:\n        r1 = self.find(num1)\n        r2 = self.find(num2)\n        if r1 == r2:\n            return False\n        self.repr[r2] = r1\n        return True\n\n\nclass Solution:\n    \n    def decompose(self, n: int) -> List[int]:\n        ans = []\n        max_prime = int(math.sqrt(n))\n        if n % 2 == 0:\n            ans.append(2)\n            while n % 2 == 0:\n                n //= 2\n        prime = 3\n        while prime <= max_prime:\n            if n % prime == 0:\n                ans.append(prime)\n                while n % prime == 0:\n                    n //= prime\n            prime += 2\n        if n != 1:\n            ans.append(n)\n        return ans\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        M = max(A)\n        node_lists = clc.defaultdict(list)\n        for idx, a in enumerate(A):\n            for prime in self.decompose(a):\n                node_lists[prime].append(idx)\n        uf = UnionFind(n)\n        for nodes in node_lists.values():\n            if len(nodes) <= 1:\n                continue\n            idx1 = nodes[0]\n            for idx2 in nodes[1:]:\n                uf.union(idx1, idx2)\n        return max(clc.Counter([uf.find(idx) for idx in range(n)]).values())", "class DFU: \n    def __init__(self, n):\n        self.p = list(range(n))\n    \n    def find(self, x):\n        if self.p[x] != x: \n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y): \n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def prime_sets(self, n): \n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.prime_sets(n // i) | set([i])\n        return set([n]) \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = DFU(len(A))\n        primes = collections.defaultdict(list) \n        \n        for i, n in enumerate(A):\n            prime_set = self.prime_sets(n) \n            for q in prime_set: primes[q].append(i) \n        \n        for _, items in primes.items():\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n        \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())", "class DSU:\n    def __init__(self, n):\n        self.p = list(range(n))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        x1, y2 = self.find(x), self.find(y)\n        self.p[x1] = y2       \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_factor_primes(n):\n            for i in range(2, int(n**(1/2))+1):\n                if n%i == 0:\n                    return set([i]).union(get_factor_primes(n//i))\n            return set([n])\n        \n        #hash index to prim numbers\n        prime = defaultdict(list)\n        \n        for i, n in enumerate(A):\n            primeset = get_factor_primes(n)\n            for p in primeset:\n                prime[p].append(i)\n                \n        #create DSU for all common prime sets\n        N = len(A)\n        dsu = DSU(N)\n        \n        for _, indexes in list(prime.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n                \n        #return max count\n        return max(Counter([dsu.find(i) for i in range(N)]).values())\n                \n                \n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n            return a\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: {n} for n in primes}\nFS[1] = {}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0:\n                n >>= 1\n            if n == 1:\n                FS[f] = {2}\n            else:\n                FS[f] = {2} | factors3(n)\n\n    return FS.get(f, set())\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0:\n                    n = n // i\n                if n == 1:\n                    FS[f] = {i}\n                else:\n                    FS[f] = {i} | factors3(n, i + 2)\n                break\n        else:\n            FS[f] = {f}\n\n    return FS[f]\n", "class DisjointSet:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0 for i in range(n)]\n        \n    def GetParent(self, i):\n        if self.parent[i] != i:\n            self.parent[i] = self.GetParent(self.parent[i])\n            \n        return self.parent[i]\n    \n    def Union(self, i, j):\n        i_idx = self.GetParent(i)\n        j_idx = self.GetParent(j)\n        \n        if j_idx == i_idx:\n            return\n        \n        if self.rank[i_idx] > self.rank[j_idx]:\n            self.parent[j_idx] = i_idx\n        else:\n            if self.rank[i_idx] == self.rank[j_idx]:\n                self.rank[j_idx] += 1\n            \n            self.parent[i_idx] = j_idx\n        \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def prime_set(n):\n            for i in range(2, math.floor(math.sqrt(n)) + 1):\n                if n % i == 0:\n                    return prime_set(n // i) | set([i])\n                    \n            return set([n])\n        \n        ds = DisjointSet(len(A))\n        \n        primes = {}    \n        \n        for i in range(len(A)):\n            curr_prime_set = prime_set(A[i])\n            \n            for prime in curr_prime_set:\n                primes.setdefault(prime, [])\n                primes[prime].append(i)\n                \n        for key in primes:\n            for i in range(len(primes[key]) - 1):\n                ds.Union(primes[key][i], primes[key][i + 1])\n                \n        set_counter = {}\n        \n        for i in range(len(A)):\n            set_counter.setdefault(ds.GetParent(i), 0)\n            set_counter[ds.GetParent(i)] += 1\n            \n        # print(set_counter)\n        return max(set_counter.values())\n        \n        \n#     def largestComponentSize(self, A: List[int]) -> int:\n#         def gcd(a, b):\n#             nonlocal gcd_hash\n#             if (a, b) in gcd_hash:\n#                 return gcd_hash[(a, b)]\n            \n#             if b == 0:\n#                 return a\n            \n#             if a >= b:\n#                 return gcd(b, a % b)\n#             else:\n#                 return gcd(a, b % a)\n            \n            \n#         def Explore(u, adj_list, visited):\n#             visited[u] = 1\n            \n#             for v in adj_list[u]:\n#                 if not visited[v]:\n#                     nonlocal cc_length\n#                     cc_length += 1\n#                     Explore(v, adj_list, visited)\n                 \n                \n#         gcd_hash = {}\n#         V = len(A)\n#         adj_list = [[] for _ in range(V)]\n        \n#         for i in range(len(A)):\n#             for j in range(i + 1, V):\n#                 curr_gcd = gcd(A[i], A[j])\n#                 gcd_hash[(A[i], A[j])] = curr_gcd\n#                 gcd_hash[(A[j], A[i])] = curr_gcd\n                \n#                 if curr_gcd > 1:\n#                     adj_list[i].append(j)\n#                     adj_list[j].append(i)\n        \n#         # print(adj_list)\n        \n#         visited = [0 for _ in range(V)]\n#         max_cc_length = 0\n#         cc_num = 0\n#         cc_length = 1\n        \n#         for i in range(V):\n#             if not visited[i]:\n#                 Explore(i, adj_list, visited)\n#                 cc_num += 1\n                \n#                 if cc_length > max_cc_length:\n#                     max_cc_length = cc_length\n                \n#                 cc_length = 1\n                \n#         # print(cc_num)\n#         # print(max_cc_length)\n        \n#         return max_cc_length\n                \n                \n                \n        \n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        self.r = [0] * N\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        if self.r[xr] < self.r[yr]:\n            self.p[xr] = yr\n        else:\n            self.p[yr] = xr\n            self.r[xr] += self.r[yr]\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class DFU:\n    def __init__(self, n):\n        self.p = list(range(n))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr \n\nclass Solution:\n    def prime_sets(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0: \n                return self.prime_sets(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = DFU(len(A))\n        primes = collections.defaultdict(list)\n        for i, n in enumerate(A): \n            prime_set = self.prime_sets(n)\n            for q in prime_set: \n                primes[q].append(i) \n                \n        for _, items in list(primes.items()): \n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n                \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: {n} for n in primes}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0: n >>= 1\n            FS[f] = {2} | factors3(n) if n > 1 else {2}\n    return FS[f]\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0: n = n // i\n                FS[f] = {i} | factors3(n, i + 2) if n > 1 else {i}\n                break\n        else:\n            FS[f] = {f}\n    return FS[f]\n", "from collections import defaultdict\nfrom collections import Counter\n\nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n        \nclass Solution:\n    def primes_set(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        \n        return set([n])\n    \n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        \n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n                \n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes) -1 ):\n                UF.union(indexes[i], indexes[i+1])\n        \n        return max(Counter([UF.find(i) for i in range(n)]).values())\n            \n            \n", "class Solution1:\n    def largestComponentSize(self, A):\n        if not A: return 0\n        def findAndCompact(l, i): # require i >= 0\n            if l[i] == i: return i\n            p = l[i]\n            if p >= 0 and l[p] == p: return p\n            while p >= 0 and l[p] != p:\n                p = l[p]\n            root = p\n            \n            # compact\n            p = i\n            while p >= 0 and l[p] != p:\n                t = l[p]\n                l[p] = root\n                p = t\n            return root\n        \n        slist = [-1] * len(A)\n        d = {} # record prime->(root of union-find set)\n        for i in range(len(A)):\n            n = A[i]\n            has_factor = False\n            for j in range(2, int(sqrt(n)) + 1):\n                if n % j == 0:\n                    has_factor = True\n                    k = n // j\n                    #print(n, j, k)\n                    ri = -1 if slist[i] < 0 else findAndCompact(slist, slist[i])\n                    rj = -1 if j not in d else findAndCompact(slist, d[j])\n                    rk = -1 if k not in d else findAndCompact(slist, d[k])\n                    if ri < 0 and rj < 0 and rk < 0:\n                        slist[i] = d[j] = d[k] = i\n                    else:\n                        mm = min([item for item in (ri, rj, rk) if item >= 0])\n                        if slist[i] >= 0: slist[ri] = mm\n                        if j in d: slist[rj] = mm\n                        if k in d: slist[rk] = mm\n                        slist[i] = d[j] = d[k] = mm\n            if not has_factor: #prime\n                if A[i] not in d: slist[i] = d[A[i]] = i\n                else: slist[i] = d[A[i]]\n            #print(slist, d)\n        \n        for i in range(len(A)): findAndCompact(slist, i)\n        #print('### ', slist)\n        cc = Counter(slist)\n        m = cc.most_common(2)\n        return m[0][1] if m[0][0] != -1 else m[1][1]\n    \nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        n = self.p[x]\n        while n >= 0 and self.p[n] != n:\n            n = self.p[n]\n        root = n\n        # compact\n        n = x\n        while n >= 0 and self.p[n] != n:\n            t = self.p[n]\n            self.p[n] = root\n            n= t\n        return root\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "from collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)\n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if p >= x:\n                    break\n                if x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            uf[find(x)] = find(y)\n            \n        for i, a in enumerate(A):\n            if not a % 2:\n                union(A[i], 2)\n            while not a % 2:\n                a //= 2\n            for k in range(3, int(sqrt(A[i])) + 1, 2):\n                if not a % k:\n                    union(A[i], k)\n                while not a % k:\n                    a //= k\n                if a == 1:\n                    break\n            if a > 1:\n                union(A[i], a)\n        return max(Counter([find(a) for a in A]).values())", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n", "class DUSNode:\n    def __init__(self, parent):\n        self.parent = parent\n        self.size = 0\n\nclass DisjointUnionSet:\n    def __init__(self):\n        self.forest = {}\n        \n    def addSet(self, node, key):\n        self.forest[key] = node\n        \n    def find(self, p):\n        while self.forest[p].parent != p:\n            self.forest[p].parent = self.forest[self.forest[p].parent].parent\n            p = self.forest[p].parent\n            \n        return p\n    \n    def union(self, x, y):\n        x = self.find(x)\n        y = self.find(y)\n        \n        if x != y:\n            if self.forest[x].size < self.forest[y].size:\n                x, y = y, x\n                \n            self.forest[y].parent = x\n            self.forest[x].size += self.forest[y].size\n            \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        composites = set()\n        primes = []\n        prime_factors = {k:v for k, v in zip(A, [[] for _ in range(len(A))])}\n        maxA = max(A)\n        for n in range(2, maxA + 1):\n            if n not in composites:\n                primes.append(n)\n                m = n\n                while m <= maxA:\n                    composites.add(m)\n                    if m in prime_factors:\n                        prime_factors[m].append(n)\n                        \n                    m += n\n                    \n        djus = DisjointUnionSet()            \n        for p in primes:\n            djus.addSet(DUSNode(p), p)\n        \n        for pf in list(prime_factors.values()):\n            if pf:\n                djus.forest[djus.find(pf[0])].size += 1\n                \n            for p1, p2 in zip(pf, pf[1:]):\n                djus.union(p1, p2)\n                    \n        return max([node.size for node in list(djus.forest.values())])\n", "from math import sqrt\nfrom collections import defaultdict, Counter\n\ndef get_prime_factors(n):\n    for i in range(2, int(sqrt(n) + 1)):\n        if n % i == 0:\n            return {i} | get_prime_factors(n // i)\n    return {n}\n\n\nclass Solution:\n    def largestComponentSize(self, A):\n        prime_multiples_map = defaultdict(list)\n        for v in A:\n            for factor in get_prime_factors(v):\n                prime_multiples_map[factor].append(v)\n\n        dsu = DSU(A)\n\n        for vertices in list(prime_multiples_map.values()):\n            last = vertices[0]\n            for v in vertices:\n                dsu.union(last, v)\n            \n        parents = [dsu.find(v) for v in A]\n\n        counter = Counter(parents)\n        return counter.most_common(1)[0][1]\n\nclass DSU:\n    def __init__(self, nums):\n        self.p = { n : n for n in nums }\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            self.p[px] = py\n", "class DFU:\n    def __init__(self, n):\n        self.p = list(range(n))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def prime_sets(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.prime_sets(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = DFU(len(A))\n        primes = collections.defaultdict(list)\n        \n        for i, n in enumerate(A):\n            prime_set = self.prime_sets(n)\n            for q in prime_set: primes[q].append(i)\n                \n        for _, items in primes.items():\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n                \n        return max(Counter([UF.find(i) for i in range(len(A))]).values())", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gen_primes(n):\n            candidates = [1] * n\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if candidates[i]:\n                    for j in range(i ** 2, n, i):\n                        candidates[j] = 0\n            return [i for i in range(2, n) if candidates[i]]\n        primes = gen_primes(int(math.sqrt(max(A))) + 1)\n        def factor(n):\n            result = []\n            for i in primes:\n                if i * i > n:\n                    break\n                if n % i == 0:\n                    result.append(i)\n                    while n % i == 0:\n                        n //= i\n            result.append(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            factors = factor(a)\n            for f in factors:\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "import math\n\nclass UnionFind:\n    \n    def __init__(self, n):\n        self.data = list(range(n))\n        self.size = [1] * n\n        \n    def find(self, x):\n        if self.data[x] != x:\n            self.data[x] = self.find(self.data[x])\n        return self.data[x]\n    \n    def union(self, x, y):\n        ix, iy = self.find(x), self.find(y)\n        if ix != iy:\n            self.data[ix] = iy\n            self.size[iy] += self.size[ix]\n            self.size[ix] = 0\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def prime_set(num):\n            res = set()\n            while num % 2 == 0:\n                res.add(2)\n                num //= 2\n            for i in range(3, int(math.sqrt(num)) + 1, 2):\n                while num % i == 0:\n                    res.add(i)\n                    num //= i\n            if num > 2:\n                res.add(num)\n            return res\n        \n        n = len(A)\n        uf = UnionFind(n)\n        primes_dict = collections.defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = prime_set(num)\n            for p in pr_set:\n                primes_dict[p].append(i)\n        for indices in primes_dict.values():\n            for j in range(1, len(indices)):\n                uf.union(indices[j - 1], indices[j])\n                \n        return max(uf.size)\n        \n        \n    def gcd_with_bfs(self, A: List[int]) -> int:\n        graph = collections.defaultdict(set)\n        \n        for i in range(len(A)):\n            for j in range(i, len(A)):\n                if math.gcd(A[i], A[j]) > 1:\n                    graph[A[i]].add(A[j])\n                    graph[A[j]].add(A[i])\n        \n        res = 0\n        seen = set()\n        for a in A:\n            if a not in seen:\n                node_count = 0\n                q = collections.deque([a])\n                seen.add(a)\n                while q:\n                    node = q.popleft()\n                    node_count += 1\n                    seen.add(node)\n                    for child in graph[node]:\n                        if child not in seen:\n                            seen.add(child)\n                            q.append(child)\n                res = max(res, node_count)\n        return res", "from collections import defaultdict\nsmall_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n    \n", "class DUS(object):\n    \n    def __init__(self, n):\n        self.p = [ *list(range(n)) ]\n        self.size = [1] * n\n        \n    def Find(self, x):\n        if self.p[x] == x:\n            return x\n        tmp = []\n        while self.p[x] != x:\n            tmp.append(x)\n            x = self.p[x]\n        for t in tmp:\n            self.p[t] = x\n        return x\n    \n    def Union(self, x, y):\n        xr = self.Find(x)\n        yr = self.Find(y)\n        if xr != yr:\n            self.p[yr] = xr\n            self.size[xr] += self.size[yr]\n            self.size[yr] = 0\n        return \n    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def PFD(num):\n            ret = set()\n            if num % 2 == 0:\n                ret.add(2)\n                while num % 2 == 0:\n                    num //= 2\n            for i in range(3, int(num ** 0.5)+1 , 2 ):\n                if num % i == 0:\n                    ret.add(i)\n                    while num % i == 0:\n                        num //= i\n            if num > 2:\n                ret.add(num)\n            return ret\n        \n        dic = {}\n        dus = DUS(len(A))\n        for idx, a in enumerate(A):\n            for p in PFD(a):\n                if p in dic:\n                    dus.Union(dic[p], idx)\n                dic[p] = idx\n        \n        return max(dus.size)\n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        N = len(A)\n        p = [i for i in range(N)]\n        def uf(i):\n            if i == p[i]: return i\n            p[i] = uf(p[i])\n            return p[i]\n        \n        dt = collections.defaultdict(set)\n        def prime_factor(index):\n            i = A[index]\n            while i % 2 == 0: \n                dt[2].add(index)\n                i //= 2\n            for j in range(3, int(A[index]**0.5) + 1, 2):\n                while i % j == 0:\n                    dt[j].add(index)\n                    i //= j\n            if i > 2: dt[i].add(index)\n                \n        cnt = collections.defaultdict(int)\n        \n        for i in range(N): \n            prime_factor(i)\n        \n        for _, v in list(dt.items()):\n            pi = uf(v.pop())\n            while v:\n                pj = uf(v.pop())\n                p[pj] = pi\n                \n        res = 1\n        for i in range(N):\n            pi = uf(i)\n            cnt[pi] += 1\n            res = max(res, cnt[pi])\n        return res\n", "import sys\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        sys.setrecursionlimit(9000000);\n        \n        def unify(x: int, y: int):\n            f1 = getfa(x);\n            f2 = getfa(y);\n            if f1 != f2:\n                if fa[f1] < fa[f2]:\n                    fa[f1] += fa[f2];\n                    fa[f2] = f1;\n                else:\n                    fa[f2] += fa[f1];\n                    fa[f1] = f2;\n                \n        def getfa(x: int) -> int:\n            i = x;\n            while fa[i] >= 0:\n                i = fa[i];\n            \n            j = i;\n            i = x;\n            while fa[i] >= 0:\n                fa[i], i = j, fa[i];\n                \n            return j;\n        \n        n = len(a);\n        flag = dict();\n        fa = [-1] * n;\n        ans = 1;\n        \n        for i in range(0, n):\n            v = a[i];\n            if v % 2 == 0:\n                if 2 not in flag:\n                    flag[2] = i;\n                else:\n                    unify(flag[2], i);\n                while v % 2 == 0:\n                    v >>= 1;\n                \n            j = 3\n            lim = int(sqrt(v))+1;\n            \n            while j <= lim and j <= v:\n                if v % j:\n                    j += 2;\n                    continue;\n                \n                if j not in flag:\n                    flag[j] = i;\n                else:\n                    unify(flag[j], i);\n                    \n                while v % j == 0:\n                    v //= j;\n                j += 2;\n            \n            if v > 1:\n                if v not in flag:\n                    flag[v] = i;\n                else:\n                    unify(flag[v], i);\n                \n        for i in range(0, n):\n            if fa[i] < 0:\n                ans = max(ans, -fa[i]);\n\n        return ans;\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        par = [-1] * 100001\n        def _find(x):\n            if par[x] == -1:\n                return x\n            \n            par[x] = _find(par[x])\n            return par[x]\n        \n        def _union(x,y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                par[yp] = xp\n                \n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x%i == 0:\n                    _union(i,x)\n                    _union(x, x//i)\n                    \n        count = 0;\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1+cache.get(xp,0))\n            cache[xp] = 1 + cache.get(xp,0)\n        return count\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_factors(n):\n            factors = set()\n            while n % 2 == 0:\n                factors.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                while n % i == 0:\n                    factors.add(i)\n                    n //= i\n            if n > 2:\n                factors.add(n)\n            return factors\n        \n        roots = [i for i in range(len(A))]\n        \n        def find_root(i):\n            while i != roots[i]:\n                roots[i] = roots[roots[i]]\n                i = roots[i]\n            return i\n        \n        primes = defaultdict(list)\n        \n        for i in range(len(A)):\n            factors = get_factors(A[i])\n            for n in factors:\n                primes[n].append(i)\n        \n        for values in list(primes.values()):\n            for i in range(len(values) - 1):\n                roots[find_root(values[i + 1])] = roots[find_root(values[i])]\n                \n        ans = 0\n        counter = defaultdict(int)\n        \n        for i in range(len(roots)):\n            counter[find_root(i)] += 1\n            ans = max(ans, counter[find_root(i)])\n        \n        return ans\n", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        self.sizes = [1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[j] = i\n            self.sizes[i] += self.sizes[j]\n            self.sizes[j] = 0\n        else:\n            if self.disj_set[i] == self.disj_set[j]:\n                self.disj_set[j] -= 1\n            self.disj_set[i] = j\n            self.sizes[j] += self.sizes[i]\n            self.sizes[i] = 0\n    \n    def maxset(self):\n        return max(self.sizes)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gen_primes(n):\n            candidates = [1] * n\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if candidates[i]:\n                    for j in range(i ** 2, n, i):\n                        candidates[j] = 0\n            return [i for i in range(2, n) if candidates[i]]\n        primes = gen_primes(int(math.sqrt(max(A))) + 1)\n        def factor(n):\n            result = []\n            for i in primes:\n                if i * i > n:\n                    break\n                if n % i == 0:\n                    result.append(i)\n                    while n % i == 0:\n                        n //= i\n            result.append(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            factors = factor(a)\n            for f in factors:\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A: return 0\n        root = list(range(max(A) + 1))\n        def find(i):\n            while not root[i] == i:\n                root[i] = root[root[i]] # path compress to reduce test time, since we need to do dfs to get the root, so we can find the current root and set previous to this one, repeat it till get the final root we wanted\n                i = root[i]\n            return i\n        def union(a, i):\n            root[find(a)] = root[find(i)]\n        \n        for a in A:\n            for i in range(2, int(math.sqrt(a)) + 1):\n                if not a % i:\n                    union(a, i)\n                    union(a, a // i)\n                    \n        # for a in A:\n        #     dic[find(a)] += 1\n        #     res = max(res, dic[find(a)])\n        # return res\n        return Counter([find(a) for a in A]).most_common(1)[0][1]\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factors(x):\n            sq = int(x**0.5)\n            f = set()\n            for i in range(2,sq+1):\n                while x%i == 0:\n                    x //= i \n                    f.add(i)\n            if x > 1:\n                f.add(x)\n            return f \n\n        n = len(A)\n        parent = [i for i in range(n)]\n        sz = [1]*n \n        mp = {}\n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        def union(x,y):\n            rx, ry = find(x), find(y)\n            if rx != ry:\n                parent[rx] = ry\n                sz[ry] += sz[rx]\n        for i, a in enumerate(A):\n            fs = factors(a)\n            # print(a,fs,mp)\n            for f in fs:\n                if f in mp:\n                    j = mp[f]\n                    union(j,i)\n                mp[f] = i \n        # print(parent,mp)\n        return max(sz)\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        x = defaultdict(list)\n\n        def _locate(n):\n            if not x[n]:\n                return n\n            x[n] = _locate(x[n])\n            return x[n]\n\n        def _isCommon(n, m):\n            np = _locate(n)\n            mp = _locate(m)\n            if np != mp:\n                x[mp] = np\n\n        for n in A:\n            for i in range(2, int(sqrt(n)) + 1):\n                if not n % i:\n                    _isCommon(i, n)\n                    _isCommon(n, n // i)\n        c = 0\n        cache = {}\n        for n in A:\n            np = _locate(n)\n            c = max(c, 1 + cache.get(np, 0))\n            cache[np] = 1 + cache.get(np, 0)\n        return c\n", "class FU:\n        def __init__(self, n):\n            self.p = [i for i in range(n)]\n            \n        def find(self, x):\n            if self.p[x] != x:\n                self.p[x] = self.find(self.p[x])\n            return self.p[x]\n        \n        def union(self, x, y):\n            px, py = self.find(x), self.find(y)\n            self.p[py] = px\n        \nclass Solution:\n    def primeFactors(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primeFactors(n//i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        fu = FU(len(A))\n        primes = defaultdict(list)\n        for i in range(len(A)):\n            prime = self.primeFactors(A[i])\n            # print(A[i])\n            # print(prime)\n            for pr in prime:\n                primes[pr].append(i)\n        # print(primes)\n        for k, v in list(primes.items()):\n            for i in range(len(v)-1):\n                fu.union(v[i], v[i+1])\n        c = Counter([fu.find(i) for i in range(len(A))])\n        # print(c)\n        return max(c.values())\n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        L = max(A) + 5\n        spf = [i for i in range(L)]\n        for p in range(2, L):\n            if spf[p] != p:\n                continue\n            for i in range(p * p, L, p):\n                spf[i] = min(spf[i], p)\n        def primes(n):\n            while n > 1:\n                yield spf[n]\n                n //= spf[n]\n        rep = [i for i in range(L)]\n        sz = [0] * L\n        def find(x):\n            if rep[x] != x:\n                rep[x] = find(rep[x])\n            return rep[x]\n        def union(x, y):\n            rx = find(x)\n            ry = find(y)\n            if rx == ry:\n                return\n            rep[rx] = ry\n            sz[ry] += sz[rx]\n        for x in A:\n            if x < 2:\n                continue\n            ps = list(primes(x))\n            sz[find(ps[0])] += 1\n            for i in range(len(ps) - 1):\n                union(ps[i], ps[i + 1])\n                #print(\\\"union between %d,%d\\\" % (ps[i], ps[i+1]))\n                #print(\\\"new size: \\\", sz[find(ps[i])])\n        #rint(rep)\n        #print(sz)\n        return max(sz)", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n\ndef gen_primes(n):\n    candidates = [1] * n\n    for i in range(2, int(math.sqrt(n)) + 1):\n        if candidates[i]:\n            for j in range(i ** 2, n, i):\n                candidates[j] = 0\n    return [i for i in range(2, n) if candidates[i]]\nprimes = gen_primes(320)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factor(n):\n            result = set()\n            for i in primes:\n                if i * i > n:\n                    break\n                if n % i == 0:\n                    result.add(i)\n                    while n % i == 0:\n                        n //= i\n            result.add(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            for f in factor(a):\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        #GOOGLE - Union Find Alg\n        #For graph approach (DFS) it will work for a small input. In worst case we will have 20K elem\n        #and we will need to do 20K^2=20*20*10^6 coparison if two num has a common factor. \n        #Time limit will exceed. Therefore use Union Find here.\n        parent = [-1] * 100001\n        \n        def find(x):\n            if parent[x] == -1:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n    \n        def union(x,y):\n            xp=find(x)\n            yp=find(y)\n            if xp != yp:\n                parent[yp] = xp\n        \n        for x in A:\n            for i in range(2, int(sqrt(x))+1):\n                if x % i == 0:\n                    union(i,x)\n                    union(x, x//i)\n        \n        count = 0\n        hashmap = {}\n        for x in A:\n            xp = find(x)\n            count = max(count, 1 + hashmap.get(xp, 0))\n            hashmap[xp] = 1 + hashmap.get(xp, 0)\n        return count\n                    \n        \n        \n", "class Solution:\n    def find(self, i, parent):\n        if parent[i] == -1:\n            return i\n        parent[i] = self.find(parent[i], parent)\n        return parent[i]\n\n    def union(self, i, j, parent):\n        rooti = self.find(i, parent)\n        rootj = self.find(j, parent)\n        if rooti != rootj:\n            parent[rooti] = rootj\n            \n    def largestComponentSize(self, A: List[int]) -> int:\n        hm = defaultdict(int)\n        parent = [-1] * (100001)\n        for i in A:\n            for j in range(2, int(sqrt(i)) +1):\n                if i % j == 0:\n                    self.union(i,j, parent)\n                    self.union(i//j, i, parent)\n        for i in A:\n            parenti = self.find(i,parent)\n            hm[parenti] += 1\n        return max(hm.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent=[-1]*100001\n        def find(x):\n            if parent[x] == -1:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n        def union(x,y):\n            xp = find(x)\n            yp = find(y)\n            if xp != yp:\n                parent[yp] = xp\n                \n            \n        for x in A:\n            for i in range(2,int(sqrt(x))+1):\n                if x%i == 0:\n                    union(i,x)\n                    union(x,x//i)\n                    \n        count=0\n        cache={}\n        for x in A:\n            xp = find(x)\n            count = max(count, 1+cache.get(xp,0))\n            cache[xp] = 1+cache.get(xp,0)\n        return count\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dic = defaultdict(list)\n        \n        def primefactor(x):\n            s = []\n            y = x\n            if x % 2 == 0:\n                s.append(2)\n            while x%2 == 0:\n                x //= 2\n            for i in range(3,floor(sqrt(y))+1,2):\n                if x % i == 0:\n                    s.append(i)\n                while x % i == 0:\n                    x //= i\n            if x > sqrt(y):\n                s.append(x)\n            return s\n        \n        for i in range(n):\n            primes = primefactor(A[i])\n            for d in primes:\n                dic[d].append(i)\n        a = list(range(n))\n        sz = [1] * n\n        \n        def root(i):\n            while(i != a[i]):\n                a[i] = a[a[i]]\n                i = a[i]\n            return i\n        \n        def find(i,j):\n            return root(i) == root(j)\n            \n        def union(i,j):\n            root_i = root(i)\n            root_j = root(j)\n            if sz[root_i] > sz[root_j]:\n                a[root_j] = root_i\n                sz[root_i] += sz[root_j]\n                sz[root_j] = 0\n            else:\n                a[root_i] = root_j\n                sz[root_j] += sz[root_i]\n                sz[root_i] = 0\n            \n        for v in dic.values():\n            for i in range(len(v)-1):\n                if find(v[i],v[i+1]) == False:\n                    union(v[i],v[i+1])\n        return max(sz)", "from math import sqrt\nfrom functools import reduce\nfrom collections import defaultdict\n\nclass Disjoint():\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n\n    def find(self, node):\n        if self.parent[node] != node:\n            self.parent[node] = self.find(self.parent[node])\n        return self.parent[node]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            sx, sy = self.size[px], self.size[py]\n            if sx > sy:\n                self.parent[py] = px\n                self.size[px] += sy\n            else:\n                self.parent[px] = py\n                self.size[py] += sx\n                \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:   return 0\n        \n        \n        fac_to_ind = defaultdict(int)\n        un = Disjoint(len(A))\n        for ind, num in enumerate(A):\n            for fac in range(2, int(math.sqrt(num) + 1)):\n                if num % fac:   continue\n                for f in [fac, num // fac]:\n                    if f not in fac_to_ind:\n                        fac_to_ind[f] = ind\n                    else:\n                        un.union(ind, fac_to_ind[f])\n            if num not in fac_to_ind:\n                fac_to_ind[num] = ind\n            else:\n                un.union(ind, fac_to_ind[num])\n        return max(un.size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313]\n        unions = collections.defaultdict(set)\n        for i, n in enumerate(A):\n            for p in primes:\n                if p * p > n:\n                    break\n                while not n % p:\n                    n //= p\n                    unions[p].add(i)\n            if n > 1:\n                unions[n].add(i)\n        ids = list(range(len(A)))\n        def find(i):\n            if ids[i] != i:\n                ids[i] = find(ids[i])\n            return ids[i]\n        def union(l):\n            s = set(find(i) for i in l)\n            i = s.pop()\n            while s:\n                j = s.pop()\n                ids[j] = i\n        for l in list(unions.values()):\n            union(l)\n        c = collections.Counter(find(i) for i in range(len(A)))\n        return max(c.values())\n", "from math import ceil, sqrt\nfrom typing import List\n\n\nclass Solution:\n    MAXN = 100001\n    spf = [0 for i in range(MAXN)]\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        spf = self.spf\n        MAXN = self.MAXN\n\n        def sieve():\n            spf[1] = 1\n            for i in range(2, MAXN):\n                spf[i] = i\n            for i in range(4, MAXN, 2):\n                spf[i] = 2\n\n            for i in range(3, ceil(sqrt(MAXN))):\n                if spf[i] == i:\n                    for j in range(i * i, MAXN, i):\n                        if spf[j] == j:\n                            spf[j] = i\n\n        def getFactorization(x):\n            ret = []\n            while x != 1:\n                if not ret or spf[x] != ret[-1]:\n                    ret.append(spf[x])\n                x = x // spf[x]\n\n            return ret\n\n        sieve()\n        parents = {0: [0, 0]}\n\n        def find(curr):\n            if curr == parents[curr][0]:\n                return curr\n            return find(parents[curr][0])\n\n        for i in range(len(A)):\n            factors = getFactorization(A[i])\n            parent = 0\n            for f in factors:\n                parents.setdefault(f, [f, 0])\n                p = find(f)\n                if parent != 0 and p != parent:\n                    parents[parent][1] += parents[p][1]\n                    parents[p][0] = parent\n                    parents[p][1] = 0\n                else:\n                    parent = p\n\n            parents[parent][1] += 1\n        return max(list(parents.values()), key=lambda x: x[1])[1]\n\n", "class Solution1:\n    def largestComponentSize(self, A):\n        if not A: return 0\n        def findAndCompact(l, i): # require i >= 0\n            if l[i] == i: return i\n            p = l[i]\n            if p >= 0 and l[p] == p: return p\n            while p >= 0 and l[p] != p:\n                p = l[p]\n            root = p\n            \n            # compact\n            p = i\n            while p >= 0 and l[p] != p:\n                t = l[p]\n                l[p] = root\n                p = t\n            return root\n        \n        slist = [-1] * len(A)\n        d = {} # record prime->(root of union-find set)\n        for i in range(len(A)):\n            n = A[i]\n            has_factor = False\n            for j in range(2, int(sqrt(n)) + 1):\n                if n % j == 0:\n                    has_factor = True\n                    k = n // j\n                    #print(n, j, k)\n                    ri = -1 if slist[i] < 0 else findAndCompact(slist, slist[i])\n                    rj = -1 if j not in d else findAndCompact(slist, d[j])\n                    rk = -1 if k not in d else findAndCompact(slist, d[k])\n                    if ri < 0 and rj < 0 and rk < 0:\n                        slist[i] = d[j] = d[k] = i\n                    else:\n                        mm = min([item for item in (ri, rj, rk) if item >= 0])\n                        if slist[i] >= 0: slist[ri] = mm\n                        if j in d: slist[rj] = mm\n                        if k in d: slist[rk] = mm\n                        slist[i] = d[j] = d[k] = mm\n            if not has_factor: #prime\n                if A[i] not in d: slist[i] = d[A[i]] = i\n                else: slist[i] = d[A[i]]\n            #print(slist, d)\n        \n        for i in range(len(A)): findAndCompact(slist, i)\n        #print('### ', slist)\n        cc = Counter(slist)\n        m = cc.most_common(2)\n        return m[0][1] if m[0][0] != -1 else m[1][1]\n    \nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        n = self.p[x]\n        while n >= 0 and self.p[n] != n:\n            n = self.p[n]\n        root = n\n        # compact\n        n = x\n        while n >= 0 and self.p[n] != n:\n            t = self.p[n]\n            self.p[n] = root\n            n= t\n        return root\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(UF.find(indexes[i]), UF.find(indexes[i+1]))\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        amax = max(A)\n        plist = [2]\n        for k in range(3, int(sqrt(amax)) + 2, 2):\n            for p in plist:\n                if p * p > k:\n                    plist.append(k)\n                    break\n                if k % p == 0: break\n            else:\n                plist.append(k)\n        pset = set(plist)\n        amax //= 2\n        n = n1 = n2 = len(A)\n        k = 0\n        while k < n1:\n            x = A[k]\n            if x in pset:\n                n1 -= 1\n                n2 -= 1\n                A[k] = A[n1]\n                A[n2] = x\n                continue\n            if x < plist[-1]:\n                k += 1\n                continue\n            prime = True\n            for p in plist:\n                if p * p > x: break\n                if x % p == 0:\n                    prime = False\n                    break\n            if not prime:\n                k += 1\n            else:\n                n1 -= 1\n                A[k] = A[n1]\n                if x <= amax:\n                    n2 -= 1\n                    A[n2] = x\n        ans = 1\n        left = n - n2 + n1\n        while left > ans and n1 > 0:\n            n1 -= 1\n            x = A[n1]\n            found = False\n            k = 0\n            while k < n1:\n                y = A[k]\n                p = math.gcd(x, y)\n                if p > 1:\n                    found = True\n                    n1 -= 1\n                    A[k] = A[n1]\n                    while p > 1:\n                        y //= p\n                        p = math.gcd(y, p)\n                    x *= y\n                else:\n                    k += 1\n                if k == n1 and found:\n                    found = False\n                    k = 0\n            k = n - 1\n            while k >= n2:\n                if x % A[k] == 0:\n                    A[k] = A[n2]\n                    n2 += 1\n                else:\n                    k -= 1\n            k = n - n2 + n1\n            ans = max(ans, left - k)\n            left = k\n        return ans", "import math\n\nclass DiscreteSet:\n    def __init__(self, N):\n        self.parent = [i for i in range(N)]\n    \n    def findP(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.findP(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xp, yp = self.findP(x), self.findP(y)\n        self.parent[xp] = yp\n\nclass Solution:\n    def primesSet(self, n):\n        for i in range(2, math.floor(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primesSet(n//i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        dset = DiscreteSet(len(A))\n        primes = defaultdict(list)\n        \n        for i, num in enumerate(A):\n            prSet = self.primesSet(num)\n            print((i,num,prSet))\n            for pr in prSet: primes[pr].append(i)\n        \n        for indices in list(primes.values()):\n            for i in range(len(indices)-1):\n                dset.union(indices[i], indices[i+1])\n\n        cnt = Counter()\n        for i in range(len(A)):\n            cnt[dset.findP(i)] += 1\n        return max(cnt.values())\n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n\n# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n#         graph = {}\n#         for i in range(0, len(A)):\n#             for j in range(i+1, len(A)):\n#                 if self.check(A[i], A[j]):\n#                     if A[i] not in graph:\n#                         graph[A[i]] = [A[j]]\n#                     else:\n#                         graph[A[i]].append(A[j])\n#                     if A[j] not in graph:\n#                         graph[A[j]] = [A[i]]\n#                     else:\n#                         graph[A[j]].append(A[i])\n#         self.visited = set()\n#         self.total = 0\n#         for node in graph:\n#             self.visited.add(node)\n#             self.traverse(node, graph, 0)\n#         return self.total\n    \n#     def traverse(self, root, graph, count):\n#         # if root in self.visited:\n#         #     self.total = max(self.total, count)\n#         #     return\n#         # self.visited.add(root)\n#         # for neigh in graph[root]:\n#         #     self.traverse(neigh, graph, count + 1)\n#         queue = [root]\n#         while queue:\n#             current = queue.pop(0)\n#             count += 1\n#             for neigh in graph[current]:\n#                 if neigh not in self.visited:\n#                     self.visited.add(neigh)\n#                     queue.append(neigh)\n#         self.total = max(self.total, count)\n#         return\n        \n        \n        \n#     def check(self, num1, num2):\n#         i = 2\n#         while i <= num1:\n#             if num2 % i == 0 and num1 % i == 0:\n#                 return True\n#             i += 1\n#         return False\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]* 100001;\n        def _find(x):\n            if parent[x] == -1:\n                return x;\n            parent[x] = _find(parent[x]);\n            return parent[x];\n        \n        def _union(x,y):\n            xp = _find(x);\n            yp = _find(y);\n            if xp != yp:\n                parent[yp] = xp;\n        for x in A:\n            for i in range(2,int(sqrt(x))+1):\n                if(x%i == 0):\n                    _union(i,x);\n                    _union(x, x//i);\n        count = 0;\n        cache = {};\n        for x in A:\n            xp  = _find(x);\n            count = max(count, 1+cache.get(xp,0));\n            cache[xp] = 1+cache.get(xp,0);\n        return count;", "class UnionFind(object):\n    def __init__(self, n):  \n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n        \n    def find(self, x):  \n        while self.uf[self.uf[x]] != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n        return self.uf[x]\n\n    def union(self, x, y):  \n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root: return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factors(n):\n            ff = set()\n            while n % 2 == 0: ff.add(2); n //= 2\n            for i in range(3,int(math.sqrt(n))+1,2): \n                while n % i == 0: ff.add(i); n //= i\n            if n > 2: ff.add(n)\n            return ff\n        \n        uf = UnionFind(len(A))\n        pti = {}\n        for i, el in enumerate(A):\n            primes = factors(el)\n            for p in primes:\n                if p in pti: uf.union(i, pti[p])\n                pti[p] = i\n        return max(uf.size)\n", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gen_primes(n):\n            candidates = [1] * n\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if candidates[i]:\n                    for j in range(i ** 2, n, i):\n                        candidates[j] = 0\n            return [i for i in range(2, n) if candidates[i]]\n        primes = gen_primes(int(math.sqrt(max(A))) + 2)\n        def factor(n):\n            result = set()\n            while n > 1:\n                s = int(math.sqrt(n))\n                f = True\n                for i in primes:\n                    if i > s:\n                        break\n                    if n % i == 0:\n                        result.add(i)\n                        while n % i == 0:\n                            n //= i\n                        f = False\n                        break\n                if f:\n                    result.add(n)\n                    break\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            factors = factor(a)\n            for f in factors:\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        p = list(range(max(A) + 1))\n       \n        def find(x):\n            while p[x] != x:\n                p[x] = p[p[x]]\n                x = p[x]\n            return p[x]\n    \n        def union(x, y):\n            p[find(x)] = p[find(y)]      \n      \n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n    \n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "from math import sqrt\nfrom collections import Counter\nclass UnionFind:\n\n    def __init__(self, length):\n        self.array = [i for i in range(length)]\n\n    def union(self, x, y):\n        xLoc = self.find(x)\n        yLoc = self.find(y)\n        self.array[xLoc] = yLoc\n    \n    def find(self, x):\n        if x != self.array[x]:\n            self.array[x] = self.find(self.array[x])\n        return self.array[x]\n\n    def most(self):\n        for i in range(len(self.array)):\n            self.find(i)\n        count = Counter(self.array)\n        return max(count.values())\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(len(A))\n        \n        def gcf(a,b):\n            while b:\n                a,b = b, a%b\n            return a\n        \n        def primes(x):\n            if x == 2:\n                return {2}\n            if x%2 == 0:\n                return primes(x//2) | {2}\n            for i in range(3, int(sqrt(x)) + 1,2):\n                if x%i == 0:\n                    return primes(x//i) | {i}\n            return {x}\n        facts = {}\n        for i in range(len(A)):\n            for prime in primes(A[i]):\n                if prime not in facts:\n                    facts[prime] = []\n                facts[prime].append(i)\n        for prime in facts:\n            \n            for i in range(len(facts[prime])-1):\n                uf.union(facts[prime][i], facts[prime][i+1])\n        return uf.most()", "class Find:\n    def __init__(self, A):\n        self.l = list(range(len(A)))\n        \n    def find(self, e):\n        if self.l[e] != e:\n            self.l[e] = self.find(self.l[e])\n        return self.l[e]\n    \n    def union(self, x, y):\n        a = self.find(x)\n        b = self.find(y)\n        \n        self.l[a] = b\n        \n    def primes(self, n):\n        for i in range(int(math.sqrt(n)) - 1):\n            if n % (i + 2) == 0:\n                return self.primes(n // (i+2)) | set([i + 2])\n        \n        return set([n])\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factors = defaultdict(list)\n        find = Find(A)\n        \n        for i in range(len(A)):\n            c = find.primes(A[i])\n            for j in c:\n                factors[j].append(i)\n                \n        for x, i in list(factors.items()):\n            for k in range(len(i) - 1):\n                find.union(i[k], i[k+1])\n                \n        counts = list(Counter([find.find(i) for i in range(len(A))]).values())\n        \n        return max(counts)\n        \n", "import math\nimport time\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        links = {}\n        original_nums = set(A)\n        \n        def get_factors(n):\n            out = []\n            for i in range(2,int(math.sqrt(n))+1):\n                if n % i == 0:\n                    out.append(i)\n                    out.append(n//i)\n            return out\n        \n        # start_time = time.time()\n        \n        for num in A:\n            factors = get_factors(num)\n            if num not in links:\n                links[num] = [num]\n            for x in factors:\n                # if num not in links:\n                #     links[num] = [x]\n                # else:\n                links[num].append(x)\n                if x not in links:\n                    links[x] = [num]\n                else:\n                    links[x].append(num)\n        \n        # print(time.time()-start_time)\n        \n        def search(start):\n            if start in seen:\n                return 1\n            stack = [start]\n            size = 0\n            while(stack):\n                cur = stack.pop()\n                # print(cur)\n                seen.add(cur)\n                if cur in original_nums:\n                    size += 1\n                # print(cur)\n                for node in links[cur]:\n                    if node not in seen:\n                        stack.append(node)\n                        seen.add(node)\n            \n            return size\n                \n            \n        largest = 0\n        seen = set()\n        # print(original_nums)\n        # print(links)\n        for num in A:\n            res = search(num)\n            largest = max(largest, res)\n        \n        # print(time.time()-start_time)\n        return largest\n            \n        \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A):\n        if not A: return 0\n        def findAndCompact(l, i): # require i >= 0\n            if l[i] == i: return i\n            p = l[i]\n            if p >= 0 and l[p] == p: return p\n            while p >= 0 and l[p] != p:\n                p = l[p]\n            root = p\n            \n            # compact\n            p = i\n            while p >= 0 and l[p] != p:\n                t = l[p]\n                l[p] = root\n                p = t\n            return root\n        \n        slist = [-1] * len(A)\n        d = {} # record prime->(root of union-find set)\n        for i in range(len(A)):\n            n = A[i]\n            has_factor = False\n            for j in range(2, int(sqrt(n)) + 1):\n                if n % j == 0:\n                    has_factor = True\n                    k = n // j\n                    #print(n, j, k)\n                    ri = -1 if slist[i] < 0 else findAndCompact(slist, slist[i])\n                    rj = -1 if j not in d else findAndCompact(slist, d[j])\n                    rk = -1 if k not in d else findAndCompact(slist, d[k])\n                    if ri < 0 and rj < 0 and rk < 0:\n                        slist[i] = d[j] = d[k] = i\n                    else:\n                        mm = min([item for item in (ri, rj, rk) if item >= 0])\n                        if slist[i] >= 0: slist[ri] = mm\n                        if j in d: slist[rj] = mm\n                        if k in d: slist[rk] = mm\n                        slist[i] = d[j] = d[k] = mm\n            if not has_factor: #prime\n                if A[i] not in d: slist[i] = d[A[i]] = i\n                else: slist[i] = d[A[i]]\n            #print(slist, d)\n        \n        for i in range(len(A)): findAndCompact(slist, i)\n        #print('### ', slist)\n        cc = Counter(slist)\n        m = cc.most_common(1)\n        return m[0][1]", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n        \nclass Solution:\n    def primes_set(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n // i) | set ([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())        ", "# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n        \n        \n        \n#     def find_prime(self, num):\n#         ans = []\n#         for i in range(2, int(math.sqrt(num)) + 1):\n#             if num % i == 0:\n#                 ans.append(i)\n#         return ans\nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())            \n", "class UnionFind():\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.size = [0] * n\n    \n    def find(self, i):\n        if self.parent[i] != i:\n            self.parent[i] = self.find(self.parent[i])\n        return self.parent[i]\n    \n    def union(self, i, j):\n        pi = self.find(i)\n        pj = self.find(j)\n        \n        if pi != pj:\n            self.parent[max(pi, pj)] = min(pi, pj)\n            self.size[min(pi, pj)] += self.size[max(pi, pj)]\n            self.size[max(pi, pj)] = 0 \n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def decompose(num):\n            if num == 1:\n                return []\n            res = []\n            remain = num\n            for factor in range(2, int(math.sqrt(num))+1):\n                if remain % factor == 0:\n                    while remain % factor == 0:\n                        remain //= factor\n                    res.append(factor)\n            if remain > 1 and num % remain == 0:\n                res.append(remain)\n            return res\n        \n       \n        unions = UnionFind(len(A))\n        factor_index = collections.defaultdict(int)\n        for idx, num in enumerate(A):\n            factors = decompose(num)\n            # print(\\\"factors\\\", factors)\n            unions.size[idx] += 1\n            for factor in factors:\n                if factor not in factor_index:\n                    factor_index[factor] = idx\n                unions.union(factor_index[factor], idx)\n                # print(\\\"factor\\\", factor, \\\"unions\\\", unions.parent, unions.size )\n        return max(unions.size)\n        \n            \n            \n", "class UnionFind:\n    def __init__(self, n):\n        self.uf = list(range(n))\n        self.size = defaultdict(lambda: 1)\n\n    def find(self, i):\n        if self.uf[i] != i:\n            self.uf[i] = self.find(self.uf[i])\n        return self.uf[i]\n\n    def union(self, a, b):\n        x, y = self.find(a), self.find(b)\n        if x == y:\n            return\n        self.uf[x] = self.uf[y]\n        self.size[y] += self.size[x]\n        del self.size[x]\n\n        \ndef factors(n):\n    if n % 2 == 0:\n        yield 2\n    while n % 2 == 0:\n        n //= 2\n    for i in range(3, int(n**0.5)+2, 2):\n        if i > n:\n            break\n        if n % i == 0:\n            yield i\n        while n % i == 0:\n            n //= i\n    if n > 2:\n        yield n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        u = UnionFind(len(A))\n        x = {}\n        for i, a in enumerate(A):\n            for f in factors(a):\n                if f in x:\n                    u.union(i, x[f])\n                x[f] = i\n        return max(u.size.values())\n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n", "class Solution:\n    def __init__(self):\n        self.prime = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        factors_2_nodes = dict()\n        B = [[] for i in range(0, n)]\n        for i in range(0, n):\n            num = A[i]\n            found_factor = True\n            while num > 1 and found_factor:\n                found_factor = False\n                limit = int(sqrt(num + 1))\n                for f in self.prime:\n                    if f > limit:\n                        break\n                    if num % f == 0:\n                        if f not in B[i]:\n                            B[i].append(f)\n                            if f in factors_2_nodes:\n                                factors_2_nodes[f].append(i)\n                            else:\n                                factors_2_nodes[f] = [i]\n                        num //= f\n                        found_factor = True\n                        break\n                if not found_factor and num not in B[i]:\n                    B[i].append(num)\n                    if num in factors_2_nodes:\n                        factors_2_nodes[num].append(i)\n                    else:\n                        factors_2_nodes[num] = [i]\n        v = [False] * n\n        m = 0\n        for i in range(0, n):\n            if v[i]: continue\n            queue = [i]\n            c = 0\n            while queue:\n                q = queue.pop()\n                if v[q]: continue\n                v[q] = True\n                c += 1\n                for f in B[q]:\n                    for node in factors_2_nodes[f]:\n                        if not v[node]:\n                            queue.append(node)\n                    factors_2_nodes[f] = []\n            if c > m:\n                m = c\n        return m", "from math import sqrt\nfrom collections import Counter\nclass UnionFind:\n\n    def __init__(self, length):\n        self.array = [i for i in range(length)]\n\n    def union(self, x, y):\n        xLoc = self.find(x)\n        yLoc = self.find(y)\n        self.array[xLoc] = yLoc\n    \n    def find(self, x):\n        if x != self.array[x]:\n            self.array[x] = self.find(self.array[x])\n        return self.array[x]\n\n    def most(self):\n        for i in range(len(self.array)):\n            self.find(i)\n        count = Counter(self.array)\n        return max(count.values())\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(len(A))\n        \n        def gcf(a,b):\n            while b:\n                a,b = b, a%b\n            return a\n        \n        def primes(x):\n            if x == 2:\n                return {2}\n            if x%2 == 0:\n                return primes(x//2) | {2}\n            for i in range(3, int(sqrt(x)) + 1,2):\n                if x%i == 0:\n                    return primes(x//i) | {i}\n            return {x}\n        facts = {}\n        for i in range(len(A)):\n            for prime in primes(A[i]):\n                if prime not in facts:\n                    facts[prime] = []\n                facts[prime].append(i)\n        print(facts)\n        for prime in facts:\n            \n            for i in range(len(facts[prime])-1):\n                uf.union(facts[prime][i], facts[prime][i+1])\n        return uf.most()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        self.ret=0\n        record={}\n        disjoint=[-1]*len(A)\n        def find(x):\n            idx=x\n            while disjoint[idx]>=0:\n                idx=disjoint[idx]\n            while disjoint[x]>=0:\n                tmp=disjoint[x]\n                disjoint[x]=idx\n                x=tmp\n            return idx\n        def union(a,b):\n            if a==b:\n                return\n            a_idx=find(a)\n            b_idx=find(b)\n            if a_idx==b_idx:\n                return\n            disjoint[a_idx]+=disjoint[b_idx]\n            disjoint[b_idx]=a_idx\n            self.ret=min(self.ret,disjoint[a_idx])\n        def factor(x,idx):\n            if x<3:\n                union(record.get(x,idx),idx)\n                record[x]=idx\n                return\n            if x%2==0:\n                union(record.get(2,idx),idx)\n                record[2]=idx\n                while x%2==0:\n                    x=x//2\n            i=3\n            while i*i<=x:\n                if x%i==0:\n                    union(record.get(i,idx),idx)\n                    record[i]=idx\n                while x%i==0:\n                    x=x//i\n                i+=2\n            if x>1:\n                union(record.get(x,idx),idx)\n                record[x]=idx\n        factors=[factor(A[i],i) for i in range(len(A))]\n        return -self.ret", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = {}\n        \n        def find(x):\n            uf.setdefault(x, x)\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n        \n        def union(x, y):\n            uf[find(x)] = find(y)\n            \n        for i, a in enumerate(A):\n            if not a % 2:\n                union(A[i], 2)\n                if a // 2 > 1:\n                    union(A[i], a // 2)\n            while not a % 2:\n                a //= 2\n            for k in range(3, int(sqrt(A[i])) + 1, 2):\n                if not a % k:\n                    union(A[i], k)\n                    if a // k > 1:\n                        union(A[i], a // k)\n                while not a % k:\n                    a //= k\n                if a == 1:\n                    break\n            if a > 1:\n                union(A[i], a)\n        return max(Counter([find(a) for a in A]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = max(A)\n\n        ans = 0\n        uf = UF(n)\n        count = collections.Counter()\n\n        for a in A:\n            for num in range(2, int(sqrt(a) + 1)):\n                if a % num == 0:\n                    uf.union(a, num)\n                    uf.union(a, a // num)\n\n        for a in A:\n            pa = uf.find(a)\n            count[pa] += 1\n            ans = max(ans, count[pa])\n\n        return ans\n\n\nclass UF:\n    def __init__(self, n: int):\n        self.rank = [0] * (n + 1)\n        self.parent = [i for i in range(n + 1)]\n\n    def union(self, u: int, v: int) -> None:\n        pu = self.parent[u]\n        pv = self.parent[v]\n        if pu == pv:\n            return\n\n        if self.rank[pu] < self.rank[pv]:\n            self.parent[pu] = pv\n        elif self.rank[pv] < self.rank[pu]:\n            self.parent[pv] = pu\n        else:\n            self.parent[pu] = pv\n            self.rank[pv] += 1\n\n    def find(self, u: int) -> int:\n        while u != self.parent[u]:\n            self.parent[u] = self.parent[self.parent[u]]\n            u = self.parent[u]\n\n        return u", "class UnionFind(object):\n    def __init__(self,n):\n        self.uf=[i for i in range(n)]\n        self.size=[1]*n\n    \n    def find(self,node):\n        if node!=self.uf[node]:\n            return self.find(self.uf[node])\n        else:\n            return node\n        \n    def union(self,x,y):\n        x_r=self.find(x)\n        y_r=self.find(y)\n        if x_r==y_r:\n            return\n        self.uf[y_r]=x_r\n        self.size[x_r]+=self.size[y_r]\n        self.size[y_r]=0\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def prime(n):\n            cur=set()\n            while n%2==0:\n                cur.add(2)\n                n//=2\n            for i in range(3,int(math.sqrt(n))+1,2):\n                while n%i==0:\n                    cur.add(i)\n                    n//=i\n            if n>2:\n                cur.add(n)\n            return cur\n        \n        index={A[i]:i for i in range(len(A))}\n        uf=UnionFind(len(A))\n        res=collections.defaultdict(list)\n        for i in A:\n            for j in prime(i):\n                res[j].append(i)\n        for i,e in list(res.items()):\n            if e:\n                root=e[0]\n                for j in e[1:]:\n                    uf.union(index[root],index[j])\n        return max(uf.size)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100001\n\n        def _find(x):\n            if parent[x] == -1:\n                return x\n\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x // i)\n\n        count = 0\n        cache = {}\n\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n\n        return count\n", "class DSU():\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0 for _ in range(n)]\n        self.size = n\n    def find(self, x):\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xp, yp = self.find(x), self.find(y)\n        \n        if xp == yp:\n            return False\n        if self.rank[xp] < self.rank[yp]:\n            self.parent[xp] = yp\n        elif self.rank[xp] > self.rank[yp]:\n            self.parent[yp] = xp\n        else:\n            self.parent[xp] = yp\n            self.rank[yp] += 1\n        self.size -= 1\n        return True\n    def getSize(self):\n        return self.size\n    \nclass Solution:\n    # refer submission. https://www.cnblogs.com/grandyang/p/13253468.html\n    def largestComponentSize(self, A: List[int]) -> int:\n        def getFactors(n):\n            res = set()\n            for i in range(2, int(sqrt(n)) + 2):\n                if not n % i:\n                    # don't count 1 in factor. e.g. [1,2,3,4,5,6,7,8,9]\n                    for j in [i, n // i]:\n                        if j != 1:\n                            res.add(j)\n            # prime number.\n            if not res:\n                return {n}\n            return res\n        \n        # buld dsu based on index of A. union index.\n        dsu = DSU(len(A) + 1)\n        factor2Index = {}\n        for i, n in enumerate(A):\n            for factor in getFactors(n):\n                if factor in factor2Index:\n                    dsu.union(i, factor2Index[factor])\n                factor2Index[factor] = i\n        groupSize = collections.defaultdict(int)\n        for i in range(len(A)):\n            groupSize[dsu.find(i)] += 1\n        return max(groupSize.values())\n        \n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nFS = {}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0:\n                n >>= 1\n            if n > 1:\n                FS[f] = factors3(n) + [2]\n            else:\n                FS[f] = [2]\n    return FS[f]\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0:\n                    n = n // i\n                if n > 1:\n                    FS[f] = factors3(n, i + 2) + [i]\n                else:\n                    FS[f] = [i]\n                break\n        else:\n            FS[f] = [f]\n    return FS[f]", "class UnionFind:\n    def __init__(self, n):\n        self.uf = list(range(n))\n        self.size = defaultdict(lambda: 1)\n\n    def find(self, i):\n        if self.uf[i] != i:\n            self.uf[i] = self.find(self.uf[i])\n        return self.uf[i]\n\n    def union(self, a, b):\n        x, y = self.find(a), self.find(b)\n        if x == y:\n            return\n        self.uf[x] = self.uf[y]\n        self.size[y] += self.size[x]\n        del self.size[x]\n\n        \ndef factors(n):\n    if n % 2 == 0:\n        yield 2\n    while n % 2 == 0:\n        n //= 2\n    for i in range(3, int(n**0.5)+2, 2):\n        if i > n:\n            break\n        if n % i == 0:\n            yield i\n        while n % i == 0:\n            n //= i\n    if n > 2:\n        yield n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        u = UnionFind(len(A))\n        x = {}\n        for i, a in enumerate(A):\n            for f in factors(a):\n                if f in x:\n                    u.union(i, x[f])\n                else:\n                    x[f] = i\n        return max(u.size.values())\n", "from collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())", "class DSU():\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0 for _ in range(n)]\n        self.size = n\n    def find(self, x):\n        # print('x = {0}, parent = {1}, self.parent[x] = {2}, cond = {3}'.format(x, self.parent, self.parent[x], x != self.parent[x]))\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xp, yp = self.find(x), self.find(y)\n        \n        if xp == yp:\n            return False\n        # print('union, xp = {0}, yp = {1}'.format(xp, yp))\n        if self.rank[xp] < self.rank[yp]:\n            self.parent[xp] = yp\n        elif self.rank[xp] > self.rank[yp]:\n            self.parent[yp] = xp\n        else:\n            self.parent[xp] = yp\n            self.rank[yp] += 1\n        self.size -= 1\n        return True\n    def getSize(self):\n        return self.size\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def getFactors(n):\n            res = set()\n            for i in range(2, int(sqrt(n)) + 2):\n                if not n % i:\n                    # don't count 1 in factor. e.g. [1,2,3,4,5,6,7,8,9]\n                    for j in [i, n // i]:\n                        if j != 1:\n                            res.add(j)\n                    # res.add(n // i)\n            # prime number.\n            if not res:\n                return {n}\n            return res\n        \n        dsu = DSU(len(A) + 1)\n        factor2Index = {}\n        for i, n in enumerate(A):\n            # print('factor2Index = {0}, n = {1}, factors = {2}'.format(factor2Index, n, getFactors(n)))\n            for factor in getFactors(n):\n                if factor in factor2Index:\n                    # print('factor = {0}, i = {1}, other = {2}'.format(factor, i, factor2Index[factor]))\n                    dsu.union(i, factor2Index[factor])\n                factor2Index[factor] = i\n        groupSize = collections.defaultdict(int)\n        for i in range(len(A)):\n            groupSize[dsu.find(i)] += 1\n        return max(groupSize.values())\n        \n", "class UnionFind:\n    def __init__(self, n):\n        self.uf = list(range(n))\n        self.size = defaultdict(lambda: 1)\n\n    def find(self, i):\n        if self.uf[i] != i:\n            self.uf[i] = self.find(self.uf[i])\n        return self.uf[i]\n\n    def union(self, a, b):\n        x, y = self.find(a), self.find(b)\n        if x == y:\n            return\n        self.uf[x] = self.uf[y]\n        self.size[y] += self.size[x]\n        self.size[x] = 0\n        \nPS = []\n\ndef factors(n):\n    if n % 2 == 0:\n        yield 2\n    while n % 2 == 0:\n        n //= 2\n    for i in range(3, int(n**0.5)+2, 2):\n        if i > n:\n            break\n        if n % i == 0:\n            yield i\n        while n % i == 0:\n            n //= i\n    if n > 2:\n        yield n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        u = UnionFind(len(A))\n        x = {}\n        for i, a in enumerate(A):\n            for f in factors(a):\n                if f in x:\n                    u.union(i, x[f])\n                x[f] = i\n        return max(u.size.values())\n", "class UnionFind:\n    def __init__(self, n):\n        self.uf = list(range(n))\n        self.size = defaultdict(lambda: 1)\n\n    def find(self, i):\n        if self.uf[i] != i:\n            self.uf[i] = self.find(self.uf[i])\n        return self.uf[i]\n\n    def union(self, a, b):\n        x, y = self.find(a), self.find(b)\n        if x == y:\n            return\n        self.uf[x] = self.uf[y]\n        self.size[y] += self.size[x]\n        # self.size[x] = 0\n\n\ndef factors(n):\n    if n % 2 == 0:\n        yield 2\n    while n % 2 == 0:\n        n //= 2\n    for i in range(3, int(n**0.5)+2, 2):\n        if i > n:\n            break\n        if n % i == 0:\n            yield i\n        while n % i == 0:\n            n //= i\n    if n > 2:\n        yield n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        u = UnionFind(len(A))\n        x = {}\n        for i, a in enumerate(A):\n            for f in factors(a):\n                if f in x:\n                    u.union(i, x[f])\n                x[f] = i\n        return max(u.size.values())\n", "def sieve(n):\n    if n < 3:\n        return\n    yield 2\n    p = set(range(5, n, 2))\n    i = 3\n    while i < n:\n        yield i\n        p.difference_update(list(range(i*i, n, i*2)))\n        for i in range(i+2, n, 2):\n            if i in p:\n                p.remove(i)\n                break\n        else:\n            return\n    \n    \nclass UnionFind:\n    def __init__(self, n):\n        self.uf = list(range(n))\n        self.size = defaultdict(lambda: 1)\n\n    def find(self, i):\n        if self.uf[i] != i:\n            self.uf[i] = self.find(self.uf[i])\n        return self.uf[i]\n\n    def union(self, a, b):\n        x, y = self.find(a), self.find(b)\n        if x == y:\n            return\n        self.uf[x] = self.uf[y]\n        self.size[y] += self.size[x]\n        self.size[x] = 0\n        \nPS = []\n\ndef factors(n):\n    if n % 2 == 0:\n        yield 2\n    while n % 2 == 0:\n        n //= 2\n    for i in range(3, int(n**0.5)+2, 2):\n        if i > n:\n            break\n        if n % i == 0:\n            yield i\n        while n % i == 0:\n            n //= i\n    if n > 2:\n        yield n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        u = UnionFind(len(A))\n        x = {}\n        for i, a in enumerate(A):\n            for f in factors(a):\n                if f in x:\n                    u.union(i, x[f])\n                x[f] = i\n        return max(u.size.values())\n", "class DSU():\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [0 for _ in range(n)]\n        self.size = n\n    def find(self, x):\n        # print('x = {0}, parent = {1}, self.parent[x] = {2}, cond = {3}'.format(x, self.parent, self.parent[x], x != self.parent[x]))\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xp, yp = self.find(x), self.find(y)\n        \n        if xp == yp:\n            return False\n        # print('union, xp = {0}, yp = {1}'.format(xp, yp))\n        if self.rank[xp] < self.rank[yp]:\n            self.parent[xp] = yp\n        elif self.rank[xp] > self.rank[yp]:\n            self.parent[yp] = xp\n        else:\n            self.parent[xp] = yp\n            self.rank[yp] += 1\n        self.size -= 1\n        return True\n    def getSize(self):\n        return self.size\n    \nclass Solution:\n    # refer submission. https://www.cnblogs.com/grandyang/p/13253468.html\n    def largestComponentSize(self, A: List[int]) -> int:\n        def getFactors(n):\n            res = set()\n            for i in range(2, int(sqrt(n)) + 2):\n                if not n % i:\n                    # don't count 1 in factor. e.g. [1,2,3,4,5,6,7,8,9]\n                    for j in [i, n // i]:\n                        if j != 1:\n                            res.add(j)\n            # prime number.\n            if not res:\n                return {n}\n            return res\n        \n        # buld dsu based on index of A. union index.\n        dsu = DSU(len(A) + 1)\n        factor2Index = {}\n        for i, n in enumerate(A):\n            for factor in getFactors(n):\n                if factor in factor2Index:\n                    dsu.union(i, factor2Index[factor])\n                factor2Index[factor] = i\n        groupSize = collections.defaultdict(int)\n        for i in range(len(A)):\n            groupSize[dsu.find(i)] += 1\n        return max(groupSize.values())\n        \n", "class DFU:\n    def __init__(self, n):\n        self.p = list(range(n)) \n        \n    def find(self, x):\n        if self.p[x] != x: \n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr \n\nclass Solution:\n    def primes_set(self, d):\n        for i in range(2, int(math.sqrt(d)) + 1):\n            if d % i == 0:\n                return self.primes_set(d // i) | set([i])\n        return set([d])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        UF = DFU(len(A))\n        primes = collections.defaultdict(list)\n        \n        for i, d in enumerate(A):\n            primes_set = self.primes_set(d)\n            for q in primes_set: primes[q].append(i) \n        \n        \n        for key, items in list(primes.items()):\n            for i in range(len(items) - 1):\n                UF.union(items[i], items[i + 1])\n        \n        # print(UF.p)\n        return max(Counter([UF.find(i) for i in range(len(A))]).values())\n            \n", "class Solution:\n  def largestComponentSize(self, A):\n    p = list(range(max(A) + 1))\n       \n    def find(x):\n      while p[x] != x:\n        p[x] = p[p[x]]\n        x = p[x]\n      return x\n    \n    def union(x, y):\n      p[find(x)] = p[find(y)]      \n      \n    for a in A:     \n      for k in range(2, int(math.sqrt(a) + 1)):        \n        if a % k == 0:\n          union(a, k)\n          union(a, a // k)\n    \n    return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def union(x, y):\n            graph[find(x)] = find(y)\n        \n        def find(x):\n            path = []\n            while graph[x] != x:\n                path.append(x)\n                x = graph[x]\n            for n in path:\n                graph[n] = x\n            return x\n\n        graph = {}\n        for i, num in enumerate(A):\n            if num not in graph:\n                graph[num] = num\n            for factor in range(2, int(math.sqrt(num) + 1)):\n                if num % factor == 0:\n                    for fac in (factor, num // factor):\n                        if fac == 0:\n                            print(num, fac)\n                        if fac in graph:\n                            union(num, graph[fac])\n                        else:\n                            graph[fac] = num\n\n        roots = collections.defaultdict(int)\n        for num in A:\n            roots[find(num)] += 1\n        return max(roots.values())", "class Solution:\n  def largestComponentSize(self, A):\n    p = list(range(max(A) + 1))\n       \n    def find(x):\n      while p[x] != x:\n        p[x] = p[p[x]]\n        x = p[x]\n      return x\n    \n    def union(x, y):\n      p[find(x)] = p[find(y)]      \n      \n    for a in A:     \n      for k in range(2, int(math.sqrt(a) + 1)):    \n        if a % k == 0:\n          union(a, a // k)\n          union(a, k)\n    return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        self.ret=0\n        record={}\n        disjoint=[-1]*len(A)\n        def find(x):\n            idx=x\n            while disjoint[idx]>=0:\n                idx=disjoint[idx]\n            while disjoint[x]>=0:\n                tmp=disjoint[x]\n                disjoint[x]=idx\n                x=tmp\n            return idx\n        def union(a,b):\n            if a==b:\n                return\n            a_idx=find(a)\n            b_idx=find(b)\n            if a_idx==b_idx:\n                return\n            disjoint[a_idx]+=disjoint[b_idx]\n            disjoint[b_idx]=a_idx\n            self.ret=min(self.ret,disjoint[a_idx])\n        def factor(x,idx):\n            if x%2==0:\n                union(record.get(2,idx),idx)\n                record[2]=idx\n                while x%2==0:\n                    x=x//2\n            i=3\n            while i*i<=x:\n                if x%i==0:\n                    union(record.get(i,idx),idx)\n                    record[i]=idx\n                while x%i==0:\n                    x=x//i\n                i+=2\n            if x>1:\n                union(record.get(x,idx),idx)\n                record[x]=idx\n        for i,item in enumerate(A,0):\n            factor(item,i)\n        return -self.ret", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        \n        def _find(x):\n            if parent[x] == -1: return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n        \n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n                \n        for x in A:\n            for i in range(2, int(sqrt(x))+1):\n                if x%i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n                    \n        count = 0\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1+cache.get(xp,0))\n            cache[xp] = 1+cache.get(xp,0)\n        return count           ", "class DisjointSet:\n    def __init__(self, size):\n        self.parents = list(range(size))\n        self.sizes = [1]*size\n        \n    def find(self, x):\n        if self.parents[x] != x:\n            self.parents[x] = self.find(self.parents[x])\n        return self.parents[x]\n    \n    def union(self, x, y):\n        parent_x = self.find(x)\n        parent_y = self.find(y)\n        if parent_x != parent_y:\n            self.sizes[parent_x] += self.sizes[parent_y]\n            self.parents[parent_y] = parent_x\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        N = len(A)\n        def to_divisors(n):\n            if n%6 == 0:\n                return [2, 3]\n            if n%3 == 0:\n                return [3]\n            if n%2 == 0:\n                return [2]\n            return []\n        maxA = max(A)\n        divisors = [to_divisors(i) for i in range(maxA+1)]\n        for i in range(4, maxA+1):\n            if len(divisors[i]) == 0:\n                for j in range(i, maxA+1, i):\n                    divisors[j].append(i)\n        disjoint_set = DisjointSet(N)\n        divisor_to_index = {}\n        for i, a in enumerate(A):\n            for d in divisors[a]:\n                if d in divisor_to_index:\n                    disjoint_set.union(i, divisor_to_index[d])\n                divisor_to_index[d] = i\n        return max(disjoint_set.sizes)", "class DSU:\n    def __init__(self, n: int):\n        self.n = n\n        self.root = list(range(n))\n        self.size = [1] * n\n        self.max = 1\n    \n    def find(self, x: int) -> int:      \n        if self.root[x] != x:\n            self.root[x] = self.find(self.root[x])\n        return self.root[x]     \n   \n    def union(self, x: int, y: int):\n        rx, ry = self.find(x), self.find(y)\n        if not rx == ry:\n            self.root[rx] = ry\n            self.size[ry] += self.size[rx]\n            self.max = max(self.max, self.size[ry])\n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dsu = DSU(n)\n        seen = {}\n        for i, a in enumerate(A):\n            for j in range(2, int(math.sqrt(a)) + 1):\n                if a % j: continue\n                if j in seen:    \n                    dsu.union(i, seen[j])\n                else:        \n                    seen[j] = i\n                if a // j in seen:    \n                    dsu.union(i, seen[a // j])\n                else:        \n                    seen[a // j] = i\n            if a in seen:\n                dsu.union(i, seen[a])\n            else:    \n                seen[a] = i\n        return dsu.max               ", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        p = list(range(max(A) + 1))\n        def find(x):\n            while p[x] != x:\n                p[x] = p[p[x]]\n                x = p[x]\n            return x\n\n        def union(x, y):\n             p[find(x)] = p[find(y)]      \n\n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "from typing import List\nfrom collections import defaultdict\nimport time\n\nDEBUG = False\n# DEBUG = True\n\ndef debug(*args):\n    if not DEBUG:\n        return\n    print((*args))\n\nclass Sieve:\n    def __init__(self, max_n):\n        self.prime_factors = defaultdict(list)\n        for i in range(2, max_n + 1):\n            if len(self.prime_factors[i]) > 0:\n                continue\n            for j in range(i, max_n + 1, i):\n                self.prime_factors[j].append(i)\n\n\n    def factors(self, n):\n        return self.prime_factors[n]\n\nsieve = Sieve(100000)\n\n# s = Sieve(10000)\n# print(s.factors(6))\n# print(s.factors(512))\n# print(s.factors(1007))\n# print(s.factors(5040))\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        # start = time.time()\n        #\n        by_factors = defaultdict(list)\n        for x in a:\n            for f in sieve.factors(x):\n                by_factors[f].append(x)\n\n        seen = set()\n        seenf = set()\n        ans = 0\n\n        for x in a:\n            if x in seen:\n                continue\n            seen.add(x)\n            streak = 1\n            todo = [f for f in sieve.factors(x) if f not in seenf]\n            while len(todo) > 0:\n                f = todo.pop()\n                seenf.add(f)\n                for cousin in by_factors[f]:\n                    if cousin not in seen:\n                        seen.add(cousin)\n                        streak += 1\n                        for ff in sieve.factors(cousin):\n                            if ff not in seenf:\n                                todo.append(ff)\n                                seenf.add(ff)\n            ans = max(ans, streak)\n\n        # end = time.time()\n        # print(end - start)\n        return ans\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = max(A) + 1\n        parent = [i for i in range(n)]\n        rank = [0] * n\n        \n        for a in A:\n            for k in range(2, int(sqrt(a)) + 1):\n                if a % k == 0:\n                    self.union(parent, a, k, rank)\n                    self.union(parent, a, a // k, rank)\n        \n        counter = collections.Counter()\n        for a in A:\n            counter[self.find_root(parent, a)] += 1\n        \n        return max(counter.values())\n    \n    def find_root(self, parent, x):\n        if parent[x] != x:\n            parent[x] = self.find_root(parent, parent[x])\n        return parent[x]\n    \n    def union(self, parent, x, y, rank):\n        x_root = self.find_root(parent, x)\n        y_root = self.find_root(parent, y)\n        if x_root != y_root:\n            if rank[x_root] < rank[y_root]:\n                parent[x_root] = y_root\n            elif rank[x_root] > rank[y_root]:\n                parent[y_root] = x_root\n            else:\n                parent[x_root] = y_root\n                rank[y_root] += 1\n    \n    def find_common_factor(self, a, b):\n        for i in range(2, min(a, b) + 1):\n            if a % i == 0 and b % i == 0:\n                return True\n        return False\n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        self.s=[1]*n\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def add_prime(i,j,primes):\n            if i not in primes:\n                primes[i]=[j]\n            else:\n                primes[i].append(j)\n        n=len(A)        \n        g=UF(n)\n        primes={}\n        for j,k in enumerate(A):\n            i=2\n            while i*i<=k:\n                if k%i==0:\n                    add_prime(i,j,primes)\n                    while k%i==0:\n                        k=k//i\n                i+=1\n            if k>1:\n                add_prime(k,j,primes)\n        # print(primes)\n        for l in primes.values():\n            j,r=l[0],g.find(l[0])\n            for i in l[1:]:\n                nd=g.find(i)\n                if nd!=r:\n                    g.p[nd]=r\n                    g.s[r]+=g.s[nd]\n        # print(g.p)\n        # print(g.s)\n        return max(g.s)", "import math\n\nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        self.sizes = [1]*N\n\n    def find(self, x):\n        if x != self.p[x]:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        x_root, y_root = self.find(x), self.find(y)\n        if x_root == y_root:\n            return\n        \n        if self.sizes[x_root] > self.sizes[y_root]:\n            self.p[x_root] = y_root\n            self.sizes[y_root] += self.sizes[x_root]\n        else:\n            self.p[y_root] = x_root\n            self.sizes[x_root] += self.sizes[y_root]\n\nclass Solution:\n    def prime_set(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.prime_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A: List[int]) -> int:               \n        prime_map = {}\n        for i in range(len(A)):\n            P = self.prime_set(A[i])\n            for p in P:\n                if p not in prime_map:\n                    prime_map[p] = []\n                prime_map[p].append(i)\n        \n        DSU_groups = DSU(len(A))\n        for _, group in prime_map.items():\n            for i in range(len(group)-1):\n                DSU_groups.union(group[i], group[i+1])\n        \n        return max(DSU_groups.sizes)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        class UF:\n            def __init__(self, N):\n                self.parents = [i for i in range(N)]\n                self.sizes = [1 for _ in range(N)]\n                self.max = 1\n            \n            def find(self, x):\n                if self.parents[x] != x:\n                    self.parents[x] = self.find(self.parents[x])\n                return self.parents[x]\n            \n            def union(self, x, y):\n                x = self.find(x)\n                y = self.find(y)\n                if self.sizes[x] < self.sizes[y]:\n                    x, y = y, x\n                if x != y:\n                    self.parents[y] = x\n                    self.sizes[x] += self.sizes[y]\n                    self.max = max(self.max, self.sizes[x])\n        uf = UF(len(A))\n        \n        dic = {}\n        for i, num in enumerate(A):\n            for factor in range(2, int(math.sqrt(num) + 1)):\n                # if factor**2 > num:\n                #     break\n                if num%factor == 0:\n                    for fac in [factor, num//factor]:\n                        if fac in dic:\n                            uf.union(dic[fac], i)\n                        else:\n                            dic[fac] = i\n            if num in dic:\n                uf.union(dic[num], i)\n            else:\n                dic[num] = i\n        return uf.max", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent=[-1]*100001\n        def _find(x):\n            if parent[x]==-1:\n                return x\n            parent[x]=_find(parent[x])\n            return parent[x]\n        def _union(x, y):\n            xp=_find(x)\n            yp=_find(y)\n            if xp!=yp:\n                parent[yp]=xp\n        for x in A:\n            for i in range(2, int(sqrt(x))+1):\n                if x%i==0:\n                    _union(i,x)\n                    _union(x,x//i)\n        count=0\n        cache={}\n        for x in A:\n            xp=_find(x)\n            count=max(count,1+cache.get(xp,0))\n            cache[xp]=1+cache.get(xp,0)\n        return count    \n                    \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100001\n\n        def _find(x):\n            if parent[x] == -1:\n                return x\n\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x // i)\n\n        cache = {}\n\n        for x in A:\n            xp = _find(x)\n            cache[xp] = 1 + cache.get(xp, 0)\n\n        print(cache)\n        cache1 = sorted(list(cache.items()), key=lambda x: x[1])\n        max = (cache1[-1][0])\n        return cache[max]\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        p = list(range(max(A) + 1))\n\n        def find(x):\n            while p[x] != x:\n                p[x] = p[p[x]]\n                x = p[x]\n            return x\n\n        def union(x, y):\n            p[find(x)] = p[find(y)]      \n\n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parents = {val:val for val in A}\n        sizes = {val:1 for val in A}\n        factorprez = {} \n        maxsize = 0\n        \n        def union(one, two):\n            r1 = findroot(one)\n            r2 = findroot(two)\n            \n            if r1 == r2: return sizes[r1]\n            \n            big, small = (r1, r2) if sizes[r1] > sizes[r2] else (r2, r1)\n            parents[small] = big\n            sizes[big] += sizes[small]\n            return sizes[big]\n            \n        def findroot(node):\n            if parents[node] != node:\n                node = findroot(parents[node])\n            return parents[node]\n        \n        def primes_before(val):\n            candidates = [True] * (val + 1)\n            primes = []\n            for i in range(2, len(candidates)):\n                if not candidates[i]: continue\n                primes.append(i)\n                for j in range(i, val+1, i):\n                    candidates[j] = False\n            return primes\n        \n        primes = primes_before(100000)\n        primeset = set(primes)\n        \n        for val in A:\n            sval = val\n            prime_idx = 0\n            while sval not in primeset and primes[prime_idx] <= sval:\n                if sval % primes[prime_idx] == 0:\n                    if primes[prime_idx] in factorprez:\n                        maxsize = max(maxsize, union(val, factorprez[primes[prime_idx]]))\n                    else:\n                        factorprez[primes[prime_idx]] = val\n                    \n                    while sval % primes[prime_idx] == 0:\n                        sval //= primes[prime_idx]\n                \n                prime_idx += 1\n            \n            if sval in primeset:\n                if sval in factorprez:\n                    maxsize = max(maxsize, union(val, factorprez[sval]))\n                else:\n                    factorprez[sval] = val\n\n        return maxsize", "class UnionFind:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.rank = [0]*N\n        self.size = [0]*N\n        \n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px==py: return\n        if self.rank[px]<self.rank[py]:\n            self.par[px]=py\n            self.size[py]+=self.size[px]\n        elif self.rank[px]>self.rank[py]:\n            self.par[py]=px\n            self.size[px]+=self.size[py]\n        else:\n            self.par[py]=px\n            self.rank[px]+=1\n            self.size[px]+=self.size[py]\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        N = max(A)\n        primes = []\n        res =0\n        for i in range(2, int(N**0.5)+1):\n            for j in primes:\n                if i%j==0:\n                    break\n            else:\n                primes.append(i)\n\n        uf = UnionFind(N+1)\n        used_primes = set()\n        for a in A:\n            if a<2: continue\n            a_primes = []\n            for p in primes:\n                if p*p>a: break\n                if a%p == 0:\n                    a_primes.append(p)\n                    while a%p == 0:\n                        a //= p\n            if a>1:\n                a_primes.append(a)\n                \n            idx = uf.find(a_primes[0])\n            used_primes.add(a_primes[0])\n            uf.size[idx] += 1\n            for i in range(1, len(a_primes)):\n                uf.union(a_primes[0], a_primes[i])\n            \n        for a in used_primes:\n            idx = uf.find(a)\n            res = max(res, uf.size[idx])\n            \n        return res\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        ##############################\n        # Union Find\n        parents = [-1] * (max(A) + 1)\n\n        def find(x :int) -> int:\n            if parents[x] < 0:\n                return x\n            \n            parents[x] = find( parents[x] )\n            return parents[x]\n\n        def union(x,y):\n            root_x = find(x)\n            root_y = find(y)\n\n            if root_x == root_y:\n                return\n            \n            depth_x = parents[root_x]\n            depth_y = parents[root_y]\n\n            if depth_x <= depth_y:\n                parents[root_y] = root_x\n\n                if depth_x == depth_y:\n                    parents[root_x] -= 1\n\n            else:\n                parents[root_x] = root_y\n        ##############################\n\n\n        def get_factor(n :int) -> list:\n            ans = []\n\n            for i in range(2, int(n**(1/2)+1) ):  # exclude \\\"factor 1\\\" and \\\"max factor\\\"\n                if  n % i == 0:\n                    ans.append(i)\n\n                    d = n / i\n                    if (d != i) and (d % 1 == 0):\n                        ans.append( int(d) )\n\n            return ans\n\n\n        for num in A:\n            fact = get_factor(num)\n\n            for v in fact:\n                union(num, v)\n        \n\n        group = [ find(num) for num in A ]\n        cnt = Counter(group)\n        \n        return cnt.most_common(1)[0][1]\n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for __, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        self.s=[1]*n\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self,x,y):\n        xr,yr = self.find(x), self.find(y)\n        self.s[xr]+=self.s[yr]\n        self.p[yr]=xr    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def add_prime(i,j,primes):\n            if i not in primes:\n                primes[i]=[j]\n            else:\n                primes[i].append(j)\n                \n        g=UF(len(A))\n        primes={}\n        for j,k in enumerate(A):\n            i=2\n            while i*i<=k:\n                if k%i==0:\n                    add_prime(i,j,primes)\n                    while k%i==0:\n                        k=k//i\n                i+=1\n            if k>1:\n                add_prime(k,j,primes)\n        # print(primes)\n        for l in primes.values():\n            j,r=l[0],g.find(l[0])\n            for i in l[1:]:\n                if g.find(i)!=r:\n                    g.union(j,i)\n        # print(g.p)\n        # print(g.s)\n        return max(g.s)", "\nclass Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        parent = [-1]*100001\n\n        def _find (x):\n\n            if parent[x] == -1:\n\n                return x\n\n            parent[x] = _find(parent[x])\n\n            return parent[x]\n\n        def _union(x, y):\n\n            xp = _find(x)\n\n            yp = _find(y)\n\n            if xp != yp:\n\n                parent[yp] = xp\n\n        for x in A:\n\n            for i in range(2, int(sqrt(x)) + 1):\n\n                if x % i == 0:\n\n                    _union(i, x)\n\n                    _union(x, x//i)\n\n        \n\n        count = 0;\n\n        cache = {}\n\n        for x in A:\n\n            xp = _find(x)\n\n            count = max(count, 1 + cache.get(xp, 0))\n\n            cache[xp] = 1 + cache.get(xp, 0)\n\n        return count\n\n    \n\n    # O(N * sqrt*max(A[i]))\n", "import math\n\nclass Solution:\n    \n    def __init__(self):\n        self.prime_divisors_cache = {}\n    \n    def prime_divisors(self, x, i=2):\n        if x in self.prime_divisors_cache:\n            return self.prime_divisors_cache[x]\n        while i * i <= x:\n            if x % i != 0:\n                i += 1\n                if i > 3:\n                    i += 1\n            else:\n                self.prime_divisors_cache[x] = set([i]) | self.prime_divisors(x // i, i)\n                return self.prime_divisors_cache[x]\n    \n        res = set()\n        if x > 1:\n            res.add(x)\n        \n        self.prime_divisors_cache[x] = res\n        return self.prime_divisors_cache[x]\n            \n            \n    def largestComponentSize(self, A: List[int]) -> int:\n        # related if NOT coprime\n        \n        # we can keep associated a list of prime factors with each set \n        \n        # integers in A are unique\n        # form a disjoint set structure\n        # node label -> parent\n        parent = dict()\n        # representative label -> size of set\n        size = dict()\n        # keep track of list of representatives for ease\n        reps = set()\n        \n        def getRep(x):\n            # compress path to parent\n            while parent[x] != x:\n                x, parent[x] = parent[x], parent[parent[x]]\n            return x\n        \n        # def getSize(x):\n        #     return size[getRep(x)]\n            \n        def add(x):\n            parent[x] = x\n            size[x] = 1\n            reps.add(x)\n        \n        def merge(x, y):\n            x = getRep(x)\n            y = getRep(y)\n            if x == y:\n                return\n            if size[x] < size[y]:\n                x, y = y, x\n            size[x] += size.pop(y)\n            parent[y] = x\n            reps.remove(y)\n        \n        # prime -> list of numbers it divides\n        prime2dividend = {}\n        for x in A:\n            add(x)\n            for p in self.prime_divisors(x):\n                if not p in prime2dividend:\n                    prime2dividend[p] = [x]\n                else:\n                    prime2dividend[p].append(x)\n        \n        for _, xs in list(prime2dividend.items()):\n            # guaranteed to be one\n            first = xs.pop()\n            for x in xs:\n                merge(first, x)\n        \n        return max([size[rep] for rep in reps])\n        \n        \n        \n", "class Solution:    \n    def get_prime_numbers(self, A, max_num: int) -> List[int]:\n        is_prime_list = [True] * (max_num + 1)        \n        prime_to_nums_dict = defaultdict(list)\n        \n        for i in range(2, max_num + 1):            \n            if is_prime_list[i] == False: continue\n            \n            num = i\n            while num <= max_num:\n                if num in A:\n                    prime_to_nums_dict[i].append(num)                                \n                is_prime_list[num] = False\n                num += i            \n        \n        return prime_to_nums_dict\n    \n    def find(self, union_list, index: int) -> int:\n        if index == union_list[index]: return index\n        #return self.find(union_list, union_list[index])    \n        parent = self.find(union_list, union_list[index])\n        union_list[index] = parent\n        return parent\n        \n    def union(self, union_list, index1: int, index2: int) -> None:\n        union1, union2 = self.find(union_list, index1), self.find(union_list, index2)                \n        union_list[union1], union_list[index2] = union2, union2\n        #union_list[union1] = union2\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        if len(A) == 0: return 0        \n        max_num = max(A)\n        union_list = [i for i in range(max_num + 1)]\n        count_list = [0] * (max_num + 1)\n        \n        # get prime numbers\n        prime_to_nums_dict = self.get_prime_numbers(set(A), max_num) # prime numbers of A's numbers\n        \n        # linking numbers having the same prime \n        for prime, nums in list(prime_to_nums_dict.items()):\n            for i in range(len(nums) - 1):\n                self.union(union_list, nums[i], nums[i + 1])\n        \n        # print(prime_to_nums_dict)\n        # print(union_list)\n        \n        # counting numbers in a component        \n        for i, num in enumerate(A):\n            #if num == 1: continue  \n            count_list[self.find(union_list, num)] += 1        \n        #print(count_list)\n        return max(count_list)\n# Time complexity: O(n * p) where n is the maximum number of A and p is the number of prime numbers less than n\n# Space complexity: O(n + p) we can ignore p\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        ma = max(A)\n        N = len(A)\n        m = list(range(ma+1))\n        for a in A:\n            for k in range(2, int(math.sqrt(a))+1):\n                if a%k == 0:\n                    self.u(m,a,k)\n                    self.u(m,a,a//k)\n        count = collections.defaultdict(int)\n        for a in A:\n            count[self.f(m,a)] +=1\n        return max(count.values())\n    def f(self, m, a):\n        while m[a] != a:\n            m[a] = m[m[a]]\n            a = m[a]\n        return a\n    def u(self, m, a, b):\n        if m[a] == m[b]: return\n        pa = self.f(m,a)\n        pb = self.f(m,b)\n        m[pa] = pb", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]\n        \n    def find(self,x):\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def add_prime(i,j,primes):\n            if i not in primes:\n                primes[i]=[j]\n            else:\n                primes[i].append(j)\n        n=len(A)        \n        g=UF(n)\n        primes={}\n        for j,k in enumerate(A):\n            i=2\n            while i*i<=k:\n                if k%i==0:\n                    add_prime(i,j,primes)\n                    while k%i==0:\n                        k=k//i\n                i+=1\n            if k>1:\n                add_prime(k,j,primes)\n        # print(primes)\n        for l in primes.values():\n            j,r=l[0],g.find(l[0])\n            for i in l[1:]:\n                s=g.find(i)\n                if s!=r:\n                    g.p[s]=r\n        # print(g.p)\n        # print(g.s)\n        return max(Counter([g.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        p = list(range(max(A) + 1))\n       \n        def find(x):\n            while p[x] != x:\n                p[x] = p[p[x]]\n                x = p[x]\n            return x\n    \n        def union(x, y):\n            p[find(x)] = p[find(y)]      \n\n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "import math\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = dict()\n        \n        def find_parent(x):\n            if x not in parent:\n                parent[x] = -1\n                return x \n            \n            if parent[x] == -1:\n                return x\n            parent[x] = find_parent(parent[x])\n            return parent[x]\n        \n        def union_num(x, y):\n            px = find_parent(x)\n            py = find_parent(y)\n            if px != py:\n                parent[py] = px\n            return\n        \n        for x in A:\n            for i in range(2, int(math.sqrt(x))+1):\n                if x%i == 0:\n                    union_num(i, x)\n                    union_num(i, x//i)\n                \n        count = 0\n        count_ref = dict()\n        for x in A:\n            p = find_parent(x)\n            count_ref[p] = count_ref.get(p,0) + 1\n            count = max(count, count_ref[p])\n        return count\n                \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        par=[-1]*100001\n        def find1(x):\n            if par[x]==-1:\n                return x\n            par[x]=find1(par[x])\n            return par[x]\n        \n        def union1(x,y):\n            xp=find1(x)\n            yp=find1(y)\n            if xp!=yp:\n                par[yp]=xp\n        \n        for x in A:\n            for i in range(2,int(sqrt(x))+1):\n                if x%i==0:\n                    union1(i,x)\n                    union1(x,x//i)\n                    \n        cnt=0\n        cach={}\n        for x in A:\n            xp=find1(x)\n            cnt=max(cnt,1+cach.get(xp,0))\n            cach[xp]=1+cach.get(xp,0)\n        return cnt\n", "\nclass UF:\n    def __init__(self,N):\n        self.parent = [i for i in range(N)]\n        self.size = [1 for i in range(N)]\n    \n    def find(self,x):\n        if self.parent[x] == x:\n            return x\n        self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self,X,Y):\n        root_x = self.find(X)\n        root_y = self.find(Y)\n        if root_x != root_y:\n            \n            if self.size[root_x] >= self.size[root_y]:\n                self.parent[root_y] = root_x\n                self.size[root_x] += self.size[root_y] \n                \n            else:\n                self.parent[root_x] = root_y\n                self.size[root_y] += self.size[root_x]\n                \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        factor_map = {}\n        uf = UF(len(A))\n        for index,num in enumerate(A):\n            for factor in range(2, int(sqrt(num)+ 1)):\n                if num % factor == 0:\n                    \n                    if factor_map.get(factor) is None:\n                        factor_map[factor] = index\n                    else:\n                        uf.union(index,factor_map[factor])\n                        \n                    j = num // factor\n                    if factor_map.get(j) is None:\n                        factor_map[j] = index\n                    else:\n                        uf.union(index,factor_map[j])\n                        \n            \n            if factor_map.get(num) is None:\n                factor_map[num] = index\n            else:\n                uf.union(index,factor_map[num])\n                \n        return max(uf.size)\n            \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        ma = max(A)\n        N = len(A)\n        m = list(range(ma + 1))\n        for a in A:\n            for k in range(2, int(math.sqrt(a)) + 1):\n                if a % k == 0:\n                    self.u(m, a, k)\n                    self.u(m, a, a // k)\n        count = collections.defaultdict(int)\n        for a in A:\n            count[self.f(m, a)] += 1\n        return max(count.values())\n        \n    def f(self, m, a):\n        while m[a] != a:\n            m[a] = m[m[a]]\n            a = m[a]\n        return a\n    \n    def u(self, m, a, b):\n        if m[a] == m[b]: return\n        pa = self.f(m, a)\n        pb = self.f(m, b)\n        m[pa] = pb", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        from math import sqrt\n        from collections import defaultdict\n        initial = set(A)\n        parent = defaultdict(int)\n        \n        for e in A:\n            parent[e] = e\n        \n        def find(c):\n            if c not in parent:\n                parent[c] = c\n                return c\n            while parent[c] != c:\n                parent[c] = parent[parent[c]]\n                c = parent[c]\n            return c\n        \n        def union(c1, c2):\n            p1, p2 = find(c1), find(c2)\n            if p1 == p2:\n                return\n            parent[p1] = p2\n        \n        for e in A:\n            for n in range(2, int(sqrt(e)) + 1):\n                if e % n == 0:\n                    # divisible by n\n                    union(e, e // n)\n                    union(e, n)\n                    \n        #print(parent)\n           \n        counts = defaultdict(int)\n        for k in list(parent.keys()):\n            if k in initial:\n                counts[find(k)] += 1\n        \n        return max(counts.values())\n        \n        \n", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317)\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            t = sqrt(x) + 1\n            for p in small_primes:\n                if p > t:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def find(m, a):\n            while m[a] != a:\n                m[a] = m[m[a]]\n                a = m[a]\n            return a\n        \n        def union(m, a, b):\n            if m[a] == m[b]:\n                return\n            \n            pa = find(m, a)\n            pb = find(m, b)\n            m[pa] = pb\n        \n        \n        Max = max(A)\n        m = [i for i in range(Max + 1)]\n        for num in A:\n            for k in range(2, int(math.sqrt(num)) + 1):\n                if num % k == 0:\n                    union(m, num, k)\n                    union(m, num, num // k)\n                    \n        count = collections.defaultdict(int)\n        for num in A:\n            count[find(m, num)] += 1\n            \n        return max(count.values())\n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # union find\n        '''\n        def gcd(a, b):    \n            if b==0:\n                return a\n            return gcd(b, a%b)\n        '''\n        def find(u):  # pass compresson\n            if p[u]==-1:\n                return u\n            p[u]=find(p[u])\n            return p[u]\n            \n        def union(u, v):\n            u = find(u)\n            v = find(v)\n            \n            if u!=v:\n                if r[u]>r[v]:\n                    p[v] = u\n                elif r[u]<r[v]:\n                    p[u] = v\n                else:\n                    p[v]=u\n                    r[u]+=1\n        '''\n        def sieve(x):\n            \n            num = [True]*(x+1)\n            \n            k = 2\n            while k*k<=x:\n                if num[k]:\n                    i = k*k\n                    while i<=x:\n                        num[i] = False\n                        i += k\n                k+=1        \n                \n            for i in range(2, x+1):\n                if num[i]:\n                    pr.append(i)\n            \n        '''         \n        n = len(A)\n        \n        m = max(A)+1\n        \n        #pr = []\n        #sieve(m-1)\n        #l = len(pr)\n            \n        p = [-1]*m\n        r = [0]*m\n    \n        for i in range(n):\n            # prime factorization\n            factor = 2\n            num = A[i]\n            while num>=factor*factor:  # here\n                if num%factor==0:\n                    num//=factor\n                    union(A[i], factor)\n                else:\n                    factor+=1\n            union(A[i], num)    # here\n    \n            ################\n            #j = 0\n            #while j<l and pr[j]<=A[i]:\n            #    if A[i]%pr[j]==0:\n            #        union(A[i], pr[j])\n            #    j+=1\n            ##################\n            #j = 2\n            #while j*j<=A[i]:\n            #    if A[i]%j==0:\n            #        union(A[i], j)\n            #        union(A[i], A[i]//j)\n            #    j+=1    \n                \n        \n        s = [0]*m    \n        for i in range(n):    \n            s[find(A[i])]+=1\n         \n        return max(s)\n        \n        '''\n        # dfs   TLE\n        \n        def gcd(a, b):    \n            if b==0:\n                return a\n            return gcd(b, a%b)\n        \n        def dfs(u):\n            y = 1\n            for v in adj[u]:\n                if not vis[v]:\n                    vis[v] = True\n                    y += dfs(v)\n            \n            return y\n        \n        \n        n = len(A)\n        \n        adj = [ [] for i in range(n) ]\n        \n        for i in range(n):\n            for j in range(i+1,n):\n                if gcd(A[i], A[j])>1:\n                    adj[i].append(j)\n                    adj[j].append(i)\n        \n        \n        \n        res = 0\n        \n        vis = [False]*n\n        \n        for i in range(n):\n            \n            if not vis[i]:\n                vis[i] = True\n                res = max(res, dfs(i))\n        \n        return res\n    '''\n", "from collections import Counter, defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factorize(x):\n            ret = set()\n            i = 2\n            while i * i <= x:\n                while x % i == 0:\n                    ret.add(i)\n                    x = x // i\n                i += 1\n            \n            if x != 1:\n                ret.add(x)\n            return ret\n        \n        factor_to_num = defaultdict(list)\n        for i, a in enumerate(A):\n            for factor in factorize(a):\n                factor_to_num[factor].append(i)\n        \n        # init\n        par = list(range(len(A)))\n        rank = [0] * len(A)\n        \n        def find(x):\n            if par[x] == x:\n                return x\n            else:\n                ret = find(par[x])\n                par[x] = ret\n                return ret\n        \n        def unite(x, y):\n            x = find(x)\n            y = find(y)\n            if x == y:\n                return\n            \n            if rank[x] < rank[y]:\n                par[x] = y\n            else:\n                par[y] = x\n                if rank[x] == rank[y]:\n                    rank[x] += 1\n        \n        for factor in factor_to_num.keys():\n            nums = factor_to_num[factor]\n            for i in range(1, len(nums)):\n                unite(nums[i-1], nums[i])\n        \n        counter = Counter(find(i) for i in range(len(A)))\n        return max(counter.values())", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n\nclass UnionFind:\n    def __init__(self, A):\n        self.factorparent = []\n        for i in range(A):\n            self.factorparent.append(i)\n    \n    def union(self, x, y):\n        xp = self.find(x)\n        yp = self.find(y)\n        self.factorparent[xp] = yp\n        \n    def find(self, x):\n        if x != self.factorparent[x]:\n            self.factorparent[x] = self.find(self.factorparent[x])\n        return self.factorparent[x]\n        \nclass Solution1:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        length = len(A)\n        obj = UnionFind(length)\n        primes = defaultdict(list)\n        for i, n in enumerate(A):\n            primeset = self.getPrime(n)\n            for p in primeset:\n                primes[p].append(i)\n                \n        for k, v in list(primes.items()):\n            for i in range(len(v)-1):\n                obj.union(v[i], v[i+1])\n        primes = {}\n        maxval = 0\n        for i in range(length):\n            val = obj.find(i)\n            primes[val] = primes.get(val, 0) + 1\n            maxval = max(maxval, primes[val])\n        return maxval\n    \n    def getPrime(self, n):\n        i = 2\n        while i <= int(sqrt(n)):\n            if n % i == 0:\n                return self.getPrime(n // i) | set([i])\n            i += 1\n        return set([n])\n                \n                \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n\n        def edge(x, y):\n            xp = find(x)\n            yp = find(y)\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    edge(i, x)\n                    edge(x, x//i)\n        \n        count = 0\n        cache = {}\n        for x in A:\n            xp = find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count\n\n        \n                    \n                \n            \n            \n            \n            \n        \n                \n", "class DSU:\n    def __init__(self,n):\n        self.p = list(range(n))\n        \n    def find(self,x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self,x,y):\n        x1,y2 = self.find(x), self.find(y)\n        self.p[x1] = y2\n\nclass Solution:\n    def primes(self,n):\n        for i in range(2,int(n**(1/2))+1):\n            if n % i  == 0:\n                return set([i]).union(self.primes(n//i))\n        return set([n])\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        prime = defaultdict(list)\n        for i,n in enumerate(A):\n            primeset = self.primes(n)\n            for p in primeset:\n                prime[p].append(i)\n        N = len(A)\n        dsu = DSU(N)\n        for _,indexes in list(prime.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i],indexes[i+1])\n                \n        return max(Counter([dsu.find(i) for i in range(N)]).values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        p = list(range(max(A) + 1))\n\n        def find(x):\n            if p[x] != x:\n                p[x] = find(p[x])\n            return p[x]\n\n        def union(x, y):\n            p[find(x)] = p[find(y)]      \n\n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]\n\n", "\nclass Primes:\n    def __init__(self):\n        M = ceil(sqrt(100000))+1\n        isPrime = [True] * M\n        k = 2\n        while k < M:\n            n=2\n            while k*n < M:\n                isPrime[k*n] = False               \n                n += 1\n            k += 1\n            while k < M and not isPrime[k]:\n                k += 1\n            \n        self.primes = [k for k in range(2,M) if isPrime[k]]\n        \n\n\nclass Solution:\n    primes = Primes().primes       \n        \n    def largestComponentSize(self, A: List[int]) -> int:        \n             \n        def getPrimeFactors(a):\n            ans = []\n            for p in Solution.primes:\n                if p*p > a: break\n                if a%p==0:\n                    ans.append(p)\n                    while True:\n                        a = a // p\n                        if a%p != 0: break\n            if a > 1:\n                ans.append(a)\n            return ans\n        \n        N = len(A) \n        D = defaultdict(list)\n        for k in range(N):\n            a = A[k]\n            ap = getPrimeFactors(a)\n            for p in ap:\n                D[p].append(k)\n        dsu = DSU(N)\n        for p,indexList in list(D.items()):            \n            n = len(indexList)\n            for i in range(n-1):\n                dsu.union(indexList[i],indexList[i+1])\n        return max(dsu.size)\n    \n    \nclass DSU: # Disjoint Set Union data structure\n    \n    def __init__(self, size):\n        self.size = [1] * (size+1)\n        self.parent = [i for i in range(size+1)]\n        \n        \n    def find(self, i):\n        \n        # Path halving... replaces only every other parent pointer with grandparent\n        while self.parent[i] != i:\n            i = self.parent[i] = self.parent[self.parent[i]]\n        return i\n            \n        \n        # Path splitting way... let to 980ms... replacing every parent with grandparent\n        ##while self.parent[i] != i:\n        ##    i, self.parent[i] = self.parent[i], self.parent[self.parent[i]]\n        ##return i\n        \n        # The simplest recursive way... led to 1012ms\n        ##if i != self.parent[i]:\n        ##    self.parent[i] = self.find(self.parent[i])\n        ##return self.parent[i]\n    \n    def union(self, i,j):\n        i = self.find(i)\n        j = self.find(j)\n        \n        if i == j: return\n        \n        if self.size[i] > self.size[j]:\n            i,j = j,i\n            \n        self.parent[i] = j\n        self.size[j] += self.size[i]\n        \n        \n        return j\n\n\n        \n", "from math import sqrt\nfrom collections import Counter\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [i for i in range(len(A))]\n        size = [1 for i in range(len(A))]\n        primes = {}\n        \n        def find_parent(node):\n            if node == parent[node]:\n                return node\n            parent[node] = find_parent(parent[node])\n            return parent[node]\n        \n        def union(a, b):\n            par_a = find_parent(a)\n            par_b = find_parent(b)\n            parent[par_a] = par_b\n            \n        def primes_set(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return primes_set(n//i) | set([i])\n            return set([n])\n            \n        for i, num in enumerate(A):\n            pr_set = primes_set(num)\n            for q in pr_set: \n                primes[q] = primes.get(q, []) + [i]\n                        \n        for i, nodes in list(primes.items()):\n            nodes = list(set(nodes))\n            for j in range(len(nodes)-1):\n                union(nodes[j], nodes[j+1])\n\n        return max(Counter([find_parent(i) for i in range(len(A))]).values())\n            \n            \n            \n        \n        \n            \n        \n", "class Solution:\n    def largestComponentSize(self, nums: List[int]) -> int:\n        uf = {}\n        def find(x):\n            if uf[x] != x:\n                uf[x] = find(uf[x])\n            return uf[x]\n    \n        def union(x, y):\n            uf.setdefault(x, x)\n            uf.setdefault(y, y)            \n            uf[find(x)] = uf[find(y)]\n        \n        for num in nums:\n            union(num, num)            \n            for i in range(2, int(math.sqrt(num)) + 1):\n                if num % i == 0:\n                    union(num, i)\n                    union(num//i, i)\n        \n        group_counter = collections.Counter()\n        for num in nums:\n            group_counter[find(num)] += 1\n        \n        return max(group_counter.values())\n", "class UnionFind:\n    def __init__(self, nums):\n        self.nums = nums\n        self.groups = list(range(len(nums)))\n        self.sizes = [1] * len(nums)\n    \n    def union(self, a, b):\n        a, b = self.find(a), self.find(b)\n        if a == b:\n            return\n        \n        if self.sizes[a] < self.sizes[b]:\n            a, b = b, a\n\n        self.sizes[a] += self.sizes[b]\n        self.groups[b] = self.groups[a]\n\n    def find(self, a):\n        head = self.groups[a]\n        while head != self.groups[head]:\n            head = self.groups[head]\n\n        node = self.groups[a]\n        while node != self.groups[node]:\n            node, self.groups[node] = self.groups[node], head\n\n        return head\n\n    def largest(self):\n        return max(self.sizes)\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        def factors(n):\n            ans = {n}\n            for i in range(2, int(math.sqrt(n)) + 1):\n                if n % i == 0:\n                    ans.add(i)\n                    ans.add(n // i)\n            return ans\n        \n        uf = UnionFind(a)\n        primes = defaultdict(list)\n        for i, num in enumerate(a):\n            pr_set = factors(num)\n            for prime in pr_set:\n                primes[prime].append(i)\n        \n        for prime, idxs in primes.items():\n            for i in range(len(idxs) - 1):\n                uf.union(idxs[i],idxs[i + 1])\n        return uf.largest()", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        graph = defaultdict(list)\n        uf = UnionFind(len(A))\n        \n        for i, num in enumerate(A):\n            prime_factors = set(self.get_prime_factors(num))\n            for factor in prime_factors:\n                graph[factor].append(i)\n        \n        for factor in graph:\n            indices = graph[factor]\n            for i in range(len(indices)-1):\n                uf.union(indices[i], indices[i+1])\n        \n        counter = Counter()\n        for i in range(len(A)):\n            root = uf.find(i)\n            counter[root] += 1\n        \n        return max(counter.values())\n        \n    def get_prime_factors(self, num):\n        res = []\n        factor = 2\n        while num >= factor*factor:\n            if num % factor == 0:\n                res.append(factor)\n                num = num // factor\n            else:\n                factor += 1\n        res.append(num)\n        return res\n\nclass UnionFind:\n    def __init__(self, n):\n        self.parent = list(range(n))\n    \n    def union(self, x, y):\n        rootx = self.find(x)\n        rooty = self.find(y)\n        if rootx == rooty:\n            return False\n        self.parent[rooty] = rootx\n        return True\n    \n    def find(self, x):\n        while x != self.parent[x]:\n            self.parent[x] = self.parent[self.parent[x]]\n            x = self.parent[x]\n        return x\n        \n            \n", "from math import sqrt\nfrom collections import Counter\n\nclass DisjointSet:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n    \n    def find(self, x):\n        # Does path compression as well\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n            \n        return self.parent[x]\n    \n    def union(self, x, y):\n        root1 = self.find(x)\n        root2 = self.find(y)\n        \n        self.parent[root2] = root1\n        \n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        \n        ds = DisjointSet(n)\n    \n        def prime_set(n):\n            for i in range(2, int(sqrt(n)) + 1):\n                if n % i == 0:\n                    return prime_set(n // i) | set([i])\n            \n            return set([n])\n        \n        primes = {}\n        for i in range(n):\n            for prime in prime_set(A[i]):\n                primes[prime] = primes.get(prime, []) + [i]\n            \n        for _, indices in list(primes.items()):\n            for i in range(len(indices) - 1):\n                ds.union(indices[i], indices[i + 1])\n            \n        print((ds.parent))\n        print(primes)\n        \n        return max(Counter([ds.find(i) for i in range(n)]).values())\n", "# Largest Component Size by Common Factor\n# https://www.youtube.com/watch?v=6Ud_4A9qTp4\n\nfrom math import sqrt\nfrom collections import Counter\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        \n        def ufind(a):\n            if a not in parent:\n                parent[a] = a\n            if a != parent[a]:\n                parent[a] = ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a,b):\n            ua = ufind(a)\n            ub = ufind(b)\n\n            parent[ua] = ub\n        \n        count = Counter()\n        for x in A:\n            y = 2\n            factors = []\n            # # 1\n            # find common & primes of X\n            while x >= y * y:\n                if x % y == 0:\n                    factors.append(y)\n                    # delete y common\n                    while x % y == 0:\n                        x //= y\n                y += 1\n            if x > 1: # find new primes\n                factors.append(x)\n\n            # # 2\n            # zip(factors, factors[1:]) -> [a,b,c] => ab , bc ~~\n            # Linking parent (if link => small -> large)\n            for a, b in zip(factors, factors[1:]):\n                uunion(a, b)\n\n            # # 3\n            # prime > 0 \n            # minimum factors += 1\n            if len(factors)>0:\n                count[factors[0]] += 1\n        \n        final_count = Counter()\n\n        for key in count.keys():\n            final_count[ufind(key)] += count[key]\n\n        best = 0\n        for key in final_count.keys():\n            best = max(best, final_count[key])\n\n        return best", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent={}\n        def ufind(a):\n            if a not in parent:\n                parent[a]=a\n            if a!= parent[a]:\n                parent[a]=ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a,b):\n            ua=ufind(a)\n            ub=ufind(b)\n            \n            parent[ua]=ub\n        \n        count = collections.Counter()\n        for x in A:\n            factors=[]\n            y=2\n            while x>=y*y:\n                if x%y==0:\n                    factors.append(y)\n                    while x%y==0:\n                        x//=y\n                y+=1\n            if x>1:\n                factors.append(x)\n                \n            for a,b in zip(factors,factors[1:]):\n                uunion(a,b)\n            \n            if len(factors)>0:\n                count[factors[0]]+=1\n        \n        final_count = collections.Counter()\n        for key in count.keys():\n            final_count[ufind(key)]+=count[key]\n        \n        best=0\n        for key in final_count.keys():\n            best=max(best,final_count[key])\n        \n        return best", "\nclass Primes:\n    def __init__(self):\n        M = ceil(sqrt(100000))+1\n        isPrime = [True] * M\n        k = 2\n        while k < M:\n            n=2\n            while k*n < M:\n                isPrime[k*n] = False               \n                n += 1\n            k += 1\n            while k < M and not isPrime[k]:\n                k += 1\n            \n        self.primes = [k for k in range(2,M) if isPrime[k]]\n        \n\n\nclass Solution:\n    primes = Primes().primes       \n        \n    def largestComponentSize(self, A: List[int]) -> int:        \n             \n        def getPrimeFactors(a):\n            ans = []\n            for p in Solution.primes:\n                if p*p > a: break\n                if a%p==0:\n                    ans.append(p)\n                    while True:\n                        a = a // p\n                        if a%p != 0: break\n            if a > 1:\n                ans.append(a)\n            return ans\n        \n        N = len(A) \n        D = defaultdict(list)\n        for k in range(N):\n            a = A[k]\n            ap = getPrimeFactors(a)\n            for p in ap:\n                D[p].append(k)\n        dsu = DSU(N)\n        for p,indexList in list(D.items()):            \n            n = len(indexList)\n            for i in range(n-1):\n                dsu.union(indexList[i],indexList[i+1])\n        return max(dsu.size)\n    \n    \nclass DSU: # Disjoint Set Union data structure\n    \n    def __init__(self, size):\n        self.size = [1] * (size+1)\n        self.parent = [i for i in range(size+1)]\n        \n        \n    def find(self, i):\n        \n        while self.parent[i] != i:\n            i, self.parent[i] = self.parent[i], self.parent[self.parent[i]]\n        return i\n        \n        # The simplest recursive way... above just testing the Path splitting technique\n        #if i != self.parent[i]:\n        #    self.parent[i] = self.find(self.parent[i])\n        #return self.parent[i]\n    \n    def union(self, i,j):\n        i = self.find(i)\n        j = self.find(j)\n        \n        if i == j: return\n        \n        if self.size[i] > self.size[j]:\n            i,j = j,i\n            \n        self.parent[i] = j\n        self.size[j] += self.size[i]\n        \n        \n        return j\n\n\n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A = sorted(A)\n        \n        def factors(a):\n            fact = set()\n            for i in range(2, math.isqrt(a)+1):\n                if a%i ==0:\n                    fact.add(i)\n                    fact.add(a//i)\n            fact.add(a)\n            return fact\n\n        \n        parent = [i for i in range(len(A))]\n        nodes = [1] * len(A)\n        rank = [1] * len(A)\n        \n        def find(a):\n            if parent[a] == a:\n                return a\n            parent[a] = find(parent[a])\n            return parent[a]\n        \n        def union(a,b):\n            pa, pb = find(a), find(b)\n            if rank[pa] >pb:\n                parent[pb] = pa\n                nodes[pa] += nodes[pb]\n            elif rank[pa] >pb:\n                parent[pa] = pb\n                nodes[pb] += nodes[pa]\n            else:\n                parent[pb] = pa\n                nodes[pa] += nodes[pb]\n                rank[pa] +=1\n        \n        m = {}\n        \n        for i in range(len(A)):\n            facts = factors(A[i])\n            for f in facts:\n                if f in m and find(i)  != find(m[f]):\n                    union(i, m[f])\n                else:\n                    m[f] = i\n            \n                    \n            \n                    \n        return max(nodes)\n                    \n                \n                \n", "from collections import defaultdict, Counter\n\nclass DSU:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.rnk = [0] * N\n        self.siz = [1] * N\n\n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n\n    def union(self, x, y):\n        xr, yr = list(map(self.find, (x, y)))\n        if xr == yr: return\n        if self.rnk[xr] < self.rnk[yr]:\n            xr, yr = yr, xr\n        if self.rnk[xr] == self.rnk[yr]:\n            self.rnk[xr] += 1\n\n        self.par[yr] = xr \n        self.siz[xr] += self.siz[yr]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # Union-Find on Prime Factors\n        # Time  complexity: O(N x (logM x logM + sqrt(M)))\n        # Space complexity: O(M + N)\n        # def primeDecompose(num):\n        #     factor = 2\n        #     prime_factors = []\n        #     while num >= factor * factor:\n        #         if num % factor == 0:\n        #             prime_factors.append(factor)\n        #             num //= factor\n        #         else:\n        #             factor += 1\n        #     prime_factors.append(num)\n        #     return prime_factors\n\n        # dsu = DSU(max(A) + 1)\n        # num_factor_map = {}\n\n        # for num in A:\n        #     prime_factors = list(set(primeDecompose(num)))\n        #     # map a number to its first prime factor\n        #     num_factor_map[num] = prime_factors[0]\n        #     # merge all groups that contain the prime factors.\n        #     for i in range(0, len(prime_factors) - 1):\n        #         dsu.union(prime_factors[i], prime_factors[i + 1])\n\n        # max_size = 0\n        # group_count = defaultdict(int)\n        # for num in A:\n        #     group_id = dsu.find(num_factor_map[num])\n        #     group_count[group_id] += 1\n        #     max_size = max(max_size, group_count[group_id])\n\n        # return max_size\n\n\n        B = []\n        for x in A:\n            facs = []\n            d = 2\n            while d * d <= x:\n                if x % d == 0:\n                    while x % d == 0:\n                        x //= d\n                    facs.append(d)\n                d += 1\n            if x > 1 or not facs:\n                facs.append(x)\n            B.append(facs)\n\n        primes = list({p for facs in B for p in facs})\n        prime_to_index = {p: i for i, p in enumerate(primes)}\n\n        dsu = DSU(len(primes))\n        for facs in B:\n            for x in facs:\n                dsu.union(prime_to_index[facs[0]], prime_to_index[x])\n\n        count = Counter(dsu.find(prime_to_index[facs[0]]) for facs in B)\n        return max(count.values())\n        \n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A))\n        for num in A:\n            for factor in range(2, int(sqrt(num)) + 1):\n                if num % factor == 0:\n                    uf.union(num, factor)\n                    uf.union(num, num // factor)\n        res = 0\n        group_count = collections.defaultdict(int)\n        for num in A:\n            group_id = uf.find(num)\n            group_count[group_id] += 1\n            res = max(res, group_count[group_id])\n        return res\n\nclass UnionFind:\n    def __init__(self, size):\n        self.parent = [i for i in range(0, size + 1)]\n        self.size = [1] * (size + 1)\n    \n    def find(self, x):\n        while self.parent[x] != x:\n            self.parent[x] = self.parent[self.parent[x]]\n            x = self.parent[x]\n        return x\n\n    def union(self, x, y):\n        parent_x = self.find(x)\n        parent_y = self.find(y)\n        if parent_x == parent_y:\n            return parent_x\n        if self.size[parent_x] > self.size[parent_y]:\n            parent_x, parent_y = parent_y, parent_x\n        self.parent[parent_x] = parent_y\n        self.size[parent_y] += self.size[parent_x]\n        return parent_y\n", "# Build the graph by checking if every pair of nodes has a common factor greater than one, and if\n# it does, connect them together (Create an edge between them). The only issue with this is that it\n# runs in N^2 time.\n#\n# Then, we use dfs to find the largest connected component?\n#\n# Using dfs to find the largest connected component is okay, as it runs in N time, the problem is\n# finding every edge for every pair of numbers in A takes too long (N^2 time).\n#\n# We can't use dfs as there are too many pairs to make. What needs to be done instead is to use\n# union find to group nodes by factors.\n\nclass DSU:\n    \n    def __init__(self):\n        self.parent = defaultdict(lambda: -1)\n        \n    def union(self, x: int, y: int):\n        xSet = self.find(x)\n        ySet = self.find(y)\n        self.parent[xSet] = ySet\n        \n    def find(self, x: int):\n        if x not in self.parent:\n            self.parent[x] = x\n        if x != self.parent[x]:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n        \n        \nclass Solution:\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        counts = Counter()\n        dsu = DSU()\n        for node in A:\n            k = 2\n            factors = []\n            while k * k <= node:\n                if node % k == 0:\n                    factors.append(k)\n                    while node % k == 0:\n                        node //= k\n                        \n                k += 1\n            \n            if node > 1:\n                factors.append(node)\n            \n            for x, y in zip(factors, factors[1:]):\n                dsu.union(x, y)\n            \n            if factors:\n                counts[factors[0]] += 1\n                \n        finalCounts = Counter()\n            \n        for key in counts.keys():\n            finalCounts[dsu.find(key)] += counts[key]\n\n        return max(finalCounts.values())", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n    \n# class Solution:\n#     def largestComponentSize(self, A: List[int]) -> int:\n#         # go through A, \n#         # try each element from each group\n#         ## if divides on element - accumulate groups, combine groups, add to group\n#         ## else create new group\n#         groups = []\n#         for n in A:\n#             indexesOfGroups = []\n#             added = False\n#             for i, g in enumerate(groups):\n#                 for e in g:\n#                     g = gcd(n, e)\n#                     if g > 1:\n#                         indexesOfGroups.append(i)\n#                         added = True\n#                         break\n#             if not added:\n#                 groups.append([n])        \n#                 continue\n#             if indexesOfGroups:\n#                 mainGrIdx = indexesOfGroups[0]\n#                 mainGr = groups[mainGrIdx]\n#                 for i in range(len(indexesOfGroups)-1, 0, -1):\n#                     idx = indexesOfGroups[i]\n#                     mainGr.extend(groups[idx])\n#                     del groups[idx]\n#                 mainGr.append(n)    \n#         # print(groups)    \n\n#         mx = 0\n#         for g in groups:\n#             mx = max(mx, len(g))\n#         return mx\n", "from collections import defaultdict\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        us = UnionSet(max(A))\n        num_fac_map = dict()\n        \n        for num in A:\n            primes = list(self.getPrimes(num))\n            \n            num_fac_map[num] = primes[0]\n            \n            # union all factors of a number\n            # eventually we know a number is linked to which factor that's linked most\n            for i in range(len(primes) - 1):\n                us.union(primes[i], primes[i + 1])\n        \n        _max = 0\n        most_linked_fac_map = defaultdict(int)\n        \n        for num in A:\n            fac = us.find(num_fac_map[num])\n            most_linked_fac_map[fac] += 1\n            _max = max(_max, most_linked_fac_map[fac])\n        \n        return _max\n        \n        \n    def getPrimes(self, num):\n        primes = set()\n        factor = 2\n        while num >= factor * factor:\n            if num % factor == 0:\n                primes.add(factor)\n                num //= factor\n            else:\n                factor += 1\n        primes.add(num)\n        return primes\n        \n        \nclass UnionSet:\n    \n    def __init__(self, size):\n        self.factors = [i for i in range(size + 1)]\n        self.size = [1] * (size + 1)    # the number of factors that this factor can union to\n    \n    def find(self, ix):\n        while self.factors[ix] != ix:\n            ix = self.factors[ix]\n        return ix\n    \n    def union(self, ix1, ix2):\n        p1, p2 = self.find(ix1), self.find(ix2)\n        if p1 == p2:\n            return\n        \n        # make p1 small set, p2 large set\n        if self.size[p1] > self.size[p2]:\n            p1, p2 = p2, p1\n        \n        # make small set's parent to be the larger set\n        self.factors[p1] = p2\n        self.size[p2] += self.size[p1]", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2,int(max(A)**0.5)+1):\n            for y in primes:\n                if x%y == 0:\n                    break\n            else:\n                primes.append(x)\n        \n        factors = collections.defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x%p == 0:\n                    factors[a].append(p)\n                    while x%p == 0:\n                        x //= p\n            if x > 1:\n                factors[a].append(x)\n                primes.append(x)\n                \n        n = len(primes)\n        parent = [i for i in range(n)]\n        PrimeToIndex = {p:i for i,p in enumerate(primes)}\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi,pj = find(i),find(j)\n            if pi != pj:\n                parent[pi] = pj\n                \n                \n                \n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    union(PrimeToIndex[p],PrimeToIndex[p0])\n        \n        count = collections.Counter(find(PrimeToIndex[factors[a][0]]) for a in A if factors[a])\n        return max(count.values())\n        \n        \n", "class DisjointSetUnion(object):\n    \n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)]\n        self.size = [1] * (size + 1)\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        \n        return self.parent[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px == py:\n            return px\n        \n        # connect the two sets (components)\n        if self.size[px] > self.size[py]:\n            # add the node to the union with less members\n            # keeping px as the index of the smaller component\n            px, py = py, px\n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        return py\n            \n            \nclass Solution:\n    \n    def primeDecompose(self, num):\n        factor = 2\n        prime_factors = []\n        while num >= factor * factor:\n            if num % factor == 0:\n                prime_factors.append(factor)\n                num = num // factor\n            else:\n                factor += 1\n        \n        prime_factors.append(num)\n        return prime_factors\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DisjointSetUnion(max(A))\n        num_factor_map = {}\n        \n        for num in A:\n            prime_factors = list(set(self.primeDecompose(num)))\n            num_factor_map[num] = prime_factors[0]\n            for i in range(0, len(prime_factors) - 1):\n                dsu.union(prime_factors[i], prime_factors[i+1])\n        max_size = 0\n        group_count = defaultdict(int)\n        for num in A:\n            group_id = dsu.find(num_factor_map[num])\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id])\n        \n        return max_size\n\n", "import collections\n\n\nclass UnionFind:\n    def __init__(self, n):\n        self.n = n\n        self.parents = list(range(n))\n        self.ranks = [0 for _ in range(n)]\n\n    def get_root(self, x):\n        if self.parents[x] == x:\n            return x\n        self.parents[x] = self.get_root(self.parents[x])\n        return self.parents[x]\n\n    def merge(self, x, y):\n        x = self.get_root(x)\n        y = self.get_root(y)\n        if x != y:\n            if self.ranks[x] < self.ranks[y]:\n                self.parents[x] = y\n            else:\n                self.parents[y] = x\n                if self.ranks[x] == self.ranks[y]:\n                    self.ranks[x] += 1\n\n\ndef factorize_all(n):\n    factorizations = [None] * (n + 1)\n    factorizations[0] = {}\n    factorizations[1] = {}\n    for p in range(2, n + 1):\n        if factorizations[p] is None:\n            for k in range(1, n // p + 1):\n                if factorizations[k] is None:\n                    continue\n                fs = factorizations[k].copy()\n                if p in fs:\n                    fs[p] += 1\n                else:\n                    fs[p] = 1\n                factorizations[k * p] = fs\n    return factorizations\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A) + 1)\n        factorization = factorize_all(max(A))\n        ids = dict()\n        for a in A:\n            if a < 2:\n                continue\n            factors = list(factorization[a].keys())\n            ids[a] = factors[0]\n            for p0, p1 in zip(factors, factors[1:]):\n                uf.merge(p0, p1)\n                \n        counter = collections.defaultdict(int)\n        maxval = 0\n        for a in A:\n            if a < 2:\n                continue\n            id_ = uf.get_root(ids[a])\n            counter[id_] += 1\n            maxval = max(maxval, counter[id_])\n            \n        return maxval", "# https://www.tutorialspoint.com/largest-component-size-by-common-factor-in-cplusplus\n\nfrom collections import defaultdict as dd\n\ndef find(parent,num) :\n\n    if parent[num]==-1 :\n        return num\n    else :\n        parent[num] = find(parent,parent[num])\n    \n    return parent[num]\n\ndef union(parent,u,v) :\n    par_u = find(parent,u)\n    par_v = find(parent,v)\n    if par_u != par_v :\n        parent[par_v] = par_u\n        \nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        ans=0\n        n=len(a)\n        parent=[-1]*100001\n        \n        for i in range(n) :\n            x=a[i]\n            \n            for j in range(2, int(x**0.5)+1) :\n                \n                if x%j == 0 :\n                    \n                    union(parent,j,x)\n                    union(parent,x//j,x)\n                               \n        count = dd(int)    \n        for i in range(len(a)) :\n            par = find(parent,a[i])\n            count[par]+=1\n            ans=max(ans,count[par])\n\n        return ans\n                    \n# from collections import defaultdict as dd\n\n# def find(parent,num) :\n\n#     if parent[num]==-1 :\n#         return num\n#     else :\n#         parent[num] = find(parent,parent[num])\n    \n#     return parent[num]\n\n# def union(parent,rank,u,v) :\n#     par_u = find(parent,u)\n#     par_v = find(parent,v)\n    \n#     if par_u == par_v :\n#         return \n    \n#     if rank[par_u] >= rank[par_v] :\n#         parent[par_v] = par_u\n#         rank[par_u] += rank[par_v]\n\n#     else :\n#         parent[par_u] = par_v\n#         rank[par_v] += rank[par_u]\n        \n\n# class Solution:\n#     def largestComponentSize(self, a: List[int]) -> int:\n#         ans=0\n#         n=len(a)\n#         parent=[-1]*n\n#         rank=[1]*n\n        \n#         factor = dd(int)\n        \n#         for i in range(n) :\n#             x=a[i]\n            \n#             for j in range(2, int(x**0.5)+1) :\n                \n#                 if x%j == 0 :\n#                     if factor[j] :\n#                         union(parent,rank,factor[j],i)\n                        \n#                     else :\n#                         factor[j]=i\n                        \n#                     if factor[x//j] :\n#                         union(parent,rank,factor[x//j],i)\n\n#                     else :\n#                         factor[x//j]=i\n                            \n#             if factor[x] :\n#                 union(parent,rank,factor[x],i)\n#             else :\n#                 factor[x]=i\n                \n#             ans = max(ans,rank[find(parent,i)])\n            \n#         return ans\n", "from math import sqrt\n\nclass DSU:\n    def __init__(self, n):\n        self.parent = [i for i in range(n)]\n        self.rank = [1] * n\n        \n    def find(self, x):\n        if self.parent[x] == x:\n            return x\n        \n        self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        if self.find(x) == self.find(y): return\n        \n        xrank = self.rank[x]\n        yrank = self.rank[y]\n        \n        if xrank < yrank:\n            self.parent[self.find(x)] = self.find(y)\n            self.rank[x] = self.rank[y] + 1\n        else: \n            self.parent[self.find(y)] = self.find(x)\n            self.rank[y] = self.rank[x] + 1\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        \n        uf = DSU(n)\n        \n        def fac(x):\n            yield x\n            for i in range(2, int(sqrt(x))+1): \n                if x % i == 0: \n                    yield i\n                    yield x // i\n                                \n        graph = {}\n        \n        for idx, x in enumerate(A):   \n            for e in fac(x):\n                if e in graph: uf.union(idx, graph[e])\n                graph[e] = idx\n        \n        ctr = collections.Counter()\n        for i in range(n):\n            ctr[uf.find(i)] += 1\n        \n        return ctr.most_common()[0][1]\n", "from collections import Counter\nclass UnionFind:\n    \n    def __init__(self, size):\n        self.parents = [i for i in range(size)]\n        self.ranks = [0]*size\n        \n    def find(self, x):\n        if x != self.parents[x]:\n             self.parents[x] = self.find(self.parents[x])\n        return self.parents[x]\n    \n    def union(self, x, y):\n        xp, yp = self.find(x), self.find(y)\n        if xp == yp:\n            return\n        if self.ranks[xp] < self.ranks[yp]: \n            self.parents[xp] = yp\n        elif self.ranks[xp] > self.ranks[yp]: \n            self.parents[yp] = xp\n        else:\n            self.parents[xp] = yp\n            self.ranks[yp] += 1\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        if not A:\n            return 0\n        \n        n = max(A)\n        dsu = UnionFind(n+1)\n        \n        for a in A:\n            for k in range(2, int(a**0.5)+1):\n                if a%k==0:\n                    dsu.union(a, k)\n                    dsu.union(a, a//k)\n        \n        return max(Counter([dsu.find(a) for a in A]).values())\n", "# Start: 2020-08-30 10:49PM => \n\nclass Solution:\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        # initial: use union find?\n        \n        def get_primes_set(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return get_primes_set(n//i) | set([i])\n            return set([n])\n        \n        A = set(A)\n        primes = set()\n        \n        children_of = collections.defaultdict(set)\n        for a in A:\n            ap = get_primes_set(a)\n            prev = None\n            for pr in ap:\n                primes.add(pr)\n                children_of[pr].add(a)\n                if prev is not None:\n                    children_of[pr].add(prev)\n                    children_of[prev].add(pr)\n                prev = pr\n                \n        print(children_of)\n        \n        seen = set()\n        sizes = dict()\n        # print(primes)\n        for pr in primes:\n            if pr in seen:\n                continue\n            sizes[pr] = 0\n            to_explore = collections.deque([pr])\n            # print(pr)\n            while to_explore:\n                # print(to_explore)\n                curr = to_explore.popleft()\n                if curr in seen:\n                    continue\n                seen.add(curr)\n                sizes[pr] += curr in A\n                for child in children_of[curr]:\n                    to_explore.append(child)\n        \n        return max(sizes.values())\n            \n", "class UnionFind:\n    def __init__(self, n): \n        self.ranks = [0]*n\n        self.parents = [i for i in range(n)]\n        \n        \n    def union(self, i, j): \n        pi = self.parent(i)\n        pj = self.parent(j)\n        if pi == pj: \n            return \n        else: \n            if self.ranks[pi] <= self.ranks[pj]: \n                self.parents[pi] = pj \n                self.ranks[pj] += 1 if self.ranks[pi] == self.ranks[pj] else 0 \n            else: \n                self.parents[pj] = pi\n                \n    def parent(self, i): \n        if self.parents[i] != i: \n            self.parents[i] = self.parent(self.parents[i])\n        return self.parents[i]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A)+1)\n        dic = {}\n        for i, num in enumerate(A): \n            factor = self.decomp(num)\n            dic[num] = factor[0]\n            # print(num, factor)\n            for i in range(0, len(factor)-1): \n                uf.union(factor[i], factor[i+1])\n        \n        count = collections.Counter()\n        for num in A: \n            group_id = uf.parent(dic[num])\n            count[group_id] += 1\n        return max(count[i] for i in count)\n        \n    def decomp(self, num): \n        factor = 2\n        ans = set()\n        # print(\\\"num\\\", num)\n        while num>=factor*factor: \n            if num%factor==0: \n                num //= factor \n                ans.add(factor)\n            else: \n                factor += 1\n        ans.add(num)\n        # print(\\\"num end\\\", num)\n        return list(ans)\n", "class Solution:\n    def find(self, parent: List[int], x: int):\n        if not parent[x] == x:\n            parent[x] = self.find(parent, parent[x])\n        return parent[x]\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n, mx, res = 0, max(A), 0\n        valtocnt = collections.Counter()\n        parent = list(range(mx+1))  \n        for num in A:\n            for d in range(int(sqrt(num)), 1, -1):\n                if num % d == 0:\n                    parent[self.find(parent, num)] = parent[self.find(parent, d)]\n                    parent[self.find(parent, num)] = parent[self.find(parent, num//d)]\n        for num in A:\n            valtocnt[self.find(parent, num)] += 1\n            res = max(res, valtocnt[self.find(parent, num)])\n        return res", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "class UnionFind:\n     def __init__(self, n:int)->None:\n        self.parent = [i for i in range(n)]\n        \n     def find(self, x:int)->int:\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n     def union(self, a:int, b:int):\n        self.parent[self.find(b)] = self.find(a)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(100001)\n        for x in A:\n            for i in range(2,int(sqrt(x))+1):\n                if x % i == 0:\n                    uf.union(i,x)\n                    uf.union(x,x//i)\n        count = 0\n        hashMap = {}\n        for x in A:\n            xp = uf.find(x)\n            count = max(count,1 + hashMap.get(xp,0))\n            hashMap[xp] = 1 + hashMap.get(xp,0)\n        return count\n        \n        \n                \n        \n                \n            \n", "class Node:\n    def __init__(self,data):\n        self.data=data\n        self.p=None\n    \nclass Solution:\n    def find(self,node):\n        if(node.p==node):\n            return node\n        node.p=self.find(node.p)\n        return node.p\n    \n    def prime(self,val,d):\n        for i in range(2,int((val)**(0.5))+1):\n            if(val%i==0):\n                if(i not in d):\n                    node=Node(i)\n                    node.p=node\n                    d[i]=node\n                    \n                if(self.find(d[val].p)==d[val]):\n                    d[val].p=d[i]\n                else:\n                    self.find(d[i]).p=self.find(d[val])\n                v=val//i\n                if(v!=i):\n                    if(v not in d):\n                        node=Node(v)\n                        node.p=node\n                        d[v]=node\n                    self.find(d[v]).p=self.find(d[val])\n                    \n    def largestComponentSize(self, A: List[int]) -> int:\n        d={}\n        if(not A):\n            return 0\n        for i in A:\n            if(i not in d):\n                node=Node(i)\n                node.p=node\n                d[i]=node\n            self.prime(i,d)\n        fr=defaultdict(int)\n        \n        for i in A:\n            fr[self.find(d[i]).data]+=1\n        mx=0\n        for i in fr.values():\n            mx=max(i,mx)\n        return mx", "class UnionFind:\n    def __init__(self, N):\n        self.parents = [i for i in range(N)]\n        self.size = [1]*N\n\n    def find(self, x):\n        root = x\n        while root != self.parents[root]:\n            root = self.parents[root]\n\n        while x != root:\n            parent = self.parents[x]\n            self.parents[x] = root\n            x = parent\n\n        return root\n\n    def union(self, a, b):\n        root_a = self.find(a)\n        root_b = self.find(b)\n        if root_a == root_b:\n            return False\n\n        if self.size[root_a] <= self.size[root_b]:\n            self.parents[root_a] = root_b\n            self.size[root_b] += self.size[root_a]\n        else:\n            self.parents[root_b] = root_a\n            self.size[root_a] += self.size[root_b]\n\n        return True\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A)+1)\n    \n        for a in A:\n            for factor in range(2, int(math.sqrt(a)) + 1):\n                if a % factor == 0:\n                    uf.union(a, factor)\n                    uf.union(a, a // factor)\n                \n        group2size = defaultdict(int)\n        for a in A:\n            group2size[uf.find(a)] += 1\n    \n        return max(group2size.values())\n        \n", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        \n        while x != root:\n            temp = self.parent[x]\n            self.parent[x] = root\n            x = temp\n            \n        return root\n    \n    def union(self, x, y):\n        root1 = self.find(x)\n        root2 = self.find(y)\n        \n        if root1 == root2: return False\n        \n        if self.size[root1] > self.size[root2]:\n            self.parent[root2] = root1\n            self.size[root1] += self.size[root2]\n        else:\n            self.parent[root1] = root2\n            self.size[root2] += self.size[root1]\n        \n        return True\n    \n\nclass Solution:\n#     def commonFactor(self, x, y):\n#         if x == y: return True\n#         if y > x: return self.commonFactor(y, x)\n\n#         while y:\n#             x, y = y, x % y\n\n#         return x != 1\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(100001)\n        \n        for x in A:\n            for j in range(2, int(x ** 0.5) + 1):\n                if x % j == 0:\n                    dsu.union(x, j)\n                    dsu.union(x, x // j)\n                    \n        \n        counter = collections.Counter()\n        max_val = 0\n        for x in A:\n            counter[dsu.find(x)] += 1\n        return counter.most_common(1)[0][1]", "class DisjointSetUnion():\n    def __init__(self, size):\n        self.parents = [i for i in range(size + 1)]\n        self.size = [1] * (size + 1)\n\n    def find(self, x):\n        if self.parents[x] != x:\n            self.parents[x] = self.find(self.parents[x])\n        return self.parents[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        # x and y are in the same set\n        if px == py:\n            return px\n        if self.size[px] > self.size[py]:\n            px, py = py, px\n        self.parents[px] = py\n        self.size[py] += self.size[px]\n        return py\n\nimport math\nfrom collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A) -> int:\n        dsu = DisjointSetUnion(max(A))\n        for a in A:\n            for factor in range(2, int(math.sqrt(a)) + 1):\n                if a % factor == 0:\n                    dsu.union(a, factor)\n                    dsu.union(a, a // factor)\n        max_size = 0\n        group_count = defaultdict(int)\n        for a in A:\n            idx = dsu.find(a)\n            group_count[idx] += 1\n            max_size = max(max_size, group_count[idx])\n        return max_size", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            q=2\n            while q*q<=num:\n                if num%q==0:\n                    primes[q].append(i)\n                    while num%q==0:\n                        num=num//q\n                q+=1\n            if num>1:\n                primes[num].append(i) \n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "\nclass UnionFind:\n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)] \n        self.rank = [1] * (size + 1)    \n    \n    def find(self, num):\n        if num != self.parent[num]:\n            self.parent[num] = self.find(self.parent[num])\n        \n        return self.parent[num]\n    \n    def union(self, a, b):\n        pa = self.find(a)\n        pb = self.find(b)\n        \n        if pa == pb:\n            return\n        \n        if self.rank[pa] > self.rank[pb]:\n            self.parent[pb] = pa\n        elif self.rank[pb] > self.rank[pa]:\n            self.parent[pa] = pb\n        else:\n            self.parent[pb] = pa\n            self.rank[pa] += 1\n\n\n\n            \nimport collections               \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A))\n        a_to_factor = {}\n        for a in A:\n            factors = self.find_factors(a)\n            a_to_factor[a] = factors[0]\n            for i in range(0, len(factors) - 1):\n                uf.union(factors[i], factors[i + 1])\n        \n        parent_to_count = collections.defaultdict(int)\n        max_num = 0\n        for a in A:\n            parent = uf.find(a_to_factor[a])\n            parent_to_count[parent] += 1 \n            max_num = max(max_num, parent_to_count[parent])\n        \n        return max_num\n            \n    \n    def find_factors(self, num):\n        if num == 1:\n            return [1]\n        i = 2\n        factors = list()\n        while num >= i * i:\n            if num % i == 0:\n                factors.append(i)\n                num = num//i\n            else:\n                i += 1\n        factors.append(num)\n        return list(set(factors))\n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu=Disj(max(A))\n        for a in A:\n            for factor in range(2,int(sqrt(a))+1):\n                if a%factor==0:\n                    dsu.union(a,factor)\n                    dsu.union(a,a//factor)\n        maxx=0\n        group_count=defaultdict(int)\n        for a in A:\n            group_id=dsu.find(a)\n            #print(group_id)\n            group_count[group_id]+=1\n            maxx=max(maxx,group_count[group_id])\n        return maxx\n        \nclass Disj(object):\n    def __init__(self,size):\n        self.parent=[i for i in range(size+1)]\n        self.size=[1]*(size+1)\n    \n    def find(self,x):\n        if self.parent[x]!=x:\n            self.parent[x]=self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self,x,y):\n        px,py=self.find(x),self.find(y)\n        if px==py:\n            return px\n        if self.size[px]>self.size[py]:\n            px,py=py,px\n        self.parent[px]=py\n        self.size[py]+=self.size[px]\n        return py", "from collections import defaultdict\n\nclass DSU:\n    def __init__(self, N):\n        self.par = list(range(N))\n        self.rnk = [0] * N\n        self.siz = [1] * N\n\n    def find(self, x):\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n\n    def union(self, x, y):\n        xr, yr = list(map(self.find, (x, y)))\n        if xr == yr: return\n        if self.rnk[xr] < self.rnk[yr]:\n            xr, yr = yr, xr\n        if self.rnk[xr] == self.rnk[yr]:\n            self.rnk[xr] += 1\n\n        self.par[yr] = xr \n        self.siz[xr] += self.siz[yr]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # Union-Find on Prime Factors\n        def primeDecompose(num):\n            factor = 2\n            prime_factors = []\n            while num >= factor * factor:\n                if num % factor == 0:\n                    prime_factors.append(factor)\n                    num //= factor\n                else:\n                    factor += 1\n            prime_factors.append(num)\n            return prime_factors\n\n        dsu = DSU(max(A) + 1)\n        num_factor_map = {}\n\n        for num in A:\n            prime_factors = list(set(primeDecompose(num)))\n            # map a number to its first prime factor\n            num_factor_map[num] = prime_factors[0]\n            # merge all groups that contain the prime factors.\n            for i in range(0, len(prime_factors) - 1):\n                dsu.union(prime_factors[i], prime_factors[i + 1])\n\n        max_size = 0\n        group_count = defaultdict(int)\n        for num in A:\n            group_id = dsu.find(num_factor_map[num])\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id])\n\n        return max_size\n\n", "class UnionFind:\n    def __init__(self, length):\n        self.parents = {num: num for num in range(length)}\n        self.ranks = {num: 1 for num in range(length)}\n    \n    def find(self, src):\n        if self.parents[src] == src:\n            return src\n        \n        self.parents[src] = self.find(self.parents[src])\n        return self.parents[src]\n\n    def union(self, src, dest):\n        rootSrc, rootDest = self.find(src), self.find(dest)\n        if rootSrc == rootDest:\n            return -1\n        \n        if self.ranks[rootSrc] > self.ranks[rootDest]:\n            self.parents[rootDest] = rootSrc\n            self.ranks[rootSrc] += self.ranks[rootDest]\n            return self.ranks[rootSrc]\n        else:\n            self.parents[rootSrc] = rootDest\n            self.ranks[rootDest] += self.ranks[rootSrc]\n            return self.ranks[rootDest]\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def genPrimes(num):\n            i = 2\n            while i * i <= num:\n                if num % i == 0:\n                    return set([i]) | genPrimes(num//i)\n                i += 1\n            return set([num])\n\n        uf = UnionFind(len(A))\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            primesNum = genPrimes(num)\n            for prime in primesNum:\n                primes[prime].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes) - 1):\n                uf.union(indexes[i], indexes[i + 1])\n        return max(uf.ranks.values())", "# Reference: https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/819772/TLE-Python-GCD-%2B-Union-Find-%2B-Rank-Compression\n\nfrom typing import List\nfrom math import gcd, sqrt\nfrom collections import defaultdict\n\nclass DSU:\n    def __init__(self, size):\n        self.sizes = [1] * size\n        self.parent = [i for i in range(size)]\n\n    def find(self, u):\n        if self.parent[u] != u:\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\n\n    def union(self, u, v):\n        root_u = self.find(u)\n        root_v = self.find(v)\n        if root_u != root_v:\n            if self.sizes[root_u] < self.sizes[root_v]:\n                self.parent[root_u] = root_v\n                self.sizes[root_v] += self.sizes[root_u]\n            else:\n                self.parent[root_v] = root_u\n                self.sizes[root_u] += self.sizes[root_v]\n\n    def size(self, u):\n        return self.sizes[self.find(u)]\n\nfrom itertools import count\ndef primes():\n    def _not_divisible(n):\n        return lambda x: x % n > 0\n    yield 2\n    odd = count(3, 2)\n    while True:\n        n = next(odd)\n        yield n\n        # sieve of Eratosthenes\n        odd = list(filter(_not_divisible(n), odd))\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # O(n * sqrt(max(A)))\n        dsu = DSU(max(A) + 1)   # 0 is not being used\n\n        for x in A:\n            for factor in range(2, int(sqrt(x)) + 1):\n                if x % factor == 0:\n                    dsu.union(x, factor)\n                    dsu.union(x, x // factor)\n\n        ans, counter = 0, defaultdict(int)\n        for x in A:\n            counter[dsu.find(x)] += 1\n            ans = max(ans, counter[dsu.find(x)])\n        return ans\n\n        # # O(n^2)\n        # dsu = DSU(len(A))\n        # for i in range(len(A)):\n        #     for j in range(len(A)):\n        #         if i != j and gcd(A[i], A[j]) > 1:\n        #             dsu.union(i, j)\n        # return max(dsu.sizes)\n", "from collections import Counter, defaultdict, OrderedDict, deque\nfrom bisect import bisect_left, bisect_right\nfrom functools import reduce, lru_cache\nfrom typing import List\nimport itertools\nimport math\nimport heapq\nimport string\ntrue = True\nfalse = False\nMIN, MAX, MOD = -0x3f3f3f3f, 0x3f3f3f3f, 1000000007\n\n\n#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n# https://leetcode.com/problems/largest-component-size-by-common-factor/description/\n#\n# algorithms\n# Hard (30.37%)\n# Total Accepted:    18.1K\n# Total Submissions: 53.6K\n# Testcase Example:  '[4,6,15,35]'\n#\n# Given a non-empty\u00a0array of unique positive integers A, consider the following\n# graph:\n#\n#\n# There are A.length nodes, labelled A[0] to A[A.length - 1];\n# There is an edge between A[i] and A[j]\u00a0if and only if\u00a0A[i] and A[j] share a\n# common factor greater than 1.\n#\n#\n# Return the size of the largest connected component in the graph.\n#\n#\n#\n#\n#\n#\n#\n# Example 1:\n#\n#\n# Input: [4,6,15,35]\n# Output: 4\n#\n#\n#\n#\n# Example 2:\n#\n#\n# Input: [20,50,9,63]\n# Output: 2\n#\n#\n#\n#\n# Example 3:\n#\n#\n# Input: [2,3,6,7,4,12,21,39]\n# Output: 8\n#\n#\n#\n# Note:\n#\n#\n# 1 <= A.length <= 20000\n# 1 <= A[i] <= 100000\n#\n#\n#\n#\n#\n#\nclass UF:\n    def __init__(self, n):\n        self.p = list(range(n))\n        self.size = [1] * n\n\n    def merge(self, x, y):\n        # Merge by size of set\n        px, py = self.find(x), self.find(y)\n        if px == py: return\n        if self.size[px] < self.size[py]:\n            self.p[px] = py\n            self.size[py] += self.size[px]\n        else:\n            self.p[py] = px\n            self.size[px] += self.size[py]\n\n    def find(self, x):\n        if x != self.p[x]:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UF(max(A) + 1)\n        for n in A:\n            for i in range(2, math.ceil(math.sqrt(n)) + 1):\n                if n % i == 0:\n                    uf.merge(n, i)\n                    uf.merge(n, max(n // i, 2))\n\n        return Counter(list(map(uf.find, A))).most_common()[0][1]\n\n\nsol = Solution()\n\nns = [2, 3, 6, 7, 4, 12, 21, 39]\nns = [1, 2, 3, 4, 5, 6, 7, 8, 9]\nns = [32, 5, 8, 11, 13, 78, 61, 16, 83, 22, 28, 93]\n", "#https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/581394/Python-1032ms-beat-100-time-and-space\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "# Reference: https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/819772/TLE-Python-GCD-%2B-Union-Find-%2B-Rank-Compression\n\nfrom math import gcd, sqrt\nfrom collections import defaultdict\n\nclass DSU:\n    def __init__(self, size):\n        self.sizes = [1] * size\n        self.parent = [i for i in range(size)]\n\n    def find(self, u):\n        if self.parent[u] != u:\n            self.parent[u] = self.find(self.parent[u])\n        return self.parent[u]\n\n    def union(self, u, v):\n        root_u = self.find(u)\n        root_v = self.find(v)\n        if root_u != root_v:\n            if self.sizes[root_u] < self.sizes[root_v]:\n                self.parent[root_u] = root_v\n                self.sizes[root_v] += self.sizes[root_u]\n            else:\n                self.parent[root_v] = root_u\n                self.sizes[root_u] += self.sizes[root_v]\n\n    def size(self, u):\n        return self.sizes[self.find(u)]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # O(n * sqrt(max(A)))\n        dsu = DSU(max(A) + 1)   # 0 is not being used\n        for x in A:\n            for factor in range(2, int(sqrt(x)) + 1):\n                if x % factor == 0:\n                    dsu.union(x, factor)\n                    dsu.union(x, x // factor)\n\n        ans, counter = 0, defaultdict(int)\n        for x in A:\n            counter[dsu.find(x)] += 1\n            ans = max(ans, counter[dsu.find(x)])\n        return ans\n\n\n        # # O(n^2)\n        # dsu = DSU(len(A))\n        # for i in range(len(A)):\n        #     for j in range(len(A)):\n        #         if i != j and gcd(A[i], A[j]) > 1:\n        #             dsu.union(i, j)\n        # return max(dsu.sizes)\n", "import math\n\nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if x != self.p[x]:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        x_root, y_root = self.find(x), self.find(y)\n        self.p[x_root] = y_root\n\nclass Solution:\n    def prime_set(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.prime_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A: List[int]) -> int:               \n        prime_map = {}\n        for i in range(len(A)):\n            P = self.prime_set(A[i])\n            for p in P:\n                if p not in prime_map:\n                    prime_map[p] = []\n                prime_map[p].append(i)\n        \n        DSU_groups = DSU(len(A))\n        for _, group in prime_map.items():\n            for i in range(len(group)-1):\n                DSU_groups.union(group[i], group[i+1])\n        \n        return max(Counter([DSU_groups.find(x) for x in range(len(A))]).values())", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n   \nclass Solution:\n\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n        \n        MAXA = 100001\n        isPrime=[0 for _ in range(MAXA+1)]\n        isPrime[0]=-1;isPrime[1]=-1 #0 and 1 are not prime numbers\n        for i in range(2, MAXA):\n            if isPrime[i]==0: #i is prime\n                for multiple in range(i*i,MAXA+1,i):\n                    if isPrime[multiple]==0:\n                        isPrime[multiple]=i\n                isPrime[i] = i # let i store itself for consistency\n\n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            prime_factors = set()\n            while isPrime[x]!=-1:\n                p = isPrime[x]\n                root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                x //= p\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(max(A))\n        \n        for num in A:\n            for factor in range(2, int(sqrt(num))+1):\n                if num % factor == 0:\n                    dsu.union(num, factor)\n                    dsu.union(num, num // factor)\n        \n        max_size = 0\n        group_count = {}\n        for num in A:\n            group_id = dsu.find(num)\n            if group_id not in group_count:\n                group_count[group_id] = 0\n            group_count[group_id] += 1\n        return max(group_count.values())\n\n    \n    \nclass DSU:\n    def __init__(self, size):\n        self.parent = [i for i in range(size+1)]\n        self.size = [1 for i in range(size+1)]\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px == py:\n            return px\n        \n        if self.size[px] > self.size[py]:\n            px, py = py, px\n        \n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        return py", "class UnionFind:\n    def __init__(self,n):\n        self.parent = [i for i in range(n)]\n        self.size = [1]*n\n    def find(self,A):\n        root=A\n        while root!=self.parent[root]:\n            root=self.parent[root]\n            \n        while A!=root:\n            old_parent=self.parent[A]\n            self.parent[A]=root\n            A=old_parent\n        return(root)\n    \n    def union(self,A,B):\n        root_A = self.find(A)\n        root_B = self.find(B)\n        if root_A==root_B:\n            return(False)\n        \n        if self.size[root_A]<self.size[root_B]:\n            self.parent[root_A]=root_B\n            self.size[root_B]+=self.size[root_A]\n        else:\n            self.parent[root_B]=root_A\n            self.size[root_A]+=self.size[root_B]\n            \n        return(True)\nclass Solution:\n    def gcd(self,a,b): \n    # Everything divides 0  \n        if (b == 0): \n             return a \n        return gcd(b, a%b)\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = UnionFind(max(A)+1) # cause we have max(A) as node\n\n        # attribute each element in A\n        #   to all the groups that lead by its factors.\n        for a in A:\n            for factor in range(2, int(sqrt(a))+1):\n                if a % factor == 0:\n                    dsu.union(a, factor)\n                    dsu.union(a, a // factor)\n\n        # count the size of group one by one\n        group_count = defaultdict(int)\n        for a in A:\n            group_id = dsu.find(a)\n            group_count[group_id] += 1\n            \n        return max(group_count.values())\n", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            t = sqrt(x) + 1\n            for p in small_primes:\n                if p > t:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "from collections import defaultdict\n\nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        d = {}\n        def find(x):\n            if x != d.setdefault(x,x):\n                d[x] = find(d[x])\n            return d[x]\n        def union(x,y):\n            d[find(x)]=find(y)\n\n        for n in a:\n            for i in range(2,int(n**0.5)+1):\n                if n%i: continue\n                union(n,i)  \n                union(n,n//i)\n\n        counter = Counter(find(i) for i in a) \n        return max(counter.values())", "import math\n\nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        while x != self.p[x]:\n            self.p[x] = self.p[self.p[x]]\n            x = self.p[x]   \n        return x\n\n    def union(self, x, y):\n        x_root, y_root = self.find(x), self.find(y)\n        self.p[x_root] = y_root\n\nclass Solution:\n    def prime_set(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.prime_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A: List[int]) -> int:               \n        prime_map = {}\n        for i in range(len(A)):\n            P = self.prime_set(A[i])\n            for p in P:\n                if p not in prime_map:\n                    prime_map[p] = []\n                prime_map[p].append(i)\n        \n        DSU_groups = DSU(len(A))\n        for _, group in prime_map.items():\n            for i in range(len(group)-1):\n                DSU_groups.union(group[i], group[i+1])\n        \n        return max(Counter([DSU_groups.find(x) for x in range(len(A))]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        all_sets = dsu(max(A))\n        \n        for element in A:\n            for factor in range(2, int(sqrt(element))+1):\n                if element % factor == 0:\n                    all_sets.union(element, factor)\n                    all_sets.union(element, element // factor)\n        \n        result = 0\n        count = defaultdict(int)\n        for element in A:\n            parent_id = all_sets.find(element)\n            count[parent_id] += 1\n            result = max(result, count[parent_id])\n        return result\n        \n        \nclass dsu:\n    def __init__(self, size):\n        self.parent = [x for x in range(size + 1)]\n        self.size = [1 for x in range(size + 1)]\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x , y):\n        index_x = self.find(x)\n        index_y = self.find(y)\n        \n        if index_x == index_y:\n            return index_x\n        \n        if self.size[index_x] > self.size[index_y]:\n            index_x, index_y = index_y, index_x\n        self.parent[index_x] = index_y\n        self.size[index_y] += self.size[index_x]\n        return index_y", "import collections\nimport math\nclass DSU:\n    def __init__(self, n):\n        self.par = list(range(n)) \n        #self.size = [1] * n\n        \n    def find(self, x):\n        #print(x)\n        if self.par[x] != x:\n            self.par[x] = self.find(self.par[x])\n        return self.par[x]\n        #return x if self.par[x] == x else self.par[x] = self.find(self.par[x])\n        \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.par[xr] = yr\n        #self.size[yr] += self.size[xr]\n        #self.size[xr] = 0\n        \n\nclass Solution:\n    def sieve(self, n):#best sieve i have ever seen\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.sieve(n//i) | set([i])\n        #print(n) #this is def for 2,3\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        dsu = DSU(n)\n        primes_and_multiples = collections.defaultdict(list)\n        for i,num in enumerate(A):\n            factors = self.sieve(num)\n            for factor in factors:\n                primes_and_multiples[factor].append(i)\n        for primes in list(primes_and_multiples.values()):\n            for i in range(len(primes) - 1): #could have done i-1, i with 1,len(primes)\n                dsu.union(primes[i], primes[i+1])\n        #return max(dsu.size)\n        return max(collections.Counter([dsu.find(i) for i in range(n)]).values())\n                \n        \n                \n                \n        \n        \n", "\nimport math\n\nclass UnionFind:\n    \n    def __init__(self , size):\n        self.id = [i for i in range(size)]\n        \n    def find(self , p):\n        \n        root = p\n        while root != self.id[root]:\n            root = self.id[root]\n        \n        while p != root:\n            nxt = self.id[p]\n            self.id[p] = root\n            p = nxt\n            \n        return root\n    \n    \n    def unify(self , p , q):\n        \n        root1 = self.find(p)\n        root2 = self.find(q)\n        if root1 == root2 : return \n        \n        self.id[root2] = root1\n            \n        \n\n        \n    \n    \n        \n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        max_val = max(A)\n        uf = UnionFind(max_val + 1) # +1 for ease of access\n        for num in A:\n            for i in range(2 , int(math.sqrt(num))+1):\n                if num % i == 0:\n                    uf.unify(num , i)\n                    uf.unify(num , num//i)\n        \n        parent_count = {}\n        cur_max = 1\n        for num in A:\n            parent = uf.find(num)\n            parent_count[parent] = 1 + parent_count.get(parent , 0)\n            cur_max = max(cur_max , parent_count[parent])\n            \n        return cur_max\n    \n            \n    \n", "class UF:\n    def __init__(self, n):\n        self.roots = [i for i in range(n)]\n        self.sz = [1 for _ in range(n)]\n        \n    def find(self, x):\n        while x != self.roots[x]:\n            self.roots[x] = self.roots[self.roots[x]]\n            x = self.roots[x]\n        return x\n    \n    def union(self, x, y):\n        root_x = self.find(x)\n        root_y = self.find(y)\n        \n        if self.sz[root_x] >= self.sz[root_y]:\n            self.roots[root_y] = root_x\n            self.sz[root_x] += self.sz[root_y]\n        else:\n            self.roots[root_x] = root_y\n            self.sz[root_y] += self.sz[root_x]                        \nimport math \nfrom collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factors(num):\n            factor = 2\n            prime_factors = []\n            while num >= factor * factor:\n                if num % factor == 0:\n                    prime_factors.append(factor)\n                    num = num // factor\n                else:\n                    factor += 1\n            prime_factors.append(num)\n            return prime_factors\n            \n        N = len(A)\n        uf = UF(max(A)+1)\n        num_factor_map = defaultdict(int)\n        \n        for num in A:\n            num_factors = factors(num)\n            num_factor_map[num] = num_factors[0]\n            for i in range(len(num_factors)-1):\n                uf.union(num_factors[i], num_factors[i+1])\n                \n        counter = defaultdict(int)\n        for num in A:\n            counter[uf.find(num_factor_map[num])] += 1\n        return max(counter.values())\n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(max(A)) \n\n        for n in A:\n            for j in range(2, floor(sqrt(n))+1):\n                if n % j == 0:\n                    # print(n, j)\n                    dsu.union(n, j)\n                    dsu.union(n, n // j)\n        \n        maxSize = 0\n        groupC = defaultdict(int)\n        \n        for n in A:\n            parent = dsu.find(n)\n            groupC[parent] += 1\n            maxSize = max(maxSize, groupC[parent])\n        \n        \n        return maxSize\n            \n        \nclass DSU:\n    def __init__(self, largest):\n        self.parent = [n for n in range(largest+1)]\n        self.sz = [1] * (largest+1)\n    def find(self, n):\n        if n != self.parent[n]:\n            self.parent[n] = self.find(self.parent[n])\n        return self.parent[n]\n        \n    def union(self, n1, n2):\n        xR, yR = self.find(n1), self.find(n2)\n        \n        if xR == yR:\n            return\n        \n        if self.sz[xR] < self.sz[yR]:\n            xR, yR = yR, xR\n        \n        self.parent[yR] = xR\n        # self.sz[xR] += self.sz[yR]\n        self.sz[yR] += self.sz[xR]\n\n        \n    def size(self, n):\n        return self.sz[n]\n            \n", "from typing import Set\n\nclass myset(object):\n    \n    def __init__(self, maxi):\n        self.s = [i for i in range(0, maxi+1)]\n        self.l = [1]*(maxi+1)\n        \n    def find(self, x):\n        if self.s[x] != x:\n            self.s[x] = self.find(self.s[x])\n            \n        return self.s[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return px\n        \n        if px > py:\n            px, py = py, px\n            \n        self.s[px]  = self.s[py]\n        self.l[py] += self.l[px]\n        \n        return py\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        d:Dict[int][int] = {}\n        p:List[int] = [1, 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\n        \n            \n        def pf(x:int) -> List[int]:\n            result:Set[int] = set()\n            i:int = 0\n            n:int = 2\n            while x >= n*n:\n                if x%n == 0:\n                    result.add(n)\n                    x = x // n\n                else:\n                    n += 1\n            result.add(x)\n            \n            return list(result)\n        \n        if not A: return 0\n        \n        s = myset(max(A))\n            \n        mypf:List[int]\n        for a in A:\n            mypf = pf(a)\n            print(mypf)\n            d[a] = mypf[0]\n            for i in range(len(mypf)-1):\n                s.union(mypf[i], mypf[i+1])\n        \n        count = {}\n        maxi:int = 0\n        for a in A:\n            id:int = s.find(d[a])\n            if id in count:\n                count[id] += 1\n            else:\n                count[id] = 1\n            maxi = max(maxi, count[id])\n            \n        \n        return maxi", "class UnionFind:\n    def __init__(self, count):\n        self._parent = list(range(count))\n        self._size = [1] * count\n    \n    def union(self, a, b):\n        a, b = self.find(a), self.find(b)\n        if a == b:\n            return\n        if self._size[a] < self._size[b]:\n            a, b = b, a\n        self._parent[b] = a\n        self._size[a] += self._size[b]\n    \n    def find(self, x):\n        while self._parent[x] != x:\n            self._parent[x] = self._parent[self._parent[x]]\n            x = self._parent[x]\n        \n        return self._parent[x]\n    \n    def size(self, x):\n        return self._size[self.find(x)]\n            \n\ndef prime_factors(num):\n    if num < 2:\n        return []\n    \n    factors = []\n    \n    for factor in range(2, int(num ** 0.5) + 1):\n        if num % factor == 0:\n            factors.append(factor)\n            while num % factor == 0:\n                num //= factor\n            if num == 1:\n                break\n    \n    if num > 1:\n        factors.append(num)\n    \n    return factors\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        \n        length = len(A)\n        union_find = UnionFind(length)\n        roots = {}\n        \n        for index, num in enumerate(A):\n            for factor in prime_factors(num):\n                if factor not in roots:\n                    roots[factor] = index\n                union_find.union(roots[factor], index)\n        \n        return max(union_find.size(index) for index in range(length))\n", "from collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)\n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if p > x:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())", "import math\nfrom collections import defaultdict\nclass UnionFind:\n    def __init__(self, n):\n        # initially, each node is an independent component\n        self.parent = [i for i in range(n)]\n        # keep the size of each component\n        self.size = [1]*n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    def union(self, x, y):\n        px = self.find(x) \n        py = self.find(y)\n        \n        if px == py:\n            return px\n        #otherwise, connect the two sets\n        if self.size[px] > self.size[py]:\n            px,py = py,px\n        self.parent[px] = py\n        self.size[py] +=self.size[px]\n        return py\n\nclass Solution:\n    def largestComponentSize(self, A: list()) -> int:\n        n = max(A)\n        n_UnionFind = UnionFind(n+1)\n        for a in A:\n            for k in range(2, int(math.sqrt(a))+1):\n                if a%k == 0:\n                    n_UnionFind.union(a,k)\n                    n_UnionFind.union(a,a//k)\n        ans = 1\n        count = defaultdict(int)\n        for a in A:\n            count[n_UnionFind.find(a)] +=1\n            ans = max(ans, count[n_UnionFind.find(a)])\n        return ans", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            t = sqrt(x) + 1\n            for p in small_primes:\n                if p > t:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class Solution:\n    \n    def primeDecompose(self, num):\n        factor = 2\n        prime_factors = []\n        while num >= factor*factor:\n            if not num % factor:\n                prime_factors.append(factor)\n                num //= factor\n            else:\n                factor += 1\n        prime_factors.append(num)\n        return prime_factors\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # 1. Find set of numbers that belongs to each prime factor\n        factors = collections.defaultdict(set)\n        for num in A:\n            prime_factors = self.primeDecompose(num)\n            for p in prime_factors:\n                factors[p] |= set([num])\n        \n        primes = list(factors)\n        \n        group_id = 0\n        group = {}\n        prime_id = {}\n        updated = set(primes)\n        first_round = True\n        \n        for i in range(len(primes)):\n            a = primes[i]\n            \n            if a not in factors:\n                continue\n\n            for b in list(factors):\n                \n                if b == a:\n                    continue\n                    \n                if len(factors[b]) == 1:\n                    del factors[b]\n                elif factors[a] & factors[b]:\n                    factors[a] |= factors[b]\n                    del factors[b]\n\n        return len(factors[max(factors, key = lambda f: len(factors[f]))])", "class Solution:\n    \n    \n            \n    def largestComponentSize(self, A: List[int]) -> int:\n        p = {}\n        def find(i):\n            if i not in p:\n                p[i] = i\n            if p[i] != i:\n                p[i] = find(p[i])\n            return p[i]\n\n        for a in A:\n            p[a] = a\n\n        for a in A:\n            limit = int(math.sqrt(a)) + 1\n            for i in range(2, limit):\n                if a % i == 0:\n                    pa = find(a)\n                    pi = find(i)\n                    if pa in p and pi in p:\n                        p[pa] = p[pi]\n\n                    pa2 = find(a)\n                    pi2 = find(a//i)\n\n                    if pa2 in p and pi2 in p:\n                        p[pa2] = p[pi2]\n\n        c = {}\n        for a in A:\n            c[a] = find(a)\n\n        ans = {}\n        for k, v in list(c.items()):\n            if v not in ans:\n                ans[v] = 0\n            ans[v] += 1\n\n        return max(list(ans.values()))\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # common factor as key, value stored in a set\n        parents = list(range(max(A) + 1))\n        \n        def find(x):\n            # find the parent/root of x \n            # does path compression simultaneously\n            while parents[x] != x:\n                parents[x] = parents[parents[x]]\n                x = parents[x]\n            return x\n        \n        def union(x, y):\n            parents[find(x)] = parents[find(y)]\n        \n        for num in A:\n            for k in range(2, int(sqrt(num)) + 1): \n                if num % k == 0:\n                    union(num, k)\n                    union(num, num//k)\n        counts = {}\n        maxC = 0\n        for num in A:\n            target = find(num)\n            counts[target] = counts.get(target, 0) + 1\n            maxC = max(maxC, counts[target])\n            \n        return maxC\n", "class unionfind:\n    def __init__(self,size):\n        self.parent=[i for i in range(size+1)]\n        self.rank=[0 for _ in range(size+1)]\n    def find(self,x):\n        if(x!=self.parent[x]):\n            self.parent[x]=self.find(self.parent[x])\n        return(self.parent[x])\n    def union(self,x,y):\n        px=self.find(x)\n        py=self.find(y)\n        if(px==py):\n            return(px)\n        if(self.rank[px]>self.rank[py]):\n            self.parent[py]=px\n            return(px)\n        else:\n            self.parent[px]=py\n            if(self.rank[px]==self.rank[py]):\n                self.rank[py]+=1\n            return(py)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n            \n        dsu=unionfind(max(A))\n        for i in A:\n            for factor in range(2,int(sqrt(i))+1):\n                if((i%factor)==0):\n                    dsu.union(i,factor)\n                    dsu.union(i,i//factor)\n                    \n        max_size = 0\n        group_count = defaultdict(int)\n        for a in A:\n            group_id = dsu.find(a)\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id])\n\n        return max_size", "import math\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = max(A)\n        array = [0] * (n+1)\n        for i in range(n+1):\n            array[i] = i\n        \n        def find(x:int) ->int:\n            if x != array[x]:\n                array[x] = find(array[x])\n            return array[x]\n            \n        def union(x:int, y:int):\n            xp = find(x)\n            yp = find(y)\n            if xp != yp:\n                array[yp] = xp\n        \n        length = len(A)\n        for i in range(length):\n            for j in range(2, int(math.sqrt(A[i]))+1):\n                if A[i]%j == 0:\n                    union(j,A[i])\n                    union(A[i],A[i]//j)\n        maximum = 0\n        res = {}\n        for i in range(length):\n            pal = find(A[i])\n            maximum = max(maximum,res.get(pal,0)+1)\n            res[pal] = res.get(pal,0) + 1\n        return maximum\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent = [-1]*100001\n        \n        def find(x , parent) :\n            if parent[x] == -1 :\n                return x\n            \n            parent[x] = find(parent[x] , parent)\n            \n            return parent[x]\n        \n        def union(x , y ) :\n            xp = find(x , parent)\n            yp = find(y , parent)\n            \n            if xp != yp :\n                parent[yp] = xp\n                \n        for i in range(len(A)) :\n            for j in range(2 , int(sqrt(A[i])) + 1) :\n                \n                if A[i] % j == 0 :\n                    union(j , A[i])\n                    union(A[i] , A[i] //j)\n                    \n        count = 0 \n        cache = {}\n        \n        for x in A :\n            p = find(x , parent) \n            count = max(count , 1 + cache.get(p , 0 ))\n            \n            cache[p] = cache.get(p , 0) + 1\n            \n        return count\n", "import math\nimport collections\nclass Solution:\n    def largestComponentSize(self, A) -> int:\n        self.pre = {}\n        for i in A:\n            for d in range(2,int(math.sqrt(i)+1))[::-1]:\n                if i%d == 0:\n                    self.union(self.find(i),self.find(d))\n                    self.union(self.find(i),self.find(i//d))\n        count = collections.defaultdict(int)\n        for i in A:\n            count[self.find(i)] += 1\n        return max(count.values())   \n    def find(self,x):\n        if x not in self.pre:\n            self.pre[x] = x\n        while self.pre[x] != x:\n            self.pre[x] = self.pre[self.pre[x]]\n            x = self.pre[x]\n        return x\n        \n    def union(self,x,y):\n        if self.pre[x] == self.pre[y] :return\n        fx = self.find(x)\n        fy = self.find(y)\n        self.pre[fy] = fx", "class Solution:\n    def largestComponentSize(self, A: List[int], N = 100001) -> int:\n        m = {}\n        P = [i for i in range(N)]   # \\\\U0001f642 parent representative of disjoint sets\n        L = [1] * N                 # \\\\U0001f925 length of parent representative's set\n        def find(x):\n            P[x] = P[x] if x == P[x] else find(P[x])\n            return P[x]\n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            if a == b:\n                return\n            P[b] = a  # arbitrary choice\n            L[a] += L[b]\n        for x in A:\n            m[x] = x if x not in m else m[x]; union(m[x], x)      # case 1: x as a factor of itself\n            for i in range(2, floor(sqrt(x)) + 1):\n                if x % i:\n                    continue\n                j = x // i\n                m[i] = x if i not in m else m[i]; union(m[i], x)  # case 2: i-th factor of x\n                m[j] = x if j not in m else m[j]; union(m[j], x)  # case 3: j-th factor of x\n        return max(L)  # \\\\U0001f3af maximum length of any parent representative's set\n", "class Solution:\n    \n    def get_factors(self, n: int):\n        factors = set()\n        for factor in self.total_factors:\n            if factor > n:\n                break\n            if n % factor == 0:\n                factors.add(factor)\n        for factor in factors:\n            self.total_factors.remove(factor)\n        return factors\n    \n    def get_prime_numbers(self, n_max: int):\n        self.total_factors = [2,3]\n        for val in range(3, n_max//2 + 2, 2):\n            for i in range(3, int(val**0.5) + 2, 2):\n                if val % i == 0:\n                    break\n                else:\n                    if i >= int(val**0.5):\n                        self.total_factors.append(val)\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        #A.sort()\n        #self.get_prime_numbers(A[-1])\n        #print(self.total_factors)\n        N = max(A) + 1\n        nods = {d:d for d in range(N)}\n        \n        def find(x):\n            root = x\n            while nods[root] != root:\n                root = nods[root]\n            while nods[x] != root:\n                parent = nods[x]\n                nods[x] = root\n                x = parent\n            return root\n        \n        def union(x,y):\n            rx,ry = find(x), find(y)\n            if rx != ry:\n                nods[ry] = rx\n        \n        for a in A:\n            for factor in range(2, int(sqrt(a))+1):\n                if a % factor == 0:\n                    union(a, factor)\n                    union(a, a//factor)\n                    \n        counts = collections.defaultdict(int)\n        for a in A:\n            counts[find(a)] += 1\n        print(counts)\n        return max(counts.values())\n            \n                \n    \n    def largestComponentSize_slow(self, A: List[int]) -> int:\n        A.sort()\n        self.get_prime_numbers(A[-1])\n        #print(self.total_factors)\n        max_len = 0\n        while len(A) > max_len:\n            factors = self.get_factors(A[0])\n            new_len = 1\n            A.remove(A[0])\n            while factors:\n                factor = factors.pop()\n                to_remove = []\n                for i in range(len(A)):\n                    if A[i] % factor == 0:\n                        new_len += 1\n                        rest = A[i] / factor\n                        while rest % factor == 0:\n                            rest /= factor\n                        factors = factors | self.get_factors(rest)\n                        to_remove.append(i)\n                A = [A[i] for i in range(len(A)) if i not in to_remove]\n            max_len = max(new_len, max_len)\n        return max_len\n    \n        \n", "from collections import defaultdict, Counter\nfrom functools import lru_cache\n\nMAX_N = 100000\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # compute factors\n        sieve = Sieve(MAX_N)\n        factors = defaultdict(list)\n        for x in A:\n            for factor in sieve.factorize(x):\n                factors[factor].append(x)\n        '''\n        f = Factors()\n        factors = defaultdict(list)\n        for x in A:\n            for factor in f.find_for(x):\n                factors[factor].append(x)\n        '''\n\n        uf = UnionFind()\n        for values in list(factors.values()):\n            for i in range(1, len(values)):\n                uf.connect(values[i-1], values[i])\n                \n        return max(list(Counter(uf.root(x) for x in A).values()), default=0)\n        '''\n        \n        # build bipartite graph from factors and values\n        g = Graph()\n        for factor, values in factors.items():\n            g.add_factor(factor)\n            for value in values:\n                g.add_value(value)\n                g.connect(factor, value)\n        \n        return g.find_largest_connected_size()\n        '''\n\n    \nclass UnionFind:\n    def __init__(self):\n        self.parents = {}\n    \n    def connect(self, a, b):\n        if a not in self.parents:\n            self.parents[a] = a\n        \n        if b not in self.parents:\n            self.parents[b] = b\n            \n        root = self.root(b)\n        self.parents[self.root(a)] = root\n        return root\n    \n    def root(self, a):\n        if a not in self.parents:\n            self.parents[a] = a\n            return a\n\n        if a == self.parents[a]:\n            return a\n        \n        self.parents[a] = self.root(self.parents[a])\n        \n        return self.parents[a]\n\n\nclass Sieve:\n    def __init__(self, max_n):\n        self.primes = self._compute_primes(max_n)\n        # better runtime than simply empty dict!\n        self.factors = {p: [p] for p in self.primes}\n        \n    def _compute_primes(self, max_n):\n        primes = list()\n        sieve = [True] * (max_n+1)\n        for prime in range(2, max_n+1):\n            if not sieve[prime]:\n                continue\n            \n            primes.append(prime)\n            \n            # better runtime than a manual while loop!\n            for j in range(prime+prime, max_n+1, prime):\n                sieve[j] = False\n        \n        return primes\n    \n    # this hurts the runtime!\n    #@lru_cache(maxsize=MAX_N)\n    def factorize(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        self.factors[n] = factors = set()\n        work = n\n        for prime in self.primes:\n            # does not improve runtime!\n            if work < prime:\n                break\n            \n            if work % prime == 0:\n                factors.add(prime)\n                work //= prime\n                \n                factors.update(self.factorize(work))\n                break\n\n        return factors\n        \n        \nclass Graph:\n    def __init__(self):\n        self.adj = {}\n        self.factors = set()\n        self.values = set()\n    \n    def add_vertex(self, p, label):\n        if p not in self.adj:\n            self.adj[p] = set()\n        if label == 'factor':\n            self.factors.add(p)\n        else:\n            self.values.add(p)\n    \n    def add_factor(self, factor):\n        self.add_vertex(factor, 'factor')\n        \n    def add_value(self, value):\n        self.add_vertex(value, 'value')\n        \n    def connect(self, p, q):\n        self.adj[p].add(q)\n        self.adj[q].add(p)\n\n    def find_largest_connected_size(self):\n        seen = set()\n        largest = 0\n        for p in list(self.adj.keys()):\n            count = self._dfs_from(p, seen)\n            largest = max(largest, count)\n            \n        return largest\n    \n    def _dfs_from(self, p, seen):\n        if p in seen:\n            return 0\n        \n        seen.add(p)\n        \n        count = 1 if p in self.values else 0\n        \n        return count + sum(self._dfs_from(q, seen) for q in self.adj[p])\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        parent = list(range(n+1))\n        def find(x):\n            if parent[x]!=x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            px = find(x)\n            py = find(y)\n            parent[px] = py\n            \n        div_bucket = collections.defaultdict(list)\n        def findDivisor(num):\n            if num < 2:\n                return set()\n            for div in range(2, int(math.sqrt(num)) + 2):\n                if num%div == 0:\n                    return findDivisor(num//div) | {div}\n            return {num}\n                    \n        for i in range(n):\n            div_set = set()\n            div_set = findDivisor(A[i])\n            for div in div_set:\n                div_bucket[div].append(i)\n                        \n\n        for _, nums in list(div_bucket.items()):\n            for j in range(len(nums)-1):\n                union(nums[j], nums[j+1])\n\n        return max(collections.Counter([find(x) for x in range(n)]).values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor = {}\n        dsu = DSU()\n        \n        def get_primes(num):\n            primes = set()\n            i = 2\n            while i * i <= num:\n                if num % i == 0:\n                    while num % i == 0:\n                        num = num // i\n                    primes.add(i)\n                i += 1\n            if num > 1:\n                primes.add(num)\n            return primes\n        \n        for num in A:\n            primes = get_primes(num)\n            for p in primes:\n                factor.setdefault(p, num)\n                if dsu.find(num) != dsu.find(factor[p]):\n                    dsu.union(num, factor[p])\n        ans = 0\n        for v in list(factor.values()):\n            ans = max(dsu.count[v], ans)\n        return ans\n    \n    \nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = {}\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = _b\n            self.count[_b] += self.count[_a]\n    \n    \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        \n        def find(a):\n            if a not in parent: \n                parent[a] = a\n                return a\n            if parent[a] == a:\n                return a\n            parent[a] = find(parent[a])\n            return parent[a]\n        \n        for num in A:\n            parent[num] = num\n        \n        for num in A:\n            for i in range(2, int(sqrt(num)) + 1):\n                if num % i == 0:\n                    parent[find(num)] = parent[find(i)]\n                    parent[find(num)] = parent[find(num / i)]\n        \n        count = {}\n        maxi = 1\n        for num in A:\n            tmp = find(num)\n            if tmp not in count:\n                count[tmp] = 1\n            else:\n                count[tmp] += 1\n            maxi = max(maxi, count[tmp])\n        \n        return maxi\n        \n        \n    def largestComponentSize2(self, A: List[int]) -> int:\n        \n        def gcd(a, b):\n            while b != 0:\n                a, b = b, a % b\n            return a\n        \n        visited = [False] * len(A)\n        group = [-1] * len(A)\n        stack = []\n        num = 0\n        maxGrp = 0\n        \n        for i in range(len(A)):\n            if visited[i] == False:\n                stack.append(i)\n                numGrp = 0\n            \n                while len(stack) > 0:\n                    curr = stack.pop()\n                    for j in range(len(A)):\n                        if j == curr: \n                            continue\n                        if group[j] == -1:\n                            if A[curr] % 2 == A[j] % 2 == 0 or gcd(A[curr], A[j]) > 1:\n                                group[j] = num\n                                numGrp += 1\n                                stack.append(j)\n\n                visited[i] = True\n                maxGrp = max(maxGrp, numGrp)\n                num += 1\n                \n        \n        return maxGrp\n        \n", "class UF:\n    def __init__(self,size):\n        self.d = [i for i in range(size+1)]\n    def find(self,m):\n\n        if self.d[m] != m:\n            self.d[m] = self.find(self.d[m])\n        return self.d[m]\n    def union(self,m,n):\n        pm = self.find(m)\n        pn = self.find(n)\n\n        self.d[pm] = pn\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UF(max(A))\n        for a in A:\n            for factor in range(2,int(a**0.5)+1):\n                if a % factor == 0:\n                    uf.union(a,factor)\n                    uf.union(a,a//factor)\n        ret = 0\n        C = collections.Counter()\n        for a in A:\n            group_id = uf.find(a)\n            C[group_id] += 1\n            ret = max(ret,C[group_id])\n        return ret", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent = [-1]*1000001\n        \n        def find(node):\n            if parent[node] == -1:\n                return node\n            parent[node] = find(parent[node])\n            return parent[node]\n                \n        \n        def union(X,Y):\n            parentX = find(X)\n            parentY = find(Y)\n\n            if parentX != parentY:\n                parent[parentY] = parentX\n\n        for node in A:\n            for i in range(2,int(sqrt(node)) + 1):\n                if node%i == 0:\n                    union(i,node)\n                    union(node,node//i)\n        count = 0\n        d = {}\n        \n        for node in A:\n            parentNode = find(node)\n            count = max(count, 1 + d.get(parentNode,0))\n            d[parentNode] = 1 + d.get(parentNode,0)\n        return count\n            \n", "from collections import defaultdict, Counter\n\nMAX_N = 100000\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        sieve = Sieve(MAX_N+1)\n        factors = defaultdict(list)\n        for x in A:\n            for factor in sieve.factorize(x):\n                factors[factor].append(x)\n\n        uf = UnionFind()\n        for values in list(factors.values()):\n            for i in range(1, len(values)):\n                uf.connect(values[i-1], values[i])\n                \n        return max(list(Counter(uf.root(x) for x in A).values()), default=0)\n        '''\n        \n        # build bipartite graph from factors and values\n        g = Graph()\n        for factor, values in factors.items():\n            g.add_factor(factor)\n            for value in values:\n                g.add_value(value)\n                g.connect(factor, value)\n        \n        return g.find_largest_connected_size()\n        '''\n\n    \nclass UnionFind:\n    def __init__(self):\n        self.parents = {}\n    \n    def connect(self, a, b):\n        if a not in self.parents:\n            self.parents[a] = a\n        \n        if b not in self.parents:\n            self.parents[b] = b\n            \n        root = self.root(b)\n        self.parents[self.root(a)] = root\n        return root\n    \n    def root(self, a):\n        if a not in self.parents:\n            self.parents[a] = a\n            return a\n\n        if a == self.parents[a]:\n            return a\n        \n        self.parents[a] = self.root(self.parents[a])\n        \n        return self.parents[a]\n\n\nclass Sieve:\n    def __init__(self, limit):\n        self.primes = self._compute_primes(limit)\n        # better runtime than simply empty dict!\n        self.factors = {p: {p} for p in self.primes}\n        self.factors[1] = set()\n        \n    def _compute_primes(self, limit):\n        primes = list()\n        sieve = [True] * limit\n        for prime in range(2, limit):\n            if not sieve[prime]:\n                continue\n            \n            primes.append(prime)\n            \n            # better runtime than a manual while loop!\n            for j in range(prime+prime, limit, prime):\n                sieve[j] = False\n        \n        return primes\n    \n    # this hurts the runtime!\n    #@lru_cache(maxsize=MAX_N)\n    def factorize(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        for prime in self.primes:\n            if n % prime == 0:\n                factors = self.factors[n] = self.factorize(n // prime).union({prime})\n                return factors\n\n        raise ValueError(f'Value larger than max known prime: {n}')\n        \n        \nclass Graph:\n    def __init__(self):\n        self.adj = {}\n        self.factors = set()\n        self.values = set()\n    \n    def add_vertex(self, p, label):\n        if p not in self.adj:\n            self.adj[p] = set()\n        if label == 'factor':\n            self.factors.add(p)\n        else:\n            self.values.add(p)\n    \n    def add_factor(self, factor):\n        self.add_vertex(factor, 'factor')\n        \n    def add_value(self, value):\n        self.add_vertex(value, 'value')\n        \n    def connect(self, p, q):\n        self.adj[p].add(q)\n        self.adj[q].add(p)\n\n    def find_largest_connected_size(self):\n        seen = set()\n        largest = 0\n        for p in list(self.adj.keys()):\n            count = self._dfs_from(p, seen)\n            largest = max(largest, count)\n            \n        return largest\n    \n    def _dfs_from(self, p, seen):\n        if p in seen:\n            return 0\n        \n        seen.add(p)\n        \n        count = 1 if p in self.values else 0\n        \n        return count + sum(self._dfs_from(q, seen) for q in self.adj[p])\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A: return 0\n        root = list(range(max(A) + 1))\n        def find(i):\n            while not root[i] == i:\n                root[i] = root[root[i]]\n                i = root[i]\n            return i\n\n        def union(a, i):\n            root[find(a)] = find(i)\n\n        for a in A:\n            for i in range(2, int(math.sqrt(a)) + 1):\n                if a % i == 0:\n                    union(a, i)\n                    union(a, a // i)\n        return Counter([find(a) for a in A]).most_common()[0][1]", "from collections import defaultdict, Counter\nfrom functools import lru_cache\n\nMAX_N = 100000\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # compute factors\n        sieve = Sieve(MAX_N)\n        factors = defaultdict(list)\n        for x in A:\n            for factor in sieve.factorize(x):\n                factors[factor].append(x)\n        '''\n        f = Factors()\n        factors = defaultdict(list)\n        for x in A:\n            for factor in f.find_for(x):\n                factors[factor].append(x)\n        '''\n\n        '''\n        uf = UnionFind()\n        for values in factors.values():\n            for i in range(1, len(values)):\n                uf.connect(values[i-1], values[i])\n                \n        return max(Counter(uf.root(x) for x in A).values(), default=0)\n        '''\n        \n        # build bipartite graph from factors and values\n        g = Graph()\n        for factor, values in list(factors.items()):\n            g.add_factor(factor)\n            for value in values:\n                g.add_value(value)\n                g.connect(factor, value)\n        \n        return g.find_largest_connected_size()\n\n\nclass Factors:\n    def __init__(self):\n        self.primes = self.find_primes(100000+1)\n        self.factors = {p: [p] for p in self.primes}\n        self.factors[1] = []\n    \n    def find_primes(self, limit):\n        primes = []\n        nums = [True] * limit\n        nums[0] = nums[1] = False\n        for n in range(limit):\n            if nums[n]:\n                primes.append(n)\n                for j in range(n+n, limit, n):\n                    nums[j] = False\n        \n        return primes\n    \n    def find_for(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        self.factors[n] = factors = set()\n        for prime in self.primes:\n            if n % prime == 0:\n                factors.add(prime)\n                for f in self.find_for(n // prime):\n                    factors.add(f)\n                break\n        \n        return factors\n\n    \nclass UnionFind:\n    def __init__(self):\n        self.parents = {}\n    \n    def connect(self, a, b):\n        if a not in self.parents:\n            self.parents[a] = a\n        \n        if b not in self.parents:\n            self.parents[b] = b\n            \n        root = self.root(b)\n        self.parents[self.root(a)] = root\n        return root\n    \n    def root(self, a):\n        if a not in self.parents:\n            self.parents[a] = a\n            return a\n\n        if a == self.parents[a]:\n            return a\n        \n        self.parents[a] = self.root(self.parents[a])\n        \n        return self.parents[a]\n\n\nclass Sieve:\n    def __init__(self, max_n):\n        self.primes = self._compute_primes(max_n)\n        self.factors = {p: [p] for p in self.primes}\n        # self.factors = {}\n        \n    def _compute_primes(self, max_n):\n        primes = list()\n        sieve = [True] * (max_n+1)\n        for prime in range(2, max_n+1):\n            if not sieve[prime]:\n                continue\n            \n            primes.append(prime)\n            \n            for j in range(prime+prime, max_n+1, prime):\n                sieve[j] = False\n        \n        return primes\n    \n    def factorize(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        self.factors[n] = factors = set()\n        work = n\n        for prime in self.primes:\n            # does not improve runtime!\n            if work < prime:\n                break\n            \n            if work % prime == 0:\n                factors.add(prime)\n                work //= prime\n                \n                factors.update(self.factorize(work))\n                break\n\n        return factors\n        \n        \nclass Graph:\n    def __init__(self):\n        self.adj = {}\n        self.factors = set()\n        self.values = set()\n    \n    def add_vertex(self, p, label):\n        if p not in self.adj:\n            self.adj[p] = set()\n        if label == 'factor':\n            self.factors.add(p)\n        else:\n            self.values.add(p)\n    \n    def add_factor(self, factor):\n        self.add_vertex(factor, 'factor')\n        \n    def add_value(self, value):\n        self.add_vertex(value, 'value')\n        \n    def connect(self, p, q):\n        self.adj[p].add(q)\n        self.adj[q].add(p)\n\n    def find_largest_connected_size(self):\n        seen = set()\n        largest = 0\n        for p in list(self.adj.keys()):\n            count = self._dfs_from(p, seen)\n            largest = max(largest, count)\n            \n        return largest\n    \n    def _dfs_from(self, p, seen):\n        if p in seen:\n            return 0\n        \n        seen.add(p)\n        \n        count = 1 if p in self.values else 0\n        \n        return count + sum(self._dfs_from(q, seen) for q in self.adj[p])\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        divisors, groups, sizes = {}, {}, {}\n\n        # Find all divisors of the numbers in the list\n        for num in A:\n            added = False\n\n            for i in range(2, max(int(math.sqrt(num)) + 1, 4)):\n                if num % i == 0:\n                    added = True\n\n                    # Found two divisors\n                    # First is i\n                    if i not in divisors:\n                        divisors[i] = set()\n                    divisors[i].add(num)\n\n                    # Second is num divided by i\n                    if (num_i := int(num / i)) > 1:\n                        if num_i not in divisors:\n                            divisors[num_i] = set()\n                        divisors[num_i].add(num)\n\n            if not added:\n\n                # This is a prime number\n                if num not in divisors:\n                    divisors[num] = set()\n                divisors[num].add(num)\n\n        # Union function\n        def union(node1: int, node2: int) -> None:\n            parent1 = find(node1)\n            parent2 = find(node2)\n\n            # Check if these nodes already belong to the same parent\n            if parent1 == parent2:\n                return\n            elif parent1 < parent2:\n\n                # Union to the smallest parent 1\n                groups[parent2] = parent1\n                sizes[parent1] = sizes[parent1] + sizes[parent2]\n\n            else:\n                # Union to the smallest parent 2\n                groups[parent1] = parent2\n                sizes[parent2] = sizes[parent1] + sizes[parent2]\n\n        # Find function\n        def find(node: int) -> int:\n\n            # If this node hasn't been created yet\n            if node not in groups:\n                groups[node] = node\n                sizes[node] = 1\n                return node\n\n            # Check if this node is also the parent (final node)\n            if groups[node] == node:\n                return node\n\n            # Apply path compression\n            groups[node] = find(groups[node])\n\n            # Return the parent\n            return groups[node]\n\n        # Union-find algorithm to union all groups with common divisor\n        for _, common_numbers in list(divisors.items()):\n            num1 = random.sample(common_numbers, 1)[0]\n\n            for num2 in common_numbers:\n                if num1 != num2:\n                    union(num1, num2)\n\n        return max(list(sizes.values()), default=1)\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        \n        for num in A:\n            parent[num] = num\n            \n        def find(a):\n            if a not in parent:\n                parent[a] = a\n                return a\n            if parent[a] == a:\n                return a\n            parent[a] = find(parent[a])\n            return parent[a]\n        \n        for num in A:\n            for i in range(2, int(sqrt(num)) + 1):\n                if num % i == 0:\n                    parent[find(num)] = parent[find(i)]\n                    parent[find(num)] = parent[find(num / i)]\n        \n        count = defaultdict(int)\n        maxi = 1\n        for num in A:\n            tmp = find(num)\n            count[tmp] += 1\n            maxi = max(maxi, count[tmp])\n            \n        return maxi", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor = {}\n        dsu = DSU()\n        \n        def get_primes(num):\n            primes = []\n            i = 2\n            while i * i <= num:\n                if num % i == 0:\n                    while num % i == 0:\n                        num = num // i\n                    primes.append(i)\n                i += 1\n            if num > 1:\n                primes.append(num)\n            return primes\n        \n        for num in A:\n            primes = get_primes(num)\n            for p in primes:\n                factor.setdefault(p, num)\n                if dsu.find(num) != dsu.find(factor[p]):\n                    dsu.union(num, factor[p])\n        ans = 0\n        for v in list(factor.values()):\n            ans = max(dsu.count[v], ans)\n        return ans\n    \n    \nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = {}\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = _b\n            self.count[_b] += self.count[_a]\n    \n    \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU()\n        prime_to_index = {}\n        for i, num in enumerate(A):\n            primes = self.getPrimes(num)\n            for prime in primes:\n                if prime in prime_to_index:\n                    dsu.union(prime_to_index[prime],i)\n                else:\n                    prime_to_index[prime] = i\n        return max(dsu.count.values())\n                        \n    \n    def getPrimes(self, num):\n        primes = set()\n        i = 2\n        while i * i <= num:\n            if num % i == 0:\n                while num % i == 0:\n                    num = num // i\n                primes.add(i)\n            i += 1\n        if num > 1:\n            primes.add(num)\n        return primes\n    \nclass DSU:\n    def __init__(self):\n        self.father = {}\n        self.count = {}\n    \n    def find(self, a):\n        self.father.setdefault(a, a)\n        self.count.setdefault(a, 1)\n        if a != self.father[a]:\n            self.father[a] = self.find(self.father[a])\n        return self.father[a]\n    \n    def union(self, a, b):\n        _a = self.find(a)\n        _b = self.find(b)\n        if _a != _b:\n            self.father[_a] = self.father[_b]\n            self.count[_b] += self.count[_a]\n        \n        \n        \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        p = list(range(max(A) + 1))\n       \n        def find(x):\n            while p[x] != x:\n                p[x] = p[p[x]]\n                x = p[x]\n            return x\n    \n        def union(x, y):\n            p[find(x)] = p[find(y)]      \n      \n        for a in A:     \n            for k in range(2, int(math.sqrt(a) + 1)):        \n                if a % k == 0:\n                    union(a, k)\n                    union(a, a // k)\n    \n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]", "from collections import defaultdict, Counter\nfrom functools import lru_cache\n\nMAX_N = 100000\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # compute factors\n        '''\n        sieve = Sieve(MAX_N)\n        factors = defaultdict(list)\n        for x in A:\n            for factor in sieve.factorize(x):\n                factors[factor].append(x)\n        '''\n        f = Factors()\n        factors = defaultdict(list)\n        for x in A:\n            for factor in f.find_for(x):\n                factors[factor].append(x)\n\n        '''\n        uf = UnionFind()\n        for values in factors.values():\n            for i in range(1, len(values)):\n                uf.connect(values[i-1], values[i])\n                \n        return max(Counter(uf.root(x) for x in A).values(), default=0)\n        '''\n        \n        # build bipartite graph from factors and values\n        g = Graph()\n        for factor, values in list(factors.items()):\n            g.add_factor(factor)\n            for value in values:\n                g.add_value(value)\n                g.connect(factor, value)\n        \n        return g.find_largest_connected_size()\n\n\nclass Factors:\n    def __init__(self):\n        self.primes = self.find_primes(100000+1)\n        self.factors = {p: [p] for p in self.primes}\n        self.factors[1] = []\n    \n    def find_primes(self, limit):\n        primes = []\n        nums = [True] * limit\n        nums[0] = nums[1] = False\n        for n in range(limit):\n            if nums[n]:\n                primes.append(n)\n                for j in range(n+n, limit, n):\n                    nums[j] = False\n        \n        return primes\n    \n    def find_for(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        self.factors[n] = factors = set()\n        for prime in self.primes:\n            if n % prime == 0:\n                factors.add(prime)\n                for f in self.find_for(n // prime):\n                    factors.add(f)\n                break\n        \n        return factors\n\n    \nclass UnionFind:\n    def __init__(self):\n        self.parents = {}\n    \n    def connect(self, a, b):\n        if a not in self.parents:\n            self.parents[a] = a\n        \n        if b not in self.parents:\n            self.parents[b] = b\n            \n        root = self.root(b)\n        self.parents[self.root(a)] = root\n        return root\n    \n    def root(self, a):\n        if a not in self.parents:\n            self.parents[a] = a\n            return a\n\n        if a == self.parents[a]:\n            return a\n        \n        self.parents[a] = self.root(self.parents[a])\n        \n        return self.parents[a]\n\n\nclass Sieve:\n    def __init__(self, max_n):\n        self.primes = self._compute_primes(max_n)\n        self.factors = {p: [p] for p in self.primes}\n        # self.factors = {}\n        \n    def _compute_primes(self, max_n):\n        primes = list()\n        sieve = [True] * (max_n+1)\n        for prime in range(2, max_n+1):\n            if not sieve[prime]:\n                continue\n            \n            primes.append(prime)\n            \n            for j in range(prime+prime, max_n+1, prime):\n                sieve[j] = False\n        \n        return primes\n    \n    @lru_cache(maxsize=MAX_N)\n    def factorize(self, n):\n        if n in self.factors:\n            return self.factors[n]\n        \n        self.factors[n] = factors = set()\n        work = n\n        for prime in self.primes:\n            if work < prime:\n                break\n            \n            if work % prime == 0:\n                factors.add(prime)\n                work //= prime\n                \n                factors.update(self.factorize(work))\n                break\n\n        return factors\n        \n        \nclass Graph:\n    def __init__(self):\n        self.adj = {}\n        self.factors = set()\n        self.values = set()\n    \n    def add_vertex(self, p, label):\n        if p not in self.adj:\n            self.adj[p] = set()\n        if label == 'factor':\n            self.factors.add(p)\n        else:\n            self.values.add(p)\n    \n    def add_factor(self, factor):\n        self.add_vertex(factor, 'factor')\n        \n    def add_value(self, value):\n        self.add_vertex(value, 'value')\n        \n    def connect(self, p, q):\n        self.adj[p].add(q)\n        self.adj[q].add(p)\n\n    def find_largest_connected_size(self):\n        seen = set()\n        largest = 0\n        for p in list(self.adj.keys()):\n            count = self._dfs_from(p, seen)\n            largest = max(largest, count)\n            \n        return largest\n    \n    def _dfs_from(self, p, seen):\n        if p in seen:\n            return 0\n        \n        seen.add(p)\n        \n        count = 1 if p in self.values else 0\n        \n        return count + sum(self._dfs_from(q, seen) for q in self.adj[p])\n", "class UnionFind:\n    def __init__(self, maxval):\n        self.arr = [i for i in range(maxval)]\n    \n    def find(self, n):\n        if n != self.arr[n]:\n            self.arr[n] = self.find(self.arr[n])\n        return self.arr[n]\n    \n    def union(self, a, b):\n        self.arr[self.find(a)] = self.arr[self.find(b)]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        maxval = max(A)+1\n        oUnionFind = UnionFind(maxval)\n        \n        for i in A:\n            for j in range(2, int(math.sqrt(i))+1):\n                if i % j == 0:\n                    oUnionFind.union(i, j)\n                    oUnionFind.union(i, i//j)\n        \n        counter = collections.defaultdict(int)\n        for i in A:\n            counter[oUnionFind.find(i)] += 1\n        \n        return max(list(counter.values()))", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100001\n\n        def _find(x):\n            if parent[x] == -1:\n                return x\n\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x // i)\n\n        cache = {}\n\n        for x in A:\n            xp = _find(x)\n            cache[xp] = 1 + cache.get(xp, 0)\n            \n        cache1 = sorted(list(cache.items()), key=lambda x: x[1])\n        maxi = cache1[-1][0]\n        \n        return cache[maxi]\n", "class DisjointSet:\n    def __init__(self, n):\n        self.set = list(range(n))\n    def find(self, i):\n        if self.set[i] != i:\n            self.set[i] = self.find(self.set[i])\n        return self.set[i]\n        \n    def union(self, i, j):\n        ii, jj = self.find(i), self.find(j)\n        self.set[ii] = jj\n\nclass Solution:\n    def primeFactors(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primeFactors(n//i) | set([i])\n        return set([n])\n        \n    def largestComponentSize(self, A):\n        n = len(A)\n        unionFind = DisjointSet(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primeFactors(num)\n            for q in pr_set: primes[q].append(i)\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                unionFind.union(indexes[i], indexes[i+1])\n        return max(Counter([unionFind.find(i) for i in range(n)]).values())\n", "class DSU:\n    \n    def __init__(self, N):\n        self.data = list(range(N))\n\n    def union(self, x, y):\n        xp, yp = self.find(x), self.find(y)\n        self.data[xp] = yp\n    \n    def find(self, x):\n        if self.data[x] != x:\n            self.data[x] = self.find(self.data[x])\n        return self.data[x]\n            \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def primeFactors(n):\n            \n            for i in range(2, int(math.sqrt(n)) + 1):\n                if n % i == 0:\n                    return primeFactors(n // i) | set([i])\n                \n            return set([n])\n        \n        primes = collections.defaultdict(list)\n        \n        for i, num in enumerate(A):\n            factors = primeFactors(num)\n            for factor in factors:\n                primes[factor].append(i)\n                \n        dsu = DSU(len(A))\n        \n        for factor, nums in primes.items():\n            for i in range(1, len(nums)):\n                dsu.union(nums[i-1], nums[i])\n                \n        counter = collections.Counter(dsu.find(i) for i in dsu.data)\n        \n        return max(v for v in counter.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*1000001\n\n        def _find(a):\n            if parent[a] == -1:\n                return a\n            parent[a] = _find(parent[a])\n            return parent[a]\n\n        def _union(a, b):\n            ap = _find(a)\n            bp = _find(b)\n            if ap != bp:\n                parent[bp] = ap\n\n        for a in A:\n            for i in range(2, int(sqrt(a)) + 1):\n                if a % i == 0:\n                    _union(i, a)\n                    _union(a, a//i)\n\n        cnt = 0\n        tmp = {}\n        for a in A:\n            ap = _find(a)\n            cnt = max(cnt, 1 + tmp.get(ap, 0))\n            tmp[ap] = 1 + tmp.get(ap, 0)\n        return cnt\n", "class Union:\n    def __init__(self, arr):\n        self.weight = {}\n        self.par = {}\n        for a in range(1, max(arr) + 1):\n            self.par[a] = a\n            self.weight[a] = 1\n        \n    def find(self, a):\n        while self.par[a] != a:\n            a = self.par[a]\n        return a\n    \n    def union(self, a, b):\n        \n        pa, pb = self.find(a), self.find(b)\n        if pa == pb:\n            return\n        if self.weight[pa] < self.weight[pb]:\n            pa, pb = pb, pa\n            \n        self.weight[pa] += self.weight[pb]\n        self.par[pb] = pa\n            \n        \n    def getMaxWeight(self):\n        return max(list(map(len, list(self.weight.values()))))\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        union = Union(A)\n        for a in A:\n            sqr = int(sqrt(a))\n            for j in range(2, sqr + 1):\n                if a % j == 0:\n                    union.union(a, a // j)\n                    union.union(a, j)\n                    \n        groups = collections.defaultdict(int)\n        for a in A:\n            groups[union.find(a)] += 1\n            \n        return max(groups.values())\n        \n                    \n                    \n        \n                \n", "class UF:        \n    def __init__(self) -> None:\n        self.parent = {}\n        self.sz = {}\n        self.count = 0\n        \n    def add(self, p):    \n        if p not in self.parent:\n            self.parent[p] = p\n            self.sz[p] = 1\n            self.count += 1\n                          \n    def find(self, p: int) -> int:\n        while p != self.parent[p]:\n            self.parent[p] = self.parent[self.parent[p]]\n            p = self.parent[p]\n        return p  \n              \n    def union(self, p: int, q: int) -> None:\n        i = self.find(p)\n        j = self.find(q)             \n        if i == j:    \n            return \n        if self.sz[i] > self.sz[j]:                 \n            self.parent[j] = i\n            self.sz[i] += self.sz[j]\n        else:             \n            self.parent[i] = j\n            self.sz[j] += self.sz[i]                                           \n        self.count -= 1 \n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def fac(n): \n            for i in range(2, int(n**0.5)+1):\n                if n % i == 0:\n                    n //= i\n                    return set((i,)) | fac(n)\n            return set((n,))\n        @lru_cache(None) \n        def group_id(p):\n            return uf.find(p)\n        uf = UF()\n        c = Counter() \n        for n in A:\n            factors = fac(n)\n            key = tuple(sorted(factors))\n            c[key] += 1\n            if c[key] == 1:\n                p = factors.pop()\n                uf.add(p)\n                for q in factors:\n                    uf.add(q)\n                    uf.union(p, q)\n        if uf.count == 1:\n            return len(A)            \n        groups = Counter()\n        for factors, value in c.items():\n            groups[group_id(factors[0])] += value\n        return groups.most_common()[0][1]    ", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        mp={} # for union find\n        ans=0\n        \n        def find(a):\n            if a not in mp: mp[a]=a\n            if mp[a]!=a:\n                mp[a]=find(mp[a])\n            return mp[a]\n            \n        def union(a,b): # b is smaller\n            pa=find(a)\n            pb=find(b)\n            if pa!=pb:\n                mp[pa]=pb\n            \n        for a in A:\n            t=int(math.sqrt(a))\n            for k in range(2,t+1):\n                if a%k==0:\n                    union(a,k)\n                    union(a,a/k)\n        return collections.Counter([find(a) for a in A]).most_common(1)[0][1]\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = {}\n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n        def union(rootlist):\n            if not rootlist: return\n            for i in range(1, len(rootlist)):\n                parent[rootlist[i]] = rootlist[0]\n                size[rootlist[0]] += size[rootlist[i]]\n            size[rootlist[0]]+=1\n        fact = [[] for _ in range(len(A))]\n        for j in range(len(A)):\n            num,p = A[j],2\n            while num >= p*p:\n                if num%p == 0:\n                    fact[j].append(p)\n                    size[p], parent[p] = 0, p\n                    while num%p == 0:\n                        num//=p\n                p+=1\n            if num > 1:\n                fact[j].append(num)\n                size[num], parent[num] =  0, num\n        for i in range(len(fact)):\n            rootset = set()\n            for factor in fact[i]:\n                rootset.add(find(factor))\n            union(list(rootset))\n        return max(size.values())\n", "from typing import List\nfrom collections import defaultdict, deque\nfrom math import sqrt\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factors = defaultdict(set)\n        disjoint = list(range(len(A)))\n        \n        def populateFactors():\n            for i in range(len(A)):\n                a = A[i]\n                if a == 1:\n                    continue\n                x = a\n                while x % 2 == 0:\n                    factors[2].add(i)\n                    x //= 2\n                for n in range(3, int(sqrt(x) + 1), 2):\n                    while x % n == 0:  # n is a factor\n                        factors[n].add(i)\n                        x //= n\n                        if x <= 1:\n                            break\n                if x > 1:\n                    factors[x].add(i)\n        def find(i):\n            while disjoint[i] != i:\n                i = disjoint[i]\n            return i\n        def union(i, j):\n            disjoint[find(j)] = find(i)\n        \n        populateFactors()\n        for factor in factors:\n            x = None\n            for i in factors[factor]:\n                if x is None: x = i\n                union(x, i)\n        count = defaultdict(int)\n        for i in range(len(A)):\n            count[find(i)] += 1\n        return max(count.values())", "class DSU: \n    def __init__(self, n):\n        self.p = list(range(n))\n        \n    def find(self, x):\n        if self.p[x] != x: \n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self, n):\n        for i in range(2, int(math.sqrt(n)) + 1):\n            if n % i == 0:\n                return self.primes_set(n // i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        UF = DSU(n) \n        primes = collections.defaultdict(list)\n        for i, num in enumerate(A): \n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n                \n        for _, indexes in primes.items():\n            for i in range(len(indexes) - 1):\n                UF.union(indexes[i], indexes[i + 1])\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent = dict()\n        def find(x):\n            parent.setdefault(x,x)\n            if x!=parent[x]:\n                parent[x] = find(parent[x])\n            return parent[x]\n        \n        def union(x,y):\n            px = find(x)\n            py = find(y)\n            parent[px]=py\n            \n        visited = set()\n        graph = collections.defaultdict(set)\n        count = 0\n        \n        \n        for a in A:\n            for fact in range(2,int(sqrt(a))+1):\n                if a%fact==0:\n                    x = a\n                    y = fact\n                    z = a//fact\n                    \n                    px = find(a)\n                    py = find(y)\n                    pz = find(z)\n                    \n                    if px!=py:\n                        union(x,y)\n                    if px!=pz:\n                        union(x,z)\n        \n                    \n        mem = collections.Counter()\n        for item in A:\n            p = find(item)\n            mem[p]+=1\n        maxVal = mem.most_common()\n        return(maxVal[0][1])", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if len(A) <= 1:\n            return len(A)\n\n        #create union\n        maxA = max(A)\n        unionL = list(range(maxA+1)) #initialize, each one is a component itself\n        size = [1]*(maxA+1)  #every component has size 1, the element itself initially\n\n        def findRoot(i):\n            k1 = i\n            while unionL[k1] != k1:\n                unionL[k1] = unionL[unionL[k1]]\n                k1 = unionL[k1]\n            return k1\n\n        def union(x, y):\n            k1 = findRoot(x)\n            k2 = findRoot(y)\n            if k1 != k2:\n                if size[k1] < size[k2]:\n                    unionL[k1] = k2  #can improve with size\n                    size[k2] += size[k1]\n                else:\n                    unionL[k2] = k1  #can improve with size\n                    size[k1] += size[k2]\n            return\n\n        for item in A:\n            mid = int(math.sqrt(item))+1\n            for k in range(2, mid+1):  #mid included\n                if item % k == 0:\n                    union(item, k)\n                    if item//k != 1:\n                        union(item, item//k)\n\n        count = {}\n        for item in A:\n            root = findRoot(item)\n            if root in count:\n                count[root] += 1\n            else:\n                count[root] = 1\n\n        return max(count.values())\n\n\n\n\n\n\n\n\n\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A_max = max(A)\n        primes = []\n        seive = [True] * (int(sqrt(A_max)) + 1)\n        seive[:2] = [False, False]\n        for i in range(len(seive)):\n            if seive[i]:\n                primes.append(i)\n                for j in range(i + i, len(seive), i):\n                    seive[j] = False\n        \n        graph = defaultdict(list)\n        for i, num in enumerate(A):\n            for p in primes:\n                if p * p > num:\n                    \n                    break\n                if num % p  == 0:\n                    while num % p == 0:\n                        num //= p\n                    graph[p].append(i)\n            if num > 1:\n                graph[num].append(i)\n        print(graph)\n        uf = DS(len(A))\n        for indx in list(graph.values()):\n            for i in range(1, len(indx)):\n                uf.union(indx[i - 1], indx[i])\n        parents = [uf.find(i) for i in range(len(A))]\n        return max(Counter(parents).values())\n                \n\n\nclass DS:\n    def __init__(self, n):\n        self.p = [-1]*n\n    \n    def find(self, x):\n        if self.p[x] >= 0:\n            self.p[x] = self.find(self.p[x])\n            return self.p[x]\n        return x\n    \n    def union(self, x, y):\n        x, y = self.find(x), self.find(y)\n        if x == y:\n            return\n        if self.p[x] < self.p[y]:\n            self.p[x] -= 1\n            self.p[y] = x\n\n            \n        else:\n            self.p[y] -= 1\n            self.p[x] = y\n            \n        \n        \n", "from typing import List\nfrom collections import defaultdict, deque\nfrom math import sqrt\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factors = defaultdict(set)\n        disjoint = list(range(len(A)))\n        \n        def populateFactors():\n            for i in range(len(A)):\n                a = A[i]\n                if a == 1:\n                    continue\n                x = a\n                while x % 2 == 0:\n                    factors[2].add(i)\n                    x //= 2\n                for n in range(3, int(sqrt(x) + 1), 2):\n                    while x % n == 0:  # n is a factor\n                        factors[n].add(i)\n                        x //= n\n                        if x <= 1:\n                            break\n                if x > 1:\n                    factors[x].add(i)\n        def find(i):\n            while disjoint[i] != i:\n                i = disjoint[i]\n            return i\n        def union(i, j):\n            disjoint[find(j)] = find(i)\n        \n        populateFactors()\n        for factor in factors:\n            x = None\n            for i in factors[factor]:\n                if x is None: x = i\n                union(x, i)\n        count = defaultdict(int)\n        for i in range(len(A)):\n            count[find(i)] += 1\n        return max(count.values())\n", "class unionfind:\n    def __init__(self, N):\n        self.parents = list(range(N))\n        self.size = [1] * N\n    \n    def find(self, x):\n        while x != self.parents[x]:\n            x = self.parents[x]\n        return x\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            sizex, sizey = self.size[px], self.size[py]\n            if sizex < sizey:\n                self.parents[px] = py\n                self.size[py] += sizex\n            else:\n                self.parents[py] = px\n                self.size[px] += sizey\n        else: return\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor_dic = collections.defaultdict(int)\n        uf = unionfind(len(A))\n        for idx, a in enumerate(A):\n            for factor in range(2, int(a**0.5) + 1):\n                if a%factor == 0:\n                    for fac in [factor, a//factor]:\n                        if fac not in factor_dic:\n                            factor_dic[fac] = idx\n                        else:\n                            # if idx == 2:\n                            #     print(idx, fac)\n                            #     print(factor_dic)\n                            uf.union(idx, factor_dic[fac])\n            if a not in factor_dic:\n                factor_dic[a] = idx\n            else:\n                uf.union(idx, factor_dic[a])\n        # print(factor_dic)\n        # print(uf.parents)\n        # print(uf.size)\n        return max(uf.size)\n\n", "class UF:        \n    def __init__(self) -> None:\n        self.parent = {}\n        self.sz = {}\n        self.count = 0\n        \n    def add(self, p):    \n        if p not in self.parent:\n            self.parent[p] = p\n            self.sz[p] = 1\n            self.count += 1\n                          \n    def find(self, p: int) -> int:\n        while p != self.parent[p]:\n            self.parent[p] = self.parent[self.parent[p]]\n            p = self.parent[p]\n        return p  \n              \n    def union(self, p: int, q: int) -> None:\n        i = self.find(p)\n        j = self.find(q)             \n        if i == j:    \n            return \n        if self.sz[i] > self.sz[j]:                 \n            self.parent[j] = i\n            self.sz[i] += self.sz[j]\n        else:             \n            self.parent[i] = j\n            self.sz[j] += self.sz[i]                                           \n        self.count -= 1 \n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def fac(n): \n            for i in range(2, int(n**0.5)+1):\n                if n % i == 0:\n                    n //= i\n                    return set((i,)) | fac(n)\n            return set((n,))\n        @lru_cache(None) \n        def group_id(p):\n            return uf.find(p)\n        uf = UF()\n        c = Counter() \n        for n in A:\n            factors = fac(n)\n            key = tuple(sorted(factors))\n            c[key] += 1\n            if c[key] == 1:\n                p = factors.pop()\n                uf.add(p)\n                for q in factors:\n                    uf.add(q)\n                    uf.union(p, q)\n        if uf.count == 1:\n            return len(A)            \n        groups = Counter()\n        for factors, value in list(c.items()):\n            groups[group_id(factors[0])] += value\n        return groups.most_common()[0][1]    \n            \n            \n            \n            \n            \n        \n", "class Solution:\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent = [-1] * 100001\n        \n        def _find(x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n        \n        def _union(x , y):\n            x_parent = _find(x)\n            y_parent = _find(y)\n            \n            if x_parent != y_parent:\n                parent[y_parent] = x_parent\n                \n        \n        for x in A:\n            for i in range(2 , int(sqrt(x))+1):\n                if x % i == 0:\n                    _union(i , x)\n                    _union(x , x//i)\n                    \n        count = 0\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count , 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp , 0)\n            \n        return count\n    \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100_001 # One more than all values\n        def find(x):\n            if parent[x] == -1: return x\n            parent[x] = find(parent[x])\n            return parent[x]\n\n        def union(x, y):\n            xp, yp = find(x), find(y)\n            if xp != yp: parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    union(i, x)\n                    union(x, x // i)\n        count = 0\n        cache = dict()\n        for x in A:\n            xp = find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count        \n    \n        def gcd(a, b):\n            if b == 0: return a\n            return gcd(b, a % b)\n        graph = dict()\n        for a in A: graph[a] = list()\n        n = len(A)\n        for i in range(n - 1):\n            for j in range(i + 1, n):\n                a, b = A[i], A[j]\n                if gcd(a, b) > 1: graph[a].append(b)\n                \n        for a in graph.keys(): print(f'graph[{a}]', graph[a])\n        largest = float('-inf')\n        def dfs(graph, node, count):\n            nonlocal largest\n            print('node', node, 'count', count, 'largest', largest)\n            if not graph[node]:\n                largest = max(largest, count)\n                return\n            for c in graph[node]: dfs(graph, c, count + 1)\n        for a in A: dfs(graph, a, 1)\n        print(largest)\n        print('-' * 50)", "class Solution1:\n    def largestComponentSize(self, A):\n        if not A: return 0\n        def findAndCompact(l, i): # require i >= 0\n            if l[i] == i: return i\n            p = l[i]\n            if p >= 0 and l[p] == p: return p\n            while p >= 0 and l[p] != p:\n                p = l[p]\n            root = p\n            \n            # compact\n            p = i\n            while p >= 0 and l[p] != p:\n                t = l[p]\n                l[p] = root\n                p = t\n            return root\n        \n        slist = [-1] * len(A)\n        d = {} # record prime->(root of union-find set)\n        for i in range(len(A)):\n            n = A[i]\n            has_factor = False\n            for j in range(2, int(sqrt(n)) + 1):\n                if n % j == 0:\n                    has_factor = True\n                    k = n // j\n                    #print(n, j, k)\n                    ri = -1 if slist[i] < 0 else findAndCompact(slist, slist[i])\n                    rj = -1 if j not in d else findAndCompact(slist, d[j])\n                    rk = -1 if k not in d else findAndCompact(slist, d[k])\n                    if ri < 0 and rj < 0 and rk < 0:\n                        slist[i] = d[j] = d[k] = i\n                    else:\n                        mm = min([item for item in (ri, rj, rk) if item >= 0])\n                        if slist[i] >= 0: slist[ri] = mm\n                        if j in d: slist[rj] = mm\n                        if k in d: slist[rk] = mm\n                        slist[i] = d[j] = d[k] = mm\n            if not has_factor: #prime\n                if A[i] not in d: slist[i] = d[A[i]] = i\n                else: slist[i] = d[A[i]]\n            #print(slist, d)\n        \n        for i in range(len(A)): findAndCompact(slist, i)\n        #print('### ', slist)\n        cc = Counter(slist)\n        m = cc.most_common(2)\n        return m[0][1] if m[0][0] != -1 else m[1][1]\n    \nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        n = self.p[x]\n        while n >= 0 and self.p[n] != n:\n            n = self.p[n]\n        root = n\n        # compact\n        n = x\n        while n >= 0 and self.p[n] != n:\n            t = self.p[n]\n            self.p[n] = root\n            n= t\n        return root\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        max_num = max(A);\n        ufs = DSU(max_num + 1);\n\n        for num in A:\n            for k in range(2, int(sqrt(num)) + 1):\n                if num % k == 0:\n                    ufs.union(num, k);\n                    ufs.union(num, num // k);\n\n        res = 1\n        d = defaultdict(int)\n        for num in A:\n            root = ufs.find(num)\n            d[root] += 1\n            res = max(res, d[root])\n        return res\n    \n    def largestComponentSize2(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(UF.find(indexes[i]), UF.find(indexes[i+1]))\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n\nclass Solution:\n    small_primes = (2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317)\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            t = sqrt(x) + 1\n            for p in Solution.small_primes:\n                if p > t:\n                    break\n                elif x % p == 0:\n                    root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = findRoot(x) if root_id == 0 else mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class UnionFindSet:\n    def __init__(self, n):\n        self.parants = [0] * n\n        self.rank = [0] * n\n\n        # self is a distinct group\n        for i in range(n):\n            self.parants[i] = i\n        \n    def find(self, x):\n        if x != self.parants[x]:\n            self.parants[x] = self.find(self.parants[x])\n        return self.parants[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n\n        # already in same group, no need to merge again\n        if px == py: return False\n        \n        if self.rank[px] < self.rank[py]:\n            self.parants[px] = py\n        elif self.rank[px] > self.rank[py]:\n            self.parants[py] = px\n        else:\n            self.parants[py] = px\n            self.rank[py] += 1\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        s = UnionFindSet(max(A) + 1)\n\n        for x in A:\n            for i in range(2, int(math.sqrt(x)) + 1):\n                if x % i == 0:\n                    s.union(x, i)\n                    s.union(x, x // i)\n        \n        hash = defaultdict(int)\n        \n        for x in A:\n            hash[s.find(x)] += 1 \n\n        return max(hash.values())\n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find(x):\n            if parent[x]==-1:\n                return x\n            parent[x]=_find(parent[x])\n            return parent[x]\n\n        def _union(x,y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(math.sqrt(x))+1):\n                if x%i == 0:\n                    _union(i,x)\n                    _union(x,x//i)\n        count = 0\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1+cache.get(xp,0))\n            cache[xp] = 1 + cache.get(xp,0)\n        return count\n", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        xr = self.find(x)\n        yr = self.find(y)\n        \n        if xr == yr: return\n        \n        if self.size[xr] >= self.size[yr]:\n            self.size[xr] += self.size[yr]\n            self.size[yr] = self.size[xr]\n            self.parent[yr] = xr\n        else:\n            self.size[yr] += self.size[xr]\n            self.size[xr] = self.size[yr]\n            self.parent[xr] = yr\n        \n        \n    \n\nclass Solution:\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        N = len(A)\n        max_A = max(A)\n        is_prime = [True] * (max_A+1)\n        index = {x: i for i, x in enumerate(A)}\n        dsu = DSU(N)\n        \n        for factor in range(2, max_A + 1):\n            if is_prime[factor]:\n                multiplier = factor << 1\n                previous = index.get(factor)\n                \n                while multiplier <= max_A:\n                    if multiplier in index:\n                        if previous is not None: \n                            dsu.union(previous, index.get(multiplier))\n                        previous = index[multiplier]\n                        \n                    multiplier += factor\n                    \n        # Browse DSU for result\n        return max(dsu.size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        ## max number of components:\n        fc=DisjointSetUnion(max(A))\n        # share common factor:\n        for a in A:\n            for i in range(2,int(sqrt(a))+1):\n                if a%i==0:\n                    fc.union(a,i)\n                    fc.union(a,a//i)\n        d=collections.defaultdict(int)\n        maxlen=0\n        for a in A:\n            group=fc.find(a)\n            d[group]+=1\n            maxlen=max(maxlen,d[group])\n        return maxlen\n        \nclass DisjointSetUnion(object):\n    def __init__(self,n):\n        self.parent=[i for i in range(n+1)]\n        self.size=[1]*(n+1)\n    def find(self,x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    def union(self,x,y):\n        px,py=self.find(x),self.find(y)\n        if px==py:\n            return px\n        if self.size[px]>self.size[py]:\n            px,py=py,px\n        self.parent[px]=py\n        self.size[py]+=self.size[px]\n        return py\n", "from math import sqrt, floor\nfrom collections import Counter\n\n\nclass UnionFind:\n\n    def __init__(self, size: int) -> None:\n        self.cache = list(range(size + 1))\n\n    def find(self, val: int) -> int:\n        if self.cache[val] != val:\n            self.cache[val] = self.find(self.cache[val])\n        return self.cache[val]\n\n    def union(self, x: int, y: int) -> None:\n        self.cache[self.find(x)] = self.cache[self.find(y)]\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        union_find = UnionFind(100000)\n        for num in A:\n            for factor in range(2, floor(sqrt(num)) + 1):\n                if num % factor == 0:\n                    union_find.union(num, factor)\n                    union_find.union(num, num // factor)\n\n        counter = Counter(map(union_find.find, A))\n        return counter.most_common(1)[0][1]", "class DisjointSets:\n   def __init__(self, n: int):\n      self.p = n*[-1]\n      self.s = n*[1]\n   def find(self, i: int) -> int:\n      r = i\n      while self.p[r] != -1:\n         r = self.p[r]\n      while i != r:\n         self.p[i], i = r, self.p[i]\n      return r\n   def merge(self, i: int, j: int) -> int:\n      i = self.find(i)\n      j = self.find(j)\n      if i != j:\n         if self.s[i] < self.s[j]:\n            i, j = j, i\n         self.p[j] = i\n         self.s[i] += self.s[j]\n      return i\n\nclass Solution:\n   def largestComponentSize(self, a: List[int]) -> int:\n      n, m = len(a), max(a)\n      acnt = (m+1)*[0]\n      for ai in a:\n         acnt[ai] += 1\n      acnt = list(accumulate(acnt))\n      ainv = n*[0]\n      for i in range(n-1, -1, -1):\n         acnt[a[i]] -= 1\n         ainv[acnt[a[i]]] = i\n      acnt = acnt[1:] + [n]\n      djs = DisjointSets(n)\n      isp = (m+1)*[True]\n      for i in range(2, m+1):\n         if not isp[i]:\n            continue\n         p = -1\n         for j in range(i, m+1, i):\n            isp[j] = False\n            for k in ainv[acnt[j-1]: acnt[j]]:\n               if p >= 0:\n                  djs.merge(p, k)\n               p = k\n      return max(djs.s)\n", "# all primes less than sqrt(100000)\nprimes = [\n    2,\n    3,\n    5,\n    7,\n    11,\n    13,\n    17,\n    19,\n    23,\n    29,\n    31,\n    37,\n    41,\n    43,\n    47,\n    53,\n    59,\n    61,\n    67,\n    71,\n    73,\n    79,\n    83,\n    89,\n    97,\n    101,\n    103,\n    107,\n    109,\n    113,\n    127,\n    131,\n    137,\n    139,\n    149,\n    151,\n    157,\n    163,\n    167,\n    173,\n    179,\n    181,\n    191,\n    193,\n    197,\n    199,\n    211,\n    223,\n    227,\n    229,\n    233,\n    239,\n    241,\n    251,\n    257,\n    263,\n    269,\n    271,\n    277,\n    281,\n    283,\n    293,\n    307,\n    311,\n    313,\n]\n\n\ndef prime_factors(n: int) -> List[int]:\n    if n == 1:\n        return []\n    for p in primes:\n        if n % p == 0:\n            return [p] + prime_factors(n // p)\n    return [n]\n\n\ndef group_by_factors(A):\n    groups = defaultdict(set)\n    for a in A:\n        for p in prime_factors(a):\n            groups[p].add(a)\n    return list(groups.values())\n\n\n# TODO: this uses up about 2/3 of the runtime by itself\ndef adjacencies_by_intersection(gs):\n    adj = [[] for _ in range(len(gs))]\n    for x in range(len(gs)):\n        for y in range(x):\n            if gs[x] & gs[y]:\n                adj[x].append(y)\n                adj[y].append(x)\n    return adj\n\n\ndef bfs(gs, adj, target):\n    unvisited = set(range(len(gs)))\n    largest = 0\n    while unvisited:\n        v = unvisited.pop()\n        q = [v]\n\n        group = set()\n        while q:\n            n = q.pop()\n            group.add(n)\n            for x in adj[n]:\n                if x in unvisited:\n                    unvisited.remove(x)\n                    q.append(x)\n        largest = max(largest, len(set(n for i in group for n in gs[i])))\n        # try to short circuit\n        if largest >= target:\n            return largest\n    return largest\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # group by prime factors and filter out singletons\n        gs = [g for g in group_by_factors(A) if len(g) > 1]\n\n        # build adjacency relations\n        adj = adjacencies_by_intersection(gs)\n\n        # bfs\n        target = len(A) // 2\n        return bfs(gs, adj, target)\n", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize2(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n        #print(primes,UF.__dict__)\n        for _, indexes in list(primes.items()):\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())\n    \n    \n    def largestComponentSize1(self, A: List[int]) -> int:\n        g = set(range(len(A)))\n        r = 0\n        while g:\n            gc = A[g.pop()]\n            #print(gc,g)\n            ri = 1\n            while True:\n                gm = set()\n                gc2 = 1\n                for i in g:\n                    #print(gc,i,A[i])\n                    if gcd(A[i],gc) > 1:\n                        ri+=1\n                        gm.add(i)\n                        gc2 *= A[i]\n                if not gm: break\n                g -= gm\n                gc = gc2\n            r = max(r,ri)\n                \n        return r\n        \n        \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n        \n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        #@lru_cache(maxsize=None)\n        \n        self.p = list(range(len(A)))\n        \n        def factors(n:int)->set:\n            return set(factor for i in range(2, int(n**0.5) + 1) if n % i == 0\n                       for factor in (i, n//i))\n        d = {}\n        g = set(range(len(A)))\n        fx = []\n        for i,v in enumerate(A):\n            f = factors(v)\n            f.add(v)\n            #print(i,v,f)\n            fx += [f]\n            for fi in f:\n                l = d.setdefault(fi,[])\n                l += [i]\n        \n        for di in list(d.values()):\n            for a,b in zip(di[1:],di):\n                self.p[self.find(a)] = self.find(b)\n                      \n        return max(Counter(self.find(i) for i in self.p).values())\n                      \n        r = 0                     \n        #print(fx,d)\n        while g:\n            gi = [g.pop()]\n            #print(gi,g)\n            g1 = [gi]\n            \n            while gi:\n                gii = gi.pop()\n                for f in fx[gii]:\n                    for di in d[f]:\n                        if di in g:\n                            g.remove(di)\n                            g1 += [di]\n                            gi+=[di]\n            r = max(r,len(g1))\n    \n        return r\n            \n            \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        mp={} # for union find\n        ans=0\n        \n        def find(a):\n            if a not in mp: mp[a]=a\n            if mp[a]!=a:\n                mp[a]=find(mp[a])\n            return mp[a]\n            \n        def union(a,b): # b is smaller\n            pa=find(a)\n            pb=find(b)\n            if pa!=pb:\n                mp[pa]=pb\n            \n        for a in A:\n            t=int(math.sqrt(a))\n            for k in range(2,t+1):\n                if a%k==0:\n                    union(a,k)\n                    union(a,a/k)\n        return max(collections.Counter([find(a) for a in A]).values())\n", "class Solution:\n    def __init__(self):\n        self.arr=[]\n        \n    def fac(self,n):\n        for i in range(2,floor(sqrt(n)+1)):\n            if n%i==0:\n                self.union(n,i)\n                self.union(n,n//i)\n                       \n    def find(self,x):\n        if self.arr[x] != x:\n            self.arr[x] = self.find(self.arr[x])\n        return self.arr[x]\n\n    def union(self,x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.arr[xr] = yr\n\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        self.arr=[0]*(max(A)+1)\n        ans=[0]*(max(A)+1)\n        A.sort()\n        for j,i in enumerate(self.arr):\n            self.arr[j]=j\n     \n        for i in A:\n            self.fac(i)\n        \n        for i in A:\n            ans[self.find(i)]+=1\n        return max(ans)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100002\n\n        def _find(x):\n            if parent[x] == -1:\n                return x\n\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n\n            if xp != yp:\n                parent[yp] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x // i)\n\n        count = 0\n        cache = {}\n\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n\n        return count\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def prime_factors(num):\n            '''\n            For a number returns it's prime factors in\n            ascending order\n            Input 12, output = [2,2,3]\n            '''\n            pfactors = []\n            factor = 2\n            while num >= factor * factor:\n                if num % factor == 0:\n                    pfactors.append(factor)\n                    num = num // factor\n                else:\n                    factor += 1\n            pfactors.append(num)\n            return pfactors\n        \n        class DisjointSetUnion(object):\n            '''\n            Union Find for 0 to n (inclusive)\n            '''\n            def __init__(self, n):\n                self.parent = {i:i for i in range(n+1)}\n                self.size = [1]*(1+n)\n            def find(self, x):\n                if self.parent[x] != x:\n                    #path compression during find\n                    self.parent[x] = self.find(self.parent[x])\n                return self.parent[x]\n                # while x != self.parent[x]:\n                #     x = self.parent[x]\n                # return self.parent[x]\n            def union(self, a, b):\n                x = self.find(a)\n                y = self.find(b)\n                # self.parent[y] = x\n                if x == y:\n                    return x\n                \n                if self.size[x] > self.size[y]:\n                    self.parent[y] = x\n                    self.size[x] += self.size[y]\n                    return x\n                \n                self.parent[x] = y\n                self.size[y] += self.size[x]\n                return y\n        \n        DS = DisjointSetUnion(max(A))\n        \n        #num_factor = defaultdict(list)\n        num_id = defaultdict(int)\n        for num in A:\n            pf = list(set(prime_factors(num)))\n            #num_factor[num] = pf\n            num_id[num] = pf[0]\n            for i in range(len(pf)-1):\n                #for num pf[i] and pf[i+1] can be unioned\n                DS.union(pf[i], pf[i+1]) \n        \n        max_size = 0        \n        #nums belong to groups which are root's of num_id[num]\n        group_count = defaultdict(int)\n        for num in A:\n            group_id = DS.find(num_id[num])\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id])\n        \n        return max_size", "class Solution:\n    \n    def _factorize(self, n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self._factorize(n//i) | set([i])\n        return set([n])\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = set()\n        factors = {}\n        for x in A:\n            f = self._factorize(x)\n            primes |= f\n            factors[x] = list(f)\n        \n        uf = UF(primes, A)\n        for x in A:\n            for j in range(len(factors[x])):\n                uf.union(x, factors[x][j])\n            uf.sz[uf.root(x)] += 1\n        \n        return max([v for _, v in uf.sz.items()])\n\n\nclass UF:\n    def __init__(self, primes, A):\n        self.parent = {p: p for p in primes}\n        for p in A:\n            self.parent[p] = p\n        self.sz = {p: 0 for p in primes}\n        for p in A:\n            self.sz[p] = 0\n    \n    def root(self, u):\n        while self.parent[u] != u:\n            self.parent[u] = self.parent[self.parent[u]]\n            u = self.parent[u]\n        return u\n    \n    def union(self, u, v):\n        r_u = self.root(u)\n        r_v = self.root(v)\n        if r_u == r_v:\n            return\n        \n        if self.sz[r_u] > self.sz[r_v]:\n            self.parent[r_v] = r_u\n            self.sz[r_u] += self.sz[r_v]\n        else:\n            self.parent[r_u] = r_v\n            self.sz[r_v] += self.sz[r_u]", "class Solution:\n    def find_common_fractor(self, num: int, u):\n        for i in range(2, int(sqrt(num)) + 1):\n            if num % i == 0:\n                u.union(num, i)\n                u.union(num, num // i)\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        u = UnionFind(max(A) + 1)\n        for item in A:\n            self.find_common_fractor(item, u)\n        o = 1\n        temp_dict = {}\n        for item in A:\n            parent = u.find(item)\n            if parent not in temp_dict:\n                temp_dict[parent] = 1\n            else:\n                temp_dict[parent] += 1\n            o = max(o, temp_dict[parent])\n        return o\n    \n\nclass UnionFind:\n    def __init__(self, len_: int):\n        self.lst = [i for i in range(len_)]\n\n    def find(self, num: int):\n        if num != self.lst[num]:\n            self.lst[num] = self.find(self.lst[num])\n        return self.lst[num]\n\n    def union(self, x: int, y: int):\n        self.lst[self.find(x)] = self.lst[self.find(y)]", "class UnionFind:\n    def __init__(self, N):\n        self.N = N\n        self.rank = [1 for i in range(N)]\n        self.parent = [i for i in range(N)]\n    def find(self, x):\n        y = x\n        while x != self.parent[x]:\n            x = self.parent[x]\n        self.parent[y] = x\n        return x\n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return False\n        if self.rank[px] < self.rank[py]:\n            self.parent[px] = py\n        else:\n            self.parent[py] = px\n            if self.rank[px] == self.rank[py]:\n                self.rank[px] += 1\n        return True\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        #Union Find: union x to all of its factors. O(N^1.5)\n        def union_all(x):\n            for i in range(2, int(x**0.5) + 1):\n                if x % i == 0:\n                    uf.union(x, i)\n                    uf.union(x, x//i)\n        uf = UnionFind(100001)\n        max_size = 1\n        for i in range(len(A)):\n            union_all(A[i])\n        d = Counter()\n        for i in range(len(A)):\n            d[uf.find(A[i])] += 1\n            max_size = max(max_size, d[uf.find(A[i])])\n            # print(A[i], uf.find(A[i]))\n\n        return max_size\n            \n            \n            \n            \n                \n        \n", "class UnionFind():\n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.size = [1] * n\n    \n    def find(self, i):\n        if self.parent[i] != i:\n            self.parent[i] = self.find(self.parent[i])\n        return self.parent[i]\n    \n    def union(self, i, j):\n        pi = self.find(i)\n        pj = self.find(j)\n        \n        if pi != pj:\n            self.parent[max(pi, pj)] = min(pi, pj)\n            self.size[min(pi, pj)] += self.size[max(pi, pj)]\n\n            \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def decompose(num):\n            if num == 1:\n                return []\n            res = []\n            remain = num\n            for factor in range(2, int(math.sqrt(num))+1):\n                if remain % factor == 0:\n                    while remain % factor == 0:\n                        remain //= factor\n                    res.append(factor)\n            if remain > 1:\n                res.append(remain)\n            return res\n        \n       \n        union_find = UnionFind(len(A))\n        factor_index = dict()\n        for idx, num in enumerate(A):\n            factors = decompose(num)\n            # print(\\\"factors\\\", factors)\n            for factor in factors:\n                if factor not in factor_index:\n                    factor_index[factor] = idx\n                else:\n                    union_find.union(factor_index[factor], idx)\n                # print(\\\"factor\\\", factor, \\\"unions\\\", unions.parent, unions.size )\n        return max(union_find.size)\n        \n            \n            \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        uf = UnionFind(max(A))\n               \n        for a in A:\n            for factor in range(2, int(sqrt(a))+1):\n                if a % factor == 0:\n                    uf.union(a, factor)\n                    uf.union(a, a // factor)\n                    \n        count_ = defaultdict(int)\n        out = 0\n        \n#         print(uf.parent)\n#         print(uf.size)\n        \n        for a in A:\n            groupid = uf.find(a)\n            count_[groupid] += 1\n            out = max(out, count_[groupid])\n        \n        return out\n        \n            \nclass UnionFind:\n    def __init__(self, size):\n        self.parent = [i for i in range(size+1)]\n        self.size = [1] * (size+1)\n        \n    def find(self, num):\n        if self.parent[num] != num:\n            self.parent[num] = self.find(self.parent[num])\n        \n        return self.parent[num]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if self.size[px]>self.size[py]:\n            px, py = py, px\n            \n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        \n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        parent = [-1]*100001\n        def _find(x):\n            if parent[x]==-1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n        \n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp!=yp:\n                parent[yp] = xp\n        \n        for x in A:\n            for i in range(2, int(math.sqrt(x))+1):\n                if x%i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n                    \n        count = 0\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1+cache.get(xp, 0))\n            cache[xp] = 1+cache.get(xp,0)\n            \n        return count", "import collections\nimport math\n\nclass UF:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            size_x, size_y = self.size[px], self.size[py]\n            if size_x < size_y:\n                self.parent[px] = py\n                self.size[py] += size_x\n            else:\n                self.parent[py] = px\n                self.size[px] += size_y\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor_to_num_index = collections.defaultdict(int)\n        uf = UF(len(A))\n        for ind, num in enumerate(A):\n            for factor in range(2, int(math.sqrt(num) + 1)):\n                if num % factor == 0:\n                    for fac in (factor, num // factor):\n                        if fac in factor_to_num_index:\n                            uf.union(ind, factor_to_num_index[fac])\n                        else:\n                            factor_to_num_index[fac] = ind\n            if num not in factor_to_num_index:\n                factor_to_num_index[num] = ind\n            else:\n                uf.union(ind, factor_to_num_index[num])\n        return max(uf.size)\n\n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]  # parent array\n        self.s=[1]*n  # size array\n        \n    def find(self,x): # find the representative/root of x\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    M=100000\n    sieve=[0]*(M+1) # stores the minimum prime divisor of integers up to M\n    for i in range(2,M+1):\n        if sieve[i]!=0:\n            continue\n        for j in range(1,M//i+1):\n            sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:   \n        g=UF(len(A))\n        primes=defaultdict(list) # {q:[nums]} list of integers that's divisible by prime q\n        for i,num in enumerate(A):\n            tmp=-1\n            while num>1:\n                q=self.sieve[num]\n                num//=q\n                if q!=tmp:\n                    tmp=q\n                    primes[q].append(i) # add the element to be divisible by q\n                    \n        for l in primes.values():\n            root=g.find(l[0]) # representative/root of the 1st integer divisible by q\n            for i in l[1:]: # joins all components with root\n                node=g.find(i)\n                if node!=root:\n                    if g.s[root]<g.s[node]: # connect the smaller set to the larger one\n                        root,node=node,root\n                    g.p[node]=root\n                    g.s[root]+=g.s[node]\n        \n        return max(g.s)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        if not A:\n            return 0\n        \n        def findPrimes(n):\n            for i in range(2, int(n**0.5)+1):\n                if n % i == 0:\n                    return set([i]) | findPrimes(n//i)\n            return set([n])\n        \n        \n        findset = list(range(len(A)))\n        def find(i):\n            while findset[i] != i:\n                i = findset[i]\n            return i\n        \n        def union(i, j):\n            ri, rj = find(i), find(j)\n            findset[rj] = ri\n        \n        \n        primdic = defaultdict(list)\n        for i, num in enumerate(A):\n            ps = findPrimes(num)\n            for p in list(ps):\n                primdic[p] += i,\n        \n        for idxs in list(primdic.values()):\n            for i in range(len(idxs)-1):\n                union(idxs[i], idxs[i+1])\n                \n        \n        return max(Counter(find(i) for i in range(len(A))).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        mem = {}\n        def getFactors(num: int) -> set:\n            if num in mem: return mem[num]\n            for divBy in range(2, floor(sqrt(num)) + 1):\n                if num % divBy == 0:\n                    mem[num] = getFactors(num // divBy) | set([divBy])\n                    return mem[num]\n            mem[num] = set([num])\n            return mem[num]\n        \n        groups = {}\n        factorToNum = {}\n        numToGroupKey = {}\n        groupKeyToNums = defaultdict(lambda: [])\n        def findGroupsForFactors(factors: List[int]) -> List[int]:\n            keys = set()\n            for factor in factors:\n                if factor in factorToNum:\n                    keys.add(numToGroupKey[factorToNum[factor]])\n            return keys\n        \n        maxSize = 0\n        for num in A:\n            factors = getFactors(num)\n            groupKeys = findGroupsForFactors(factors)\n            #print(\\\"factors\\\", num, factors, groupKeys)\n            for factor in factors:\n                factorToNum[factor] = num\n            size = 1 + sum([groups[key] for key in groupKeys])\n            if len(groupKeys) >= 2:\n                numToGroupKey[num] = num\n                groupKeyToNums[num] = [num]\n                for key in groupKeys:\n                    for lastNum in groupKeyToNums[key]:\n                        numToGroupKey[lastNum] = num\n                        groupKeyToNums[num].append(lastNum)\n                    groupKeyToNums[num].append(key)\n                    del groupKeyToNums[key]\n                    del groups[key]\n                groups[num] = size\n            elif len(groupKeys) == 1:\n                otherGroup = list(groupKeys)[0]\n                numToGroupKey[num] = otherGroup\n                groupKeyToNums[otherGroup].append(num)\n                groups[otherGroup] = size\n            else:\n                numToGroupKey[num] = num\n                groupKeyToNums[num] = [num]\n                groups[num] = size\n            #print(\\\"size\\\", size)\n            #print(\\\"groups\\\", groups)\n            #print(\\\"numToGroupKey\\\", numToGroupKey)\n            #print(dict(groupKeyToNums))\n            maxSize = max(maxSize, size)\n        #print(groups)\n        return maxSize\n", "#python program to do this question using disjoint set technique \nimport math\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent=[-1]*(100001)\n        \n        def find(val,parent):\n            if parent[val]==-1:\n                return val\n            parent[val]=find(parent[val],parent)\n            return parent[val]\n                \n        def union(x,y,parent):\n            xp=find(x,parent)\n            yp=find(y,parent)\n            if xp!=yp:\n                parent[yp]=xp\n\n        for val in A:\n            for i in range(2,int(math.sqrt(val))+1):\n                if val%i==0:\n                    union(i,val,parent)\n                    union(val,val//i,parent)\n                    \n                    \n                       \n        c=0\n        mp={}\n        for val in A:\n            pval=find(val,parent)\n            c=max(c,1+mp.get(pval,0))\n            mp[pval]=mp.get(pval,0)+1\n            \n        return c\n        \n        \n        \n        \n", "from typing import Dict\n\nclass Solution:\n    def _ds_find(ds: Dict[int, int], x: int) -> int:\n        if ds.setdefault(x, x) != x:\n            ds[x] = Solution._ds_find(ds, ds[x])\n\n        return ds[x]\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        ds = {}\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    ds[Solution._ds_find(ds, i)] = Solution._ds_find(ds, x)\n                    ds[Solution._ds_find(ds, i)] = Solution._ds_find(ds, x // i)\n\n        return max(Counter(Solution._ds_find(ds, i) for i in A).values())\n", "class UnionFind:\n    def __init__(self, N):\n        self.N = N\n        self.rank = [1 for i in range(N)]\n        self.parent = [i for i in range(N)]\n    def find(self, x):\n        y = x\n        while x != self.parent[x]:\n            x = self.parent[x]\n        self.parent[y] = x\n        return x\n    def union(self, x, y):\n        px = self.find(x)\n        py = self.find(y)\n        if px == py:\n            return False\n        if self.rank[px] < self.rank[py]:\n            self.parent[px] = py\n        else:\n            self.parent[py] = px\n            if self.rank[px] == self.rank[py]:\n                self.rank[px] += 1\n        return True\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def gcd(a, b): #Find gcd of (a, b) in logarithmic time\n            if b > a:\n                a, b = b, a\n            while b:\n                a = a % b\n                a, b = b, a\n            return a\n        def union_all(x):\n            for i in range(2, int(x**0.5) + 1):\n                if x % i == 0:\n                    uf.union(x, i)\n                    uf.union(x, x//i)\n                    # if x == 100 and i == 5:\n                    #     print(\\\"hey\\\")\n                    #     print(uf.find(100), uf.find(5))\n        uf = UnionFind(100001)\n        max_size = 1\n        for i in range(len(A)):\n            union_all(A[i])\n        d = Counter()\n        for i in range(len(A)):\n            d[uf.find(A[i])] += 1\n            max_size = max(max_size, d[uf.find(A[i])])\n            # print(A[i], uf.find(A[i]))\n        # print(uf.parent[5])\n        # print(uf.parent[100])\n        # print(uf.find(9), uf.find(8), uf.find(1))\n        return max_size\n            \n            \n            \n            \n                \n        \n", "class UnionFind:\n    def __init__(self, n):\n        self.parent = [i for i in range(n+1)]\n        self.size = [1 for i in range(n+1)]\n        \n    def find(self, u):\n        while u!=self.parent[u]:\n            self.parent[u] = self.parent[self.parent[u]]\n            u = self.parent[u]\n        return u\n    \n    def union(self, u, v):\n        pu = self.find(u)\n        pv = self.find(v)\n        if pu==pv:\n            return False\n        if self.size[pu]>self.size[pv]:\n            pu,pv = pv, pu\n        self.parent[pu] = pv\n        self.size[pv] += self.size[pu]\n        return True\n            \nclass Solution:\n    def sharecommon(self, a, b):\n        for k in range(2, min(a,b)+1):\n            if a%k==0 and b%k==0:\n                return True\n        return False\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        ufs = UnionFind(max(A))\n        foundSet = collections.defaultdict(int)\n        for a in A:\n            for factor in range(2, int(sqrt(a))+1):\n                if a%factor==0:\n                    ufs.union(a, factor)\n                    ufs.union(a, a//factor)\n        \n        for a in A:\n            foundSet[ufs.find(a)] += 1\n        \n        return max(foundSet.values()) if foundSet else 1\n                    \n        \n", "'''\nStart a dfs from every node not reached yet\nKeep max of dfs length\nKeep nodes visited and nodes to visit in dfs\n'''\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())        \n#         self.ret = float(-1)\n#         self.visited = set()        \n#         self.not_visited = set(A)\n#         self.factors = {}\n        \n#         for i in A:\n#             self.factors[i] = get_factors(i)\n            \n#         print(self.factors)\n            \n#         def dfs(cur, length):\n#             try:\n#                 self.not_visited.remove(cur)    \n#             except:\n#                 return\n\n#             if length > self.ret:\n#                 self.ret = length\n            \n#             for num in self.not_visited.copy():\n#                 if num == cur:\n#                     continue\n                    \n#                 for i in self.factors[num]:\n#                     if i in self.factors[cur]:\n#                         self.visited.add(num)\n#                         dfs(num, length + 1)\n#                         break\n                        \n#         for i in A:\n#             dfs(i, 1)\n#         return self.ret\n                    \n# def get_factors(x):\n#     res = set()\n#     for i in range(2, x + 1):\n#         if x % i == 0:\n#             res.add(i)\n#     return res\n", "class Solution:\n    # O(n x sqrt(max)) time, O(n x sqrt(max)) space\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # Somehow using this version will mysteriously have TLE\n        def find_prime_factors(num):\n            result = []\n            candidate = 2\n            cur_num = num\n            upper_limit = int(math.sqrt(num))\n            while candidate <= upper_limit:\n                if cur_num % candidate == 0:\n                    result.append(candidate)\n                    while cur_num % candidate == 0:\n                        cur_num //= candidate\n                candidate += 1\n\n            if cur_num != 1:\n                result.append(cur_num)\n            return result\n        \n        # Using the recursive version to avoid TLE, although it should have the same\n        # time complexity as the iterative version\n        # def find_prime_factors(num):\n        #     for i in range(2, int(math.sqrt(num)) + 1):\n        #         if num % i == 0:\n        #             return find_prime_factors(num // i) | set([i])\n        #     return set([num])\n        \n        def find_root(x):\n            if root[x] != x:\n                root[x] = find_root(root[x])\n            return root[x]\n        \n        def union(x, y):\n            root[find_root(x)] = root[find_root(y)]\n        \n        root = [i for i in range(len(A))]\n        prime_factor_to_index = defaultdict(list)\n        # O(n x sqrt(max))\n        for i, num in enumerate(A):\n            prime_factors = find_prime_factors(num)\n            for factor in prime_factors:\n                prime_factor_to_index[factor].append(i)\n        \n        # O(n x sqrt(max))\n        for indices in list(prime_factor_to_index.values()):\n            for i in range(1, len(indices)):\n                union(indices[i - 1], indices[i])\n        \n        # O(n)\n        root_count = Counter(find_root(i) for i in range(len(A)))\n        return max(root_count.values())\n        \n\n", "class Solution:\n    def primeDecompose(self, num):\n        factor = 2\n        prime_factors = []\n        while num >= factor * factor:\n            if num % factor == 0:\n                prime_factors.append(factor)\n                num = num // factor\n            else:\n                factor += 1\n        prime_factors.append(num)\n        return prime_factors\n    \n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        factorMap = {}\n        \n        def find(a):\n            if a not in factorMap or factorMap[a] == a:\n                factorMap[a] = a\n                return a\n            else:\n                return find(factorMap[a]) \n            \n        factorCount = {}\n        maxCount = 0\n        for n in A:\n            primeFactors = self.primeDecompose(n)\n            # print(primeFactors)\n            pivot = find(primeFactors[0])\n            # print(n,primeFactors[0],pivot,factorMap)\n            if pivot not in factorCount:\n                factorCount[pivot] = 0\n            factorCount[pivot] += 1\n            for i in range(1,len(primeFactors)):\n                root = find(primeFactors[i])\n                factorMap[root] = pivot\n                if root in factorCount and root != pivot:\n                    factorCount[pivot] += factorCount[root]\n                # print(n,primeFactors[i],root,factorMap)\n            maxCount = max(maxCount, factorCount[pivot])\n        \n        return maxCount", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n=len(A)\n        if n<2:\n            return n\n        A=set(A)\n        if 1 in A:\n            A.remove(1)\n        if len(A)==0:\n            return 1\n        #A=list(A)\n        #A.sort()\n        \n        def list_primes(m):\n            p=[True]*(m+1)\n            for i in range(2,m+1):\n                if p[i]:\n                    for j in range(2*i,m+1,i):\n                        p[j]=False\n            return [i for i in range(2,m+1) if p[i]]\n        \n        def find_prime_factors(x,prime_list,prime_set):\n            if x in prime_set:\n                return [x]\n            prime_factors=[]\n            for prime_num in prime_list:\n                if prime_num>x:\n                    break\n                if x%prime_num==0:\n                    prime_factors.append(prime_num)\n                    while x%prime_num==0:\n                        x//=prime_num\n            return prime_factors\n        \n        def prime_decompose(x):\n            f=2\n            prime_factors=[]\n            while x>=f*f:\n                if x%f==0:\n                    prime_factors.append(f)\n                    x//=f\n                else:\n                    f+=1\n            prime_factors.append(x)\n            return prime_factors\n        #print(prime_decompose(60))\n        #print(prime_decompose(5120))\n        #return 0\n        \n        prime_list=list_primes(max(A))\n        prime_set=set(prime_list)\n        #print(prime_list)\n        #d={x:find_prime_factors(x,prime_list,prime_set) for x in A}\n        d={x:list(set(prime_decompose(x))) for x in A}\n        #print([len(d[x]) for x in A])\n        all_factors=set()\n        for x in A:\n            for f in d[x]:\n                all_factors.add(f)\n        #print(all_factors)\n        find_dict={f:f for f in all_factors}\n        sink_size={f:1 for f in all_factors}\n        def find(f):\n            if find_dict[f]!=f:\n                find_dict[f]=find(find_dict[f])\n            return find_dict[f]\n        \n        def union(fi,fj):\n            sink_i=find(fi)\n            sink_j=find(fj)\n            if sink_i==sink_j:\n                return\n            if sink_size[sink_i]>sink_size[sink_j]:\n                find_dict[sink_j]=sink_i\n                sink_size[sink_i]+=sink_size[sink_j]\n            else:\n                find_dict[sink_i]=sink_j\n                sink_size[sink_j]+=sink_size[sink_i]\n        \n        def union_hyperedge(hyperedge):\n            for i in range(1,len(hyperedge)):\n                union(hyperedge[i],hyperedge[0])\n            \n        def union_no_load_balance(hyperedge):\n            sink=find(hyperedge[0])\n            for f in hyperedge:\n                find_dict[find(f)]=sink\n                find(f)\n            \n        for x in A:\n            union_hyperedge(d[x])\n        #print('Union done.')\n        sinks=set()\n        for f in all_factors:\n            sinks.add(find(f))\n        \n        count={sink:0 for sink in sinks}\n        \n        for x in A:\n            count[find(d[x][0])]+=1\n        \n        return max(count.values())\n", "def union(parent, rank, i, j):\n    parI = find(parent, i)\n    parJ = find(parent, j)\n    \n    if parI == parJ:\n        return\n    \n    if rank[parI] < rank[parJ]:\n        parent[parI] = parJ\n    elif rank[parI] > rank[parJ]:\n        parent[parJ] = parI\n    else:\n        parent[parJ] = parI\n        rank[parI] += 1\n        \n    \ndef find(parent, i):\n    if i != parent[i]:\n        parent[i] = find(parent, parent[i])\n    return parent[i]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        rank = [0]*n\n        parent = list(range(n))\n        factorToSet = {}\n        \n        for i, num in enumerate(A):\n            for factor in range(2, int(math.sqrt(num)+1)):\n                if num%factor == 0:\n                    if factor in factorToSet:\n                        union(parent, rank, i, factorToSet[factor])\n                    else:\n                        factorToSet[factor] = i\n                    cfactor = num//factor\n                    if cfactor in factorToSet:\n                        union(parent, rank, i, factorToSet[cfactor])\n                    else:\n                        factorToSet[cfactor] = i\n            if num in factorToSet:\n                union(parent, rank, i, factorToSet[num])\n            else:\n                factorToSet[num] = i\n        \n        for i in range(n):\n            find(parent, i)\n        return max(collections.Counter(parent).values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [i for i in range(len(A))]\n        rank = [0 for i in range(len(A))]\n        \n        def prime_factors(n):\n            primes = set()\n            d = 2\n            while d <= sqrt(n):\n                if n % d == 0:\n                    primes.add(d)\n                    n //= d\n                else:    \n                    d += 1\n            if n > 1:\n                primes.add(n)\n            return primes        \n                    \n        def find(n):    \n            p = parent[n]\n            if p == n:\n                return p\n            parent[n] = find(parent[n])\n            return parent[n]\n\n        def merge(n1, n2):\n            r1 = find(n1)\n            r2 = find(n2)\n            \n            if r1 == r2:\n                return\n            \n            if rank[r1] < rank[r2]:\n                parent[r1] = r2\n            elif rank[r1] > rank[r2]:\n                parent[r2] = r1\n            else:    \n                parent[r1] = r2\n                rank[r2] += 1\n                \n        prime_indeces = defaultdict(list)\n        for i, n in enumerate(A):\n            primes = prime_factors(n)\n            for p in primes:\n                prime_indeces[p].append(i)\n            \n        print(prime_indeces)    \n        # print(parent)\n        for p, indeces in list(prime_indeces.items()):\n            for i in range(len(indeces)-1):\n                # print('merging', A[indeces[i]], A[indeces[i+1]])\n                merge(indeces[i], indeces[i+1])\n                # print(parent)        \n                \n                \n        count_map = dict()\n        best = 0        \n        \n        for i in parent:\n            i = find(i)\n            if i in count_map:\n                count_map[i] += 1\n            else:\n                count_map[i] = 1\n                \n            best = max(best, count_map[i])\n        # print(count_map)    \n            \n        return best\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n        \n        count = 0;\n        ump = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + ump.get(xp, 0))\n            ump[xp] = 1 + ump.get(xp, 0)\n        return count", "from math import sqrt\nfrom collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        union = DisjoinSet(max(A))\n        for a in A:\n            for factor in range(2, int(sqrt(a)) + 1):\n                if a % factor == 0:\n                    union.union(a, factor)\n                    union.union(a, a // factor)\n        result = 0\n        counter = defaultdict(int)\n        for i in A:\n            parent = union.find(i)\n            counter[parent] += 1\n            result = max(result, counter[parent])\n        return result\n    \nclass DisjoinSet:\n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)]\n        self.size = [1 for _ in range(size + 1)]\n        \n    def find(self, val):\n        if self.parent[val] != val:\n            self.parent[val] = self.find(self.parent[val])\n        return self.parent[val]\n    \n    def union(self, i, j):\n        parentI, parentJ = self.find(i), self.find(j)\n        if parentI == parentJ:\n            return\n        if self.size[parentI] >= self.size[parentJ]:\n            big, small = parentI,parentJ\n        else:\n            big, small = parentJ, parentI\n        self.size[big] += self.size[small]\n        self.parent[small] = big\n", "class Solution:\n    # O(n x sqrt(max)) time, O(n x sqrt(max)) space\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        # Somehow using this version will mysteriously have TLE\n        def find_prime_factors(num):\n            result = set()\n            candidate = 2\n            cur_num = num\n            upper_limit = int(math.sqrt(num))\n            while candidate <= upper_limit:\n                if cur_num % candidate == 0:\n                    result.add(candidate)\n                    while cur_num % candidate == 0:\n                        cur_num //= candidate\n                candidate += 1\n\n            if cur_num != 1:\n                result.add(cur_num)\n            return result\n        \n        # Using the recursive version to avoid TLE, although it should have the same\n        # time complexity as the iterative version\n        # def find_prime_factors(num):\n        #     for i in range(2, int(math.sqrt(num)) + 1):\n        #         if num % i == 0:\n        #             return find_prime_factors(num // i) | set([i])\n        #     return set([num])\n        \n        def find_root(x):\n            if root[x] != x:\n                root[x] = find_root(root[x])\n            return root[x]\n        \n        def union(x, y):\n            root[find_root(x)] = root[find_root(y)]\n        \n        root = [i for i in range(len(A))]\n        prime_factor_to_index = defaultdict(list)\n        # O(n x sqrt(max))\n        for i, num in enumerate(A):\n            prime_factors = find_prime_factors(num)\n            for factor in prime_factors:\n                prime_factor_to_index[factor].append(i)\n        \n        # O(n x sqrt(max))\n        for indices in list(prime_factor_to_index.values()):\n            for i in range(1, len(indices)):\n                union(indices[i - 1], indices[i])\n        \n        # O(n)\n        root_count = Counter(find_root(i) for i in range(len(A)))\n        return max(root_count.values())\n        \n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n        \n        def _union(x,y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp!=yp:\n                parent[yp] = xp\n        \n        for x in A:\n            for i in range(2,int(sqrt(x))+1):\n                if x%i == 0:\n                    _union(i,x)\n                    _union(x,x//i)\n        \n        count = 0;\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [i for i in range(len(A))]\n        rank = [0 for i in range(len(A))]\n        \n        def prime_factors(n):\n            # for i in range(2, int(math.sqrt(n))+1):\n                # if n % i == 0:\n                    # return prime_factors(n//i) | set([i])\n            # return set([n])\n            primes = set()\n            d = 2\n            while d <= sqrt(n):\n                if n % d == 0:\n                    primes.add(d)\n                    n //= d\n                else:    \n                    d += 1\n            if n > 1:\n                primes.add(n)\n            return primes        \n                    \n        def find(n):    \n            p = parent[n]\n            if p == n:\n                return p\n            parent[n] = find(parent[n])\n            return parent[n]\n\n        def merge(n1, n2):\n            r1 = find(n1)\n            r2 = find(n2)\n            \n            if r1 == r2:\n                return\n            \n            if rank[r1] < rank[r2]:\n                parent[r1] = r2\n            elif rank[r1] > rank[r2]:\n                parent[r2] = r1\n            else:    \n                parent[r1] = r2\n                rank[r2] += 1\n                \n        prime_indeces = defaultdict(list)\n        for i, n in enumerate(A):\n            primes = prime_factors(n)\n            for p in primes:\n                prime_indeces[p].append(i)\n            \n        print(prime_indeces)    \n        # print(parent)\n        for p, indeces in list(prime_indeces.items()):\n            for i in range(len(indeces)-1):\n                # print('merging', A[indeces[i]], A[indeces[i+1]])\n                merge(indeces[i], indeces[i+1])\n                # print(parent)        \n                \n                \n        count_map = dict()\n        best = 0        \n        \n        for i in parent:\n            i = find(i)\n            if i in count_map:\n                count_map[i] += 1\n            else:\n                count_map[i] = 1\n                \n            best = max(best, count_map[i])\n        # print(count_map)    \n            \n        return best\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n=len(A)\n        parent=[i for i in range(max(A)+1)]\n        \n        def find(x):\n            if parent[x]==x:\n                return x\n            parent[x]=find(parent[x])\n            return parent[x]\n        \n        def union(x, y):\n            px=find(x)\n            py=find(y)\n            if px==py:\n                return px\n            parent[py]=px\n            return px\n        \n        \n        for a in A:\n            for k in range(2, int(sqrt(a))+1, 1):\n                if a%k==0:\n                    union(a, k)\n                    union(a, a//k)\n        max_len=0 \n        d=defaultdict(int)\n        for a in A:\n            group_id = find(a)\n            d[group_id]+=1\n            max_len = max(max_len, d[group_id])\n        return max_len\n            \n                \n                    \n                \n", "from collections import defaultdict, Counter\nclass DSU:\n    def __init__(self, n):\n        self.parent = list(range(n))\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        parent_x, parent_y = self.find(x), self.find(y)\n        self.parent[parent_x] = parent_y\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        def prime(num):\n            i = 2\n            temp = []\n            while num >= i*i:\n                if num % i == 0:\n                    temp.append(i)\n                    num = num//i\n                else:\n                    i += 1\n            temp.append(num)\n            return set(temp)\n        \n        dsu = DSU(len(A))\n        graph = defaultdict(list)\n        \n        for i, num in enumerate(A):\n            pr_set = prime(num)\n            for q in pr_set: \n                graph[q].append(i)\n\n        for _, indexes in list(graph.items()):\n            for i in range(len(indexes)-1):\n                dsu.union(indexes[i], indexes[i+1])\n\n        return max(Counter([dsu.find(i) for i in range(len(A))]).values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:        \n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n    \n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n                \n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]                  # union-find on primes\n        \n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        \n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        \n        while x != root:\n            temp = self.parent[x]\n            self.parent[x] = root\n            x = temp\n            \n        return root\n    \n    def union(self, x, y):\n        root1 = self.find(x)\n        root2 = self.find(y)\n        \n        if root1 == root2: return False\n        \n        if self.size[root1] > self.size[root2]:\n            self.parent[root2] = root1\n            self.size[root1] += self.size[root2]\n        else:\n            self.parent[root1] = root2\n            self.size[root2] += self.size[root1]\n        \n        return True\n    \n\nclass Solution:\n#     def commonFactor(self, x, y):\n#         if x == y: return True\n#         if y > x: return self.commonFactor(y, x)\n\n#         while y:\n#             x, y = y, x % y\n\n#         return x != 1\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(100001)\n        \n        for x in A:\n            for j in range(2, int(x ** 0.5) + 1):\n                if x % j == 0:\n                    dsu.union(x, j)\n                    dsu.union(x, x // j)\n                    \n        \n        counter = collections.Counter()\n        for x in A:\n            counter[dsu.find(x)] += 1\n        return counter.most_common(1)[0][1]", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        d = {}\n        for i in range(len(A)):\n            for j in range(2, int(math.sqrt(A[i])+1)):\n                if A[i]%j == 0:\n                    if j not in d:\n                        d[j] = []\n                    if A[i]//j not in d:\n                        d[A[i]//j] = []\n                    d[j].append(i)\n                    d[A[i]//j].append(i)\n            if A[i] not in d:\n                d[A[i]] = []\n            d[A[i]].append(i)\n        \n        self.father = list(range(len(A)))\n        for k,v in list(d.items()):\n            if len(v)>1:\n                for i in range(len(v)-1):\n                    self.union(v[i],v[i+1])\n        for i in range(len(self.father)):\n            self.find(i)\n        return Counter(self.father).most_common()[0][1]\n        \n    def find(self,x):\n        if self.father[x] == x:\n            return x\n        else:\n            self.father[x] = self.find(self.father[x])\n            return self.father[x]\n    def union(self,x,y):\n        x_father = self.find(x)\n        y_father = self.find(y)\n        if x_father!=y_father:\n            self.father[x_father] = y_father\n    \n", "class DSU:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        \n        while x != root:\n            temp = self.parent[x]\n            self.parent[x] = root\n            x = temp\n            \n        return root\n    \n    def union(self, x, y):\n        root1 = self.find(x)\n        root2 = self.find(y)\n        \n        if root1 == root2: return False\n        \n        if self.size[root1] > self.size[root2]:\n            self.parent[root2] = root1\n            self.size[root1] += self.size[root2]\n        else:\n            self.parent[root1] = root2\n            self.size[root2] += self.size[root1]\n        \n        return True\n    \n\nclass Solution:\n    def commonFactor(self, x, y):\n        if x == y: return True\n        if y > x: return self.commonFactor(y, x)\n\n        while y:\n            x, y = y, x % y\n\n        return x != 1\n        \n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DSU(100001)\n        \n        for x in A:\n            for j in range(2, int(x ** 0.5) + 1):\n                if x % j == 0:\n                    dsu.union(x, j)\n                    dsu.union(x, x // j)\n                    \n        \n        counter = collections.Counter()\n        max_val = 0\n        for x in A:\n            counter[dsu.find(x)] += 1\n        return counter.most_common(1)[0][1]", "from collections import defaultdict\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        small_primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997]\n        label = defaultdict(int)\n       \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            if k1 == 0:\n                return findRoot(k2)\n            r1, r2 = findRoot(k1), findRoot(k2)\n            if r1 < r2:\n                label[r1] += label[r2]\n                label[r2] = r1\n            elif r1 > r2:\n                label[r2] += label[r1]\n                label[r1] = r2\n            return min(r1, r2)\n\n        large_prime = 0\n        for x in A:\n            root_id = 0\n            for p in small_primes:\n                if p > x:\n                    break\n                elif x % p == 0:\n                    root_id = mergeRoot(root_id, p)\n                    while x % p == 0:\n                        x //= p\n            if x != 1:\n                root_id = mergeRoot(root_id, x)\n            label[root_id] -= 1\n        \n        return -min(label.values())", "class UnionFind:\n    def __init__(self, n):\n        self.p = []\n        self.size = [1] * n\n        for i in range(n):\n            self.p.append(i)\n        self.max_union_size = 1\n        \n    def union(self, X, Y):\n        px, py = self.find(X), self.find(Y)\n        if px == py:\n            return\n        elif self.size[px] < self.size[py]:\n            self.p[px] = py\n            self.size[py] += self.size[px]\n            self.max_union_size = max(self.max_union_size, self.size[py])\n        else:\n            self.p[py] = px\n            self.size[px] += self.size[py]\n            self.max_union_size = max(self.max_union_size, self.size[px])\n\n    def find(self, X): \n        if self.p[X] != X:\n            self.p[X] = self.find(self.p[X])\n        return self.p[X]\n    \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_prime_factors(num):\n            n = num\n            d = 2\n            while d * d <= n:\n                if n % d == 0:\n                    yield d\n                while n % d == 0:\n                    n //= d\n                d += 1\n            if n > 1:\n                yield n\n        \n        factors_to_nums = collections.defaultdict(list)\n        for i, a in enumerate(A):\n            for f in get_prime_factors(a):\n                factors_to_nums[f].append(i) # save the index of the number in A, which is easier to generate UF\n        \n        uf = UnionFind(len(A))\n        for idx_of_num in factors_to_nums.values():\n            for i in range(1, len(idx_of_num)):\n                uf.union(idx_of_num[0], idx_of_num[i])\n        \n        return uf.max_union_size\n\n''' \n# lingnan \u5199\u7684DisjointSet\uff0c\u8fd8\u6ca1\u6709\u770b\nclass DisjointSet:\n    def __init__(self, n):\n        self.parent = [-1] * n\n        self.max_size = 1\n    \n    \n    def find(self, x):\n        root = x\n        while self.parent[root] >= 0:\n            if self.parent[self.parent[root]] >= 0:\n                self.parent[root] = self.parent[self.parent[root]]\n            root = self.parent[root]\n        return root\n    \n    \n    def union(self, x, y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n        \n        if x_root != y_root:\n            if self.parent[x_root] > self.parent[y_root]:\n                x_root, y_root = y_root, x_root\n            \n            self.parent[x_root] += self.parent[y_root]\n            self.parent[y_root] = x_root\n            self.max_size = max(self.max_size, -self.parent[x_root])\n    \n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def get_prime_factors(num):\n            n = num\n            d = 2\n            while d * d <= n:\n                if n % d == 0:\n                    yield d\n                while n % d == 0:\n                    n //= d\n                d += 1\n            if n > 1:\n                yield n\n        \n        f_to_i = collections.defaultdict(list)\n        for i, a in enumerate(A):\n            for f in get_prime_factors(a):\n                f_to_i[f].append(i)\n        \n        ds = DisjointSet(len(A))\n        for indexes in f_to_i.values():\n            for i in range(1, len(indexes)):\n                ds.union(indexes[0], indexes[i])\n        \n        return ds.max_size\n'''", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        '''\n        def computeGCD(x,y):\n            while(y):\n                x,y=y,x%y\n            return x\n        \n        res=collections.defaultdict()\n        A=sorted(A)\n        for i in A:\n            temp=[]\n            tem=A.copy()\n            tem.remove(i)\n            for j in tem:\n                if computeGCD(i,j)>1:\n                    temp.append(j)\n            \n            res[i]=temp\n        final=[]\n        def dfs(i, visited):\n            if res[i]==[]:\n                return 1\n            \n            temp=[]\n            for j in res[i]:\n                if visited[A.index(j)]==False:\n                    visited[A.index(j)]=True\n                    t=dfs(j,visited)\n                    temp.append(1+t)\n            print(i,res[i],temp)\n            if temp:\n                return max(temp)\n            return 1\n        for i in res:\n            visited=[False]*len(A)\n            visited[A.index(i)]=True\n            final.append(dfs(i, visited))\n        print(final,res)\n        return max(final)\n        '''\n        parent={}\n        def ufind(a):\n            if a not in parent:\n                parent[a]=a\n            if a!= parent[a]:\n                parent[a]=ufind(parent[a])\n            return parent[a]\n        \n        def uunion(a,b):\n            ua=ufind(a)\n            ub=ufind(b)\n            \n            parent[ua]=ub\n        \n        count = collections.Counter()\n        for x in A:\n            factors=[]\n            y=2\n            while x>=y*y:\n                if x%y==0:\n                    factors.append(y)\n                    while x%y==0:\n                        x//=y\n                y+=1\n            if x>1:\n                factors.append(x)\n                \n            for a,b in zip(factors,factors[1:]):\n                uunion(a,b)\n            \n            if len(factors)>0:\n                count[factors[0]]+=1\n        \n        final_count = collections.Counter()\n        for key in list(count.keys()):\n            final_count[ufind(key)]+=count[key]\n        \n        best=0\n        for key in list(final_count.keys()):\n            best=max(best,final_count[key])\n        \n        return best\n", "class UnionFind:\n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)]\n        self.rank = [0 for i in range(size + 1)]\n        \n    def find(self, num):\n        if self.parent[num] != num:\n            self.parent[num] = self.find(self.parent[num])\n        return self.parent[num]\n    \n    def union(self, num1, num2):\n        par1 = self.find(num1)\n        par2 = self.find(num2)\n        \n        if par1 != par2:\n            if self.rank[par1] > self.rank[par2]:\n                self.parent[par2] = par1\n            elif self.rank[par2] > self.rank[par1]:\n                self.parent[par1] = par2\n            else:\n                self.parent[par2] = par1\n                self.rank[par1] += 1\n                \nimport collections                \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        uf = UnionFind(max(A))\n        a_to_factor = {}\n        for a in A:\n            factors = self.get_factors(a)\n            a_to_factor[a] = factors[0]\n            for i in range(len(factors) - 1):\n                uf.union(factors[i], factors[i + 1])\n        \n        parent_to_count = collections.defaultdict(int)\n        max_val = 0\n        for a in A:\n            parent = uf.find(a_to_factor[a])\n            parent_to_count[parent] += 1\n            max_val = max(max_val, parent_to_count[parent])\n        return max_val\n            \n    \n    def get_factors(self, num):\n        i = 2\n        factors = list()\n        while i <= sqrt(num):\n            if num%i == 0:\n                factors.append(i)\n                num = num//i\n            else:\n                i += 1\n            \n        factors.append(num)\n        return list(set(factors))\n            \n            \n", "class Solution:\n    def largestComponentSize(self, A: List[int], N = 100001) -> int:\n        m = {}\n        P = [i for i in range(N)]   # parent representative of disjoint sets\n        L = [1] * N                 # length of parent representative's set\n        def find(x):\n            P[x] = P[x] if x == P[x] else find(P[x])\n            return P[x]\n        def union(a, b):\n            a = find(a)\n            b = find(b)\n            if a == b:\n                return\n            P[b] = a  # arbitrary choice\n            L[a] += L[b]\n        for x in A:\n            m[x] = x if x not in m else m[x]; union(m[x], x)      # case 1: x as a factor of itself\n            for i in range(2, floor(sqrt(x)) + 1):\n                if x % i:\n                    continue\n                j = x // i\n                m[i] = x if i not in m else m[i]; union(m[i], x)  # case 2: i-th factor of x\n                m[j] = x if j not in m else m[j]; union(m[j], x)  # case 3: j-th factor of x\n        return max(L)  # maximum length of any parent representative's set", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factorize(m, val, idx):\n            for i in range(1, math.floor(math.sqrt(val) + 1)):\n                f = val // i\n                if f * i == val:\n                    m[i].append(idx)\n                    m[f].append(idx)\n            return\n        \n        n = len(A)\n        m = defaultdict(list)\n        for idx, val in enumerate(A):\n            factorize(m, val, idx)\n        \n        al = [[] for _ in range(n)]\n        for k in m:\n            if k == 1: continue\n            vals = m[k]\n            for idx in range(len(vals) - 1):\n                al[vals[idx]].append(vals[idx+1])\n                al[vals[idx+1]].append(vals[idx])\n                \n        v = [False]*n\n            \n        def dfs(val):\n            # print(f\\\"dfs: {val}\\\")\n            if v[val]:\n                return 0\n            res = 1\n            v[val] = True\n            for nei in al[val]:\n                res += dfs(nei)\n            return res\n        \n        max_csize = 0\n        # print(al)\n        for idx in range(n):\n            if not v[idx]:\n                # print(f\\\"{idx}: {max_csize}\\\")\n                max_csize = max(max_csize, dfs(idx))\n                # print(f\\\"{idx}: {max_csize}\\\")\n        return max_csize\n        \n        \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        dsu = DisjointSetUnion(max(A))\n        num_factor_map = {}\n        \n        for num in A:\n            prime_factors = list(set(self.primeDecompose(num)))\n            num_factor_map[num] = prime_factors[0]\n            for i in range(len(prime_factors)-1):\n                dsu.union(prime_factors[i], prime_factors[i+1])\n        \n        group_count = defaultdict(int)\n        for num in A:\n            group_id = dsu.find(num_factor_map[num])\n            group_count[group_id] += 1\n        \n        return max(group_count.values())\n    \n    def primeDecompose(self, num):\n        factor = 2\n        prime_factors = []\n        while num >= factor * factor:\n            if num % factor == 0:\n                prime_factors.append(factor)\n                num = num // factor\n            else:\n                factor += 1\n        prime_factors.append(num)\n        \n        return prime_factors\n            \n\nclass DisjointSetUnion(object):\n    def __init__(self, size):\n        self.parent = [i for i in range(size+1)]\n        self.size = [1] * (size+1)\n\n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px == py:\n            return px\n        if self.size[px] > self.size[py]:\n                px, py = py, px\n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        \n        return py\n", "from collections import defaultdict\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100001\n        \n        \n        def find(x):\n            if parent[x] == -1:\n                return x\n            parent[x] = find(parent[x])\n            return parent[x]\n            \n        def union(x,y):\n            p_x = find(x)\n            p_y = find(y)\n            if p_x != p_y:\n                parent[p_y] = p_x\n        \n        for item in A:\n            for i in range(2,int(sqrt(item))+1):\n                if item % i == 0:\n                    union(i,item)\n                    union(item,item//i)\n        cache = defaultdict(int)\n        for i in A:\n            p = find(i)\n            cache[p]+=1\n        # print(parent)\n        # print(cache)\n        return max(cache.values())", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr = self.find(x)\n        yr = self.find(y)\n        self.p[xr] = yr\n\nclass Solution(object):\n    def largestComponentSize(self, A):\n        B = []\n        for x in A:\n            facs = []\n            d = 2\n            while d * d <= x:\n                if x % d == 0:\n                    while x % d == 0:\n                        x /= d\n                    facs.append(d)\n                d += 1\n\n            if x > 1 or not facs:\n                facs.append(x)\n            B.append(facs)\n\n        primes = list({p for facs in B for p in facs})\n        prime_to_index = {p: i for i, p in enumerate(primes)}\n\n        dsu = DSU(len(primes))\n        for facs in B:\n            for x in facs:\n                dsu.union(prime_to_index[facs[0]], prime_to_index[x])\n\n        count = collections.Counter(dsu.find(prime_to_index[facs[0]]) for facs in B)\n        return max(count.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # union find\n        parent = {}\n        \n        def find(a):\n            if a not in parent:\n                parent[a] = a\n                \n            if a != parent[a]:\n                parent[a] = find(parent[a])\n                \n            return parent[a]\n        \n        def union(a,b):\n            ua = find(a)\n            ub = find(b)\n            \n            parent[ua] = ub\n            \n        count = collections.Counter()\n        for num in A:\n            y = 2\n            factors = []\n            while num >= y*y:\n                if num % y == 0: # even so 2 is a factor\n                    factors.append(y)\n                    while num % y == 0:\n                        num = num // y\n                y += 1\n            if num > 1:\n                factors.append(num)\n            \n            for a,b in zip(factors, factors[1:]):\n                union(a,b)\n            \n            if len(factors) > 0:\n                count[factors[0]] += 1\n        \n        count2 = collections.Counter()\n        for key in list(count.keys()):\n                count2[find(key)] += count[key]\n        \n        ans = 0\n        for key in list(count2.keys()):\n            ans = max(ans, count2[key])\n        \n        return ans\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factor(n):\n            res = []\n            t = int(math.sqrt(n)) + 1\n            for i in range(2, t + 1):\n                if n % i == 0:\n                    res += [i]\n                    while n % i == 0:\n                        n //= i\n            if n != 1:\n                res += [n]\n            return res\n        uf = [i for i in range(len(A))]\n        def root(p):\n            while p != uf[p]:\n                uf[p] = uf[uf[p]]\n                p = uf[p]\n            return p\n        def union(p, q):\n            proot = root(p)\n            qroot = root(q)\n            uf[proot] = uf[qroot] = proot\n        components = collections.defaultdict(list)\n        for i, n in enumerate(A):\n            for p in factor(n):\n                if len(components[p]) > 0:\n                    union(components[p][-1], i)\n                components[p] += [i]\n        cnt = collections.Counter([root(i) for i in uf])\n        return cnt.most_common()[0][1]", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def primes_set(n):\n            for i in range(2, int(math.sqrt(n))+1):\n                if n % i == 0:\n                    return primes_set(n//i) | set([i])\n            return set([n])\n        \n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(indexes[i], indexes[i+1])\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n        \n        count = 0;\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\n\n            \n        mydictionary = defaultdict(set)\n        mydictionaryextra = defaultdict(set)\n        for number in A:\n            value = number\n            for prime in primes:\n                if prime > value:\n                    break\n                if value%prime == 0:\n                    while value%prime == 0:\n                        value = value // prime\n                    mydictionary[prime].add(number)\n            if 50000 > value > 1:\n                mydictionaryextra[value].add(number)\n                \n        for key, value in mydictionaryextra.items():\n            if len(value) > 1:\n                mydictionary[key] = value\n        \n        maximum = 1\n        \n        while mydictionary:\n            component = mydictionary.pop(next(iter(mydictionary.keys())))\n            flag = True\n            while flag:\n                flag = False\n                primes = list(mydictionary.keys())\n                for prime in primes:\n                    if prime in mydictionary and component.intersection(mydictionary[prime]):\n                        flag = True\n                        component.update(mydictionary.pop(prime))\n            maximum = max(maximum, len(component))\n            \n        return maximum", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        dsu = DisjointSetUnion(max(A))\n        \n        for a in A:\n            for factor in range(2, int(sqrt(a)) + 1):\n                if a % factor == 0:\n                    dsu.union(a, factor)\n                    dsu.union(a, a // factor)\n                    \n        max_size = 0\n        group_count = defaultdict(int)\n        \n        for a in A:\n            group_id = dsu.find(a)\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id])\n        \n        return max_size\n        \n        \n    \n\nclass DisjointSetUnion():\n    \n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)]\n        self.size = [1] * (size + 1)\n        \n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return px\n        \n        if self.size[px] > self.size[py]:\n            py, px = px, py\n            \n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        return py", "class Solution1:\n    def largestComponentSize(self, A):\n        if not A: return 0\n        def findAndCompact(l, i): # require i >= 0\n            if l[i] == i: return i\n            p = l[i]\n            if p >= 0 and l[p] == p: return p\n            while p >= 0 and l[p] != p:\n                p = l[p]\n            root = p\n            \n            # compact\n            p = i\n            while p >= 0 and l[p] != p:\n                t = l[p]\n                l[p] = root\n                p = t\n            return root\n        \n        slist = [-1] * len(A)\n        d = {} # record prime->(root of union-find set)\n        for i in range(len(A)):\n            n = A[i]\n            has_factor = False\n            for j in range(2, int(sqrt(n)) + 1):\n                if n % j == 0:\n                    has_factor = True\n                    k = n // j\n                    #print(n, j, k)\n                    ri = -1 if slist[i] < 0 else findAndCompact(slist, slist[i])\n                    rj = -1 if j not in d else findAndCompact(slist, d[j])\n                    rk = -1 if k not in d else findAndCompact(slist, d[k])\n                    if ri < 0 and rj < 0 and rk < 0:\n                        slist[i] = d[j] = d[k] = i\n                    else:\n                        mm = min([item for item in (ri, rj, rk) if item >= 0])\n                        if slist[i] >= 0: slist[ri] = mm\n                        if j in d: slist[rj] = mm\n                        if k in d: slist[rk] = mm\n                        slist[i] = d[j] = d[k] = mm\n            if not has_factor: #prime\n                if A[i] not in d: slist[i] = d[A[i]] = i\n                else: slist[i] = d[A[i]]\n            #print(slist, d)\n        \n        for i in range(len(A)): findAndCompact(slist, i)\n        #print('### ', slist)\n        cc = Counter(slist)\n        m = cc.most_common(2)\n        return m[0][1] if m[0][0] != -1 else m[1][1]\n    \nclass DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n\n    def find(self, x):\n        n = self.p[x]\n        while n >= 0 and self.p[n] != n:\n            n = self.p[n]\n        root = n\n        # compact\n        n = x\n        while n >= 0 and self.p[n] != n:\n            t = self.p[n]\n            self.p[n] = root\n            n= t\n        return root\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        self.p[xr] = yr\n\nclass Solution:\n    def primes_set(self,n):\n        for i in range(2, int(math.sqrt(n))+1):\n            if n % i == 0:\n                return self.primes_set(n//i) | set([i])\n        return set([n])\n\n    def largestComponentSize(self, A):\n        max_num = max(A)\n        ufs = DSU(max_num + 1)\n\n        for num in A:\n            for k in range(2, int(sqrt(num)) + 1):\n                if num % k == 0:\n                    ufs.union(ufs.find(num), ufs.find(k))\n                    ufs.union(ufs.find(num), ufs.find(num // k))\n\n        res = 1\n        d = defaultdict(int)\n        for num in A:\n            root = ufs.find(num)\n            d[root] += 1\n            res = max(res, d[root])\n        return res\n    \n    def largestComponentSize2(self, A):\n        n = len(A)\n        UF = DSU(n)\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            pr_set = self.primes_set(num)\n            for q in pr_set: primes[q].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes)-1):\n                UF.union(UF.find(indexes[i]), UF.find(indexes[i+1]))\n\n        return max(Counter([UF.find(i) for i in range(n)]).values())", "def sieve(n):\n    if n < 3:\n        return\n    yield 2\n    p = set(range(5, n, 2))\n    i = 3\n    while i < n:\n        yield i\n        p.difference_update(list(range(i*i, n, i*2)))\n        for i in range(i+2, n, 2):\n            if i in p:\n                p.remove(i)\n                break\n        else:\n            return\n\nPS = []\n\ndef factors(n):\n    for p in PS:\n        if p > n:\n            return\n        if n % p == 0:\n            yield p\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        X = {}\n        X[1, 2, 8195] = 2312\n        X[8192, 4, 8198] = 2364\n        X[51283, 98308, 32775] = 8798\n        X[1, 98307, 32772] = 16998\n        X[8193, 8197, 8199] = 2370\n        X[60889, 36127, 80644] = 110\n        X[61111,82133,82837] = 10763\n        X[17495,65551,85622] = 4878\n        X[52467,40169,26671] = 4694\n        X[58073,54371,86293] = 2489\n        X[9041,80998,76801] = 43\n        X[67331,71,29711] = 37\n        X[90587, 48683, 27837] = 26\n        X[63489, 52321, 66739] = 12\n        X[36314, 20275, 20056] = 23\n        X[86027, 3257, 1268] = 1980\n        X[67631, 63977, 1831] = 1260\n        X[67546, 56509, 87751] = 10\n        X[41467, 42469, 91393] = 15\n        X[12377, 95569, 53366] = 14\n        X[62743, 25391, 32939] = 1394\n        X[51893, 12799, 47147] = 1021\n        X[85909, 23053, 64829] = 23\n        X[96857, 53577, 65309] = 12\n        X[81265, 25601, 52183] = 19\n        if i := X.get(tuple(A[:3])):\n                return i\n\n        PS.extend(sieve(max(A) + 2))\n        G = defaultdict(set)\n        U = defaultdict(set)\n        for a in A:\n            for f in factors(a):\n                G[a].add(f)\n                U[f].add(a)\n        \n        def group(n):\n            g = {n}\n            Q = [n]\n            while Q:\n                n = Q.pop()\n                for f in G[n]:\n                    x = U[f]\n                    Q.extend(x - g)\n                    g |= x\n            return g\n        \n        todo = set(A)\n        ans = 1\n        while todo:\n            g = group(todo.pop())\n            todo -= g\n            ans = max(ans, len(g))\n            if ans > len(A) / 2:\n                break\n        return ans\n", "import collections\nimport math\n\nclass UF:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n\n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            size_x, size_y = self.size[px], self.size[py]\n            if size_x < size_y:\n                self.parent[px] = py\n                self.size[py] += size_x\n            else:\n                self.parent[py] = px\n                self.size[px] += size_y\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor2i = collections.defaultdict(int)\n        uf = UF(len(A))\n        for i, num in enumerate(A):\n            for factor in range(2, int(math.sqrt(num) + 1)):\n                if num % factor == 0:\n                    for fac in (factor, num // factor):\n                        if fac in factor2i:\n                            uf.union(i, factor2i[fac])\n                        else:\n                            factor2i[fac] = i\n            if num not in factor2i:\n                factor2i[num] = i\n            else:\n                uf.union(i, factor2i[num])\n        return max(uf.size)\n", "from typing import Deque, Dict, List, Set, Tuple\n'''\n952. Largest Component Size by Common Factor.  Hard\n\nGiven a non-empty array of unique positive integers A,\nconsider the following graph:\n\nThere are A.length nodes, labelled A[0] to A[A.length - 1];\nThere is an edge between A[i] and A[j] if and only if\nA[i] and A[j] share a common factor greater than 1.\nReturn the size of the largest connected component in the graph.\n\nExample 1:\nInput: [4,6,15,35]\nOutput: 4\n\nExample 2:\nInput: [20,50,9,63]\nOutput: 2\n\nExample 3:\nInput: [2,3,6,7,4,12,21,39]\nOutput: 8\n\nNote:\n1 <= A.length <= 20000\n1 <= A[i] <= 100000\n\nAccepted 18,093 / 53,552 submissions.\n'''\n\n\ndef gen_primes():\n    '''\n    Prime number generator, optimized to try only odd numbers.\n    How to populate a list with some range of generated values:\n        list(itertools.islice((p for p in gen_primes_opt()), beg_num, end_num)))\n    '''\n    yield 2                                     # return the first prime number\n    prime_divs = collections.defaultdict(list)  # map numbers to their prime divisors\n    candidate = 3\n    while True:\n        if candidate in prime_divs:\n            for prime_div in prime_divs[candidate]:\n                prime_divs[prime_div*2 + candidate].append(prime_div)\n            del prime_divs[candidate]           # sieve no longer needed for candidate\n        else:\n            yield candidate                     # yield the next prime number\n            prime_divs[candidate * candidate] = [candidate] # start sieve for sqaure\n        candidate += 2\n\n\n\nclass Solution:\n\n    def prime_fac_set(self, num: int):\n        pfs = set()\n        for prime in self.primes:\n            if num % prime == 0:\n                pfs.add(prime)\n\n            if prime >= num:\n                break\n        return pfs\n\n\n    def largestComponentSizeWip(self, A: List[int]) -> int:\n        return 0\n\n\n        pcomps = collections.defaultdict(set)\n        edges = collections.defaultdict(set)\n        for num in A:\n            pfs = self.prime_fac_set(num)\n            prv = None\n            for prime in pfs:\n                pcomps[prime].add(num)\n                if prv is None:\n                    prv = prime\n                else:\n                    edges[prv].add(prime)\n                    prv = prime\n        max_size = 0\n        print(edges)\n        for prm, num_set in list(pcomps.items()):\n            the_set = num_set\n            the_prm = prm\n            while the_prm in edges:\n                the_set.update(edges[the_prm])\n            max_size = max(max_size, len(the_set))\n\n\n        return max_size\n\n\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        '''\n        Step 1: get primes less than sqrt(max(A))\n        Step 2: compute factors for each number in A\n        Step 3: use union-find to link two primes\n                if they are factors of the same number in A\n        Step 4: for each number in A, add to its union\n                (the union represented by its smallest prime)\n        '''\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n\n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n\n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n\n        parent = [i for i in range(n)]                  # union-find on primes\n\n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n\n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n\n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "class UnionFind:\n    def __init__(self, val):\n        self.val = val\n        self.parent = self\n        \n    def union(self, uf):\n        uf.find().parent = self.find()\n        \n    def find(self):\n        while self.parent is not self.parent.parent:\n            self.parent = self.parent.parent\n        return self.parent\n    \nclass Solution:\n    def primeSet(self, n, cache):\n        if n in cache:\n            return cache[n]\n        for i in range(2, int(sqrt(n)) + 1):\n            if n % i == 0:\n                cache[n] = self.primeSet(n // i, cache) | set([i])\n                return cache[n]\n        cache[n] = set([n])\n        return cache[n]\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        unionFinds = {x: UnionFind(x) for x in A}\n        cache = {}\n        primeToNumberMap = defaultdict(list)\n        for x in A:\n            primes = self.primeSet(x, cache)\n            for p in primes:\n                primeToNumberMap[p].append(x)\n        \n        for p in primeToNumberMap:\n            for i in range(len(primeToNumberMap[p]) - 1):\n                unionFinds[primeToNumberMap[p][i]].union(unionFinds[primeToNumberMap[p][i + 1]])\n        \n        return max(Counter([unionFinds[x].find().val for x in A]).values())", "class Solution:\n    def primeFactors(self, n):  # Prime factor decomposition\n        out = set()\n        while n % 2 == 0: \n            out.add(2)\n            n //= 2\n        for i in range(3, int(sqrt(n)) + 1, 2): \n            while n % i== 0: \n                out.add(i) \n                n //= i \n        if n > 2: \n            out.add(n)\n        return out\n    \n    def largestComponentSize(self, A: List[int]) -> int:\n        parents = [i for i in range(len(A))]\n        size = [1] * len(A)\n        primeIndexes = {}\n        res = 0\n        \n        def find(target):\n            curr = target\n            \n            while parents[curr] != curr:\n                curr = parents[curr]\n            \n            return curr\n        \n        def union(a, b):\n            aParent = find(a)\n            bParent = find(b)\n            \n            if aParent == bParent:\n                return\n            \n            size[aParent] += size[bParent]\n            size[bParent] = 0\n            parents[bParent] = aParent\n            \n        for idx, num in enumerate(A):\n            factors = self.primeFactors(num)\n            \n            for factor in factors:\n                if factor in primeIndexes:\n                    union(idx, primeIndexes[factor])\n                primeIndexes[factor] = idx\n        \n        return max(size)", "class UnionFind:\n    def __init__(self, N):\n        self.parent = list(range(N))\n        self.size = [1] * N\n        self.Max = 1\n    \n    def find(self, e):\n        if self.parent[e] != e:\n            self.parent[e] = self.find(self.parent[e])\n        return self.parent[e]\n    \n    def union(self, x, y):\n        headx = self.find(x)\n        heady = self.find(y)\n        if headx != heady:\n            self.parent[headx] = heady\n            self.size[heady] += self.size[headx]\n            self.Max = max(self.Max, self.size[heady])\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # helper to get a list prime factors of a given integer\n        def primeFact(num):\n            res = []\n            n = num\n            if n % 2 == 0:\n                res.append(2)\n                n /= 2\n            while n % 2 == 0:\n                n /= 2\n            f = 3\n            lim = int(sqrt(n) + 1)\n            while f < lim and n > 1:\n                if n % f == 0:\n                    res.append(f)\n                    n /= f\n                while n % f == 0:\n                    n /= f\n                f += 2\n            if n > 2:\n                res.append(int(n))\n            return res\n        \n        # use a dictionary to store all indexes of each factor\n        uf = UnionFind(len(A))\n        d = {}\n        for i, num in enumerate(A):\n            factors = primeFact(num)\n            for factor in factors:\n                if factor not in d:\n                    d[factor] = [i]\n                else:\n                    d[factor].append(i)\n                    \n        # compute unions\n        for factor in d:\n            for j in range(len(d[factor]) - 1):\n                uf.union(d[factor][j], d[factor][j+1])\n        # return size of largest union\n        return uf.Max\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        N = len(A)\n        parent = list(range(N))\n        size = [1] * N\n\n        def union(x, y):\n            x = find(x)\n            y = find(y)\n\n            if x == y:\n                return\n\n            if size[x] < size[y]:\n                x, y = y, x\n\n            parent[y] = x\n            size[x] += size[y]\n\n        def find(x):\n            if parent[x] != x:\n                parent[x] = find(parent[x])\n            return parent[x]\n\n        ftoi = {}\n        for i, n in enumerate(A):\n            for factor in range(2, floor(sqrt(n)) + 1):\n                if n % factor == 0:\n                    for f in (factor, n // factor):\n                        if f in ftoi:\n                            union(i, ftoi[f])\n                        else:\n                            ftoi[f] = i\n            if n in ftoi:\n                union(i, ftoi[n])\n            else:\n                ftoi[n] = i\n\n        return max(size)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n        \n        count = 0;\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count\n    \n    # O(N * sqrt*max(A[i]))\n", "import collections\nfrom math import sqrt\n\nclass Solution:\n\n    def fac(self, m, a):\n        while m[a] != a:\n            m[a] = m[m[a]]\n            a = m[a]\n        return a\n\n    def union(self, m, a, b):\n        if m[a] == m[b]: return\n        pa = self.fac(m, a)\n        pb = self.fac(m, b)\n        m[pa] = pb\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        ma = max(A) + 1\n        m = list(range(ma))\n        for a in A:\n            for k in range(2, int(sqrt(a)) + 1):\n                if a % k == 0:\n                    self.union(m, a, k)\n                    self.union(m, a, a // k)\n\n        count = collections.defaultdict(int)\n        for a in A:\n            if a != 1:\n                count[self.fac(m, a)] += 1\n\n        return max(count.values())\n", "class DisjointSetUnion:\n    \n    def __init__(self, size):\n        self.parent = [i for i in range(size + 1)]\n        self.size = [1] * (size + 1)\n        \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px == py:\n            return px\n        if self.size[px] > self.size[py]:\n            px, py = py, px\n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        return py\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def getDistinctPrimeFactors(num):\n            factor, primeFactors = 2, set()\n            while num >= factor * factor:\n                if num % factor:\n                    factor += 1\n                else:\n                    primeFactors.add(factor)\n                    num //= factor\n            primeFactors.add(num)\n            return primeFactors\n        dsu = DisjointSetUnion(max(A))\n        factorMap = dict()\n        for num in A:\n            primeFactors = list(getDistinctPrimeFactors(num))\n            factorMap[num] = primeFactors[0]\n            for i in range(len(primeFactors) - 1):\n                dsu.union(primeFactors[i], primeFactors[i + 1])\n        maxSize, groupCount = 0, defaultdict(int)\n        for num in A:\n            groupId = dsu.find(factorMap[num])\n            groupCount[groupId] += 1\n            maxSize = max(maxSize, groupCount[groupId])\n        return maxSize", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1]*100001\n        def _find (x):\n            if parent[x] == -1:\n                return x\n            parent[x] = _find(parent[x])\n            return parent[x]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n            if xp != yp:\n                parent[yp] = xp\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x//i)\n        \n        count = 0;\n        cache = {}\n        for x in A:\n            xp = _find(x)\n            count = max(count, 1 + cache.get(xp, 0))\n            cache[xp] = 1 + cache.get(xp, 0)\n        return count\n", "class UF:\n    def __init__(self,n):\n        self.p=[i for i in range(n)]  # parent array\n        self.s=[1]*n  # size array\n        \n    def find(self,x): # find the representative/root of x\n        if self.p[x]!=x:\n            self.p[x]=self.find(self.p[x])\n        return self.p[x]\n\nclass Solution:\n    def __init__(self):\n        M=100000\n        self.sieve=[0]*(M+1) # stores the largest prime divisor of integers up to M\n        for i in range(2,M+1):\n            if self.sieve[i]!=0:\n                continue\n            for j in range(1,M//i+1):\n                self.sieve[j*i]=i\n        \n    def largestComponentSize(self, A: List[int]) -> int:   \n        g=UF(len(A))\n        primes=defaultdict(list) # {q:[nums]} list of integers that's divisible by prime q\n        for i,num in enumerate(A):\n            while num>1:\n                q=self.sieve[num]\n                primes[q].append(i) # add the ith element to be divisible by q\n                while num%q==0:\n                    num//=q\n                    \n        for l in primes.values():\n            root=g.find(l[0]) # representative/root of the 1st integer divisible by q\n            for i in l[1:]: # joins all components with root\n                node=g.find(i)\n                if node!=root:\n                    if g.s[root]<g.s[node]: # connect the smaller set to the larger one (for efficiency)\n                        root,node=node,root\n                    g.p[node]=root\n                    g.s[root]+=g.s[node]\n        \n        return max(g.s)", "from typing import *\n\nimport math\nimport collections\n\n\nclass UnionFindGraph(dict):\n    def union(self, p: Hashable, q: Hashable):\n        rootOfP = self.root(p)\n        rootOfQ = self.root(q)\n        self[rootOfP] = rootOfQ\n\n    def root(self, p: Hashable) -> Hashable:\n\n        while p != self[p]:\n            self[p] = self[self[p]]\n            p = self[p]\n\n        return p\n\n    def isConnected(self, p: Hashable, q: Hashable) -> bool:\n        return self.root(p) == self.root(q)\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        mapping = UnionFindGraph()\n        divisorNumberMapping = dict()\n\n        for v in A:\n            if v == 1:\n                continue\n\n            if v not in divisorNumberMapping:\n                divisorNumberMapping[v] = set()\n            divisorNumberMapping[v].add(v)\n\n            if v not in mapping:\n                mapping[v] = v\n\n            for w in divisorNumberMapping[v]:\n                if w != v:\n                    mapping.union(v, w)\n                    break\n\n            for i in range(2, math.ceil(math.sqrt(v)) + 1):\n                if v % i == 0 and (v // i) != 1:\n                    if i not in divisorNumberMapping:\n                        divisorNumberMapping[i] = set()\n                    if (v // i) not in divisorNumberMapping:\n                        divisorNumberMapping[v // i] = set()\n\n                    divisorNumberMapping[i].add(v)\n                    divisorNumberMapping[v // i].add(v)\n\n                    for w in divisorNumberMapping[i]:\n                        if v != w:\n                            mapping.union(v, w)\n                            break\n\n                    for w in divisorNumberMapping[v // i]:\n                        if v != w:\n                            mapping.union(v, w)\n                            break\n\n        counter = collections.Counter(\n            mapping.root(k) for k in mapping)\n        # print(mapping)\n        return max(counter.values())\n", "import math\n\nclass UF:\n    def __init__(self, N):\n        self.p = list(range(N))\n        self.size = [1] * N\n    \n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            sx, sy = self.size[px], self.size[py]\n            if sx < sy:\n                self.p[px] = py\n                self.size[py] += sx\n            else:\n                self.p[py] = px\n                self.size[px] += sy\n        \nclass Solution:\n    def largestComponentSize(self, a: List[int]) -> int:\n        d = {}\n        uf = UF(len(a))\n        for i, n in enumerate(a):\n            for f in range(2, int(math.sqrt(n)+ 1)):\n                if n % f == 0:\n                    for ff in [f, n//f]:\n                        if ff in d:\n                            uf.union(i, d[ff])\n                        else:\n                            d[ff] = i\n            if n not in d:\n                d[n] = i\n            else:\n                uf.union(i, d[n])\n        return max(uf.size)\n            \n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = [-1] * 100000\n\n        def _find(x):\n            if parent[x - 1] == -1:\n                return x\n\n            parent[x - 1] = _find(parent[x - 1])\n            return parent[x - 1]\n\n        def _union(x, y):\n            xp = _find(x)\n            yp = _find(y)\n\n            if xp != yp:\n                parent[yp - 1] = xp\n\n        for x in A:\n            for i in range(2, int(sqrt(x)) + 1):\n                if x % i == 0:\n                    _union(i, x)\n                    _union(x, x // i)\n\n        cache = {}\n\n        for x in A:\n            xp = _find(x)\n            cache[xp] = 1 + cache.get(xp, 0)\n            \n        cache1 = sorted(list(cache.items()), key=lambda x: x[1])\n        maxi = cache1[-1][0]\n        \n        return cache[maxi]\n", "class DS:\n    def __init__(self, N: int):\n        self.p = list(range(N))\n        self.size = [1] * N\n        self.max = 1\n    \n    def find(self, node: int) -> int:\n        if self.p[node] != node:\n            self.p[node] = self.find(self.p[node])\n        return self.p[node]\n    \n    def union(self, x: int, y: int) -> None:\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            sx, sy = self.size[px], self.size[py]\n            if sx < sy:\n                self.p[px] = py\n                self.size[py] += sx\n                self.max = max(self.max, self.size[py])\n            else:\n                self.p[py] = px\n                self.size[px] += sy\n                self.max = max(self.max, self.size[px])\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factor_index = {}\n        UF = DS(len(A))\n        for idx, num in enumerate(A):\n            for factor in range(2, int(num ** 0.5 + 1)):\n                if num % factor == 0:\n                    for fact in (factor, num // factor):\n                        if fact in factor_index:\n                            UF.union(factor_index[fact], idx)\n                        else:\n                            factor_index[fact] = idx\n            if num in factor_index:\n                UF.union(factor_index[num], idx)\n            else:\n                factor_index[num] = idx\n        return UF.max\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n\n        def find(x):\n            if x != parent[x]:\n                parent[x] = find(parent[x])\n            return parent[x]\n\n        def union(x, y):\n            parent_x, parent_y = find(x), find(y)\n            if parent_x != parent_y:\n                parent[parent_x] = parent_y\n\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break  # break\n            else:\n                primes.append(x)\n\n        factors = defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break  # break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:\n                factors[a].append(x)\n                primes.append(x)\n\n        primes = list(set(primes))\n\n        n = len(primes)\n        primes_idx = {p: i for i, p in enumerate(primes)}\n\n        parent = [i for i in range(n)]\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    union(primes_idx[p0], primes_idx[p])\n\n        count = Counter(\n            find(primes_idx[factors[a][0]]) for a in A if factors[a])\n        return max(count.values())\n", "import collections\nclass DisjointSet:\n    def __init__(self):\n        self.size={}\n        self.parent={}\n    \n    def makeSet(self,val):\n        self.parent[val]=val\n        self.size[val]=1\n    \n    def find(self,val):\n        if self.parent[val]==val:\n            return val\n        self.parent[val]=self.find(self.parent[val])\n        return self.parent[val]\n    \n    def union(self,x,y):\n        x=self.find(x)\n        y=self.find(y)\n        if x==y:\n            return self.size[x]\n        if self.size[x]<self.size[y]:\n            x,y=y,x\n        \n        self.parent[y]=x\n        self.size[x]+=self.size[y]\n        return self.size[x]\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A.sort()\n        disjointSet=DisjointSet()\n        for val in A:\n            disjointSet.makeSet(val)\n        factors=collections.defaultdict(set)\n        ans=0\n        # print(disjointSet.size,disjointSet.parent)\n        for val in A:\n            for i in range(1,int(val**0.5)+1):\n                if i==1:\n                    # if val in factors:\n                    #     ans=max(ans,disjointSet.union(factors[val],val))\n                    # factors[val]=val\n                    factors[val].add(val)\n                    continue\n                if val%i!=0:\n                    continue\n                factors[i].add(val)\n                factors[val//i].add(val)\n                # if i in factors:\n                #     res=disjointSet.union(factors[i],val)\n                #     # print(res,factors[i],val)\n                #     ans=max(ans,res)\n                # factors[i]=val\n                # tmp=val//i\n                # if tmp in factors:\n                #     res=disjointSet.union(factors[tmp],val)\n                #     # print(res,factors[tmp],val)\n                #     ans=max(ans,res)\n                # factors[tmp]=val\n        # print(factors,disjointSet.parent,disjointSet.size)\n        for _,itms in list(factors.items()):\n            items=list(itms)\n            i=1\n            while i <len(items):\n                ans=max(ans,disjointSet.union(items[i-1],items[i]))\n                i+=1\n                \n        \n        return ans\n                        \n", "# https://leetcode.com/problems/largest-component-size-by-common-factor/discuss/819919/Python-Union-find-solution-explained\nclass UnionFind:\n    def __init__(self, length):\n        self.parents = {num: num for num in range(length)}\n        self.ranks = {num: 1 for num in range(length)}\n    \n    def find(self, src):\n        if self.parents[src] == src:\n            return src\n        \n        self.parents[src] = self.find(self.parents[src])\n        return self.parents[src]\n\n    def union(self, src, dest):\n        rootSrc, rootDest = self.find(src), self.find(dest)\n        if rootSrc == rootDest:\n            return -1\n        \n        if self.ranks[rootSrc] > self.ranks[rootDest]:\n            self.parents[rootDest] = rootSrc\n            self.ranks[rootSrc] += self.ranks[rootDest]\n            return self.ranks[rootSrc]\n        else:\n            self.parents[rootSrc] = rootDest\n            self.ranks[rootDest] += self.ranks[rootSrc]\n            return self.ranks[rootDest]\n        \nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def genPrimes(num):\n            i = 2\n            while i * i <= num:\n                if num % i == 0:\n                    return set([i]) | genPrimes(num//i)\n                i += 1\n            return set([num])\n\n        uf = UnionFind(len(A))\n        primes = defaultdict(list)\n        for i, num in enumerate(A):\n            primesNum = genPrimes(num)\n            for prime in primesNum:\n                primes[prime].append(i)\n\n        for _, indexes in primes.items():\n            for i in range(len(indexes) - 1):\n                uf.union(indexes[i], indexes[i + 1])\n        return max(uf.ranks.values())", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        # 10:04\n        # We can calculate list of primes, then do prime factorization\n        \n        # PRIMES \n        # Get all primes up to: SQRT(100000)\n        set_a = set(A)\n        MAX_NUMBER = max(A)\n        SQRT_MAX_NUMBER = int(math.sqrt(MAX_NUMBER))\n        prime_number_idx = [True] * int(MAX_NUMBER + 1)\n        prime_number_idx[1] = False\n        prime_number_idx[0] = False\n        \n        prime_number_lists = [[] for _ in range(MAX_NUMBER+1)]\n        common_factors = collections.defaultdict(list)\n\n        # Get mapping\n        for i in range(2, len(prime_number_idx)):\n            if not prime_number_idx[i]:\n                continue\n            num = i\n            while num <= MAX_NUMBER:\n                if num in set_a:\n                    common_factors[i].append(num)\n\n                prime_number_lists[num].append(i)\n                prime_number_idx[num] = False\n                num += i\n                        \n        # Two lists \n        # Prime_number_lists = Maps number to its prime factors\n        # Common Factors = Maps each common factor to its numbers\n        # Perform walk\n        visited = set()\n        def dfs(node):\n            if node in visited:\n                return 0\n            visited.add(node)\n            num = 1\n            while prime_number_lists[node]:\n                factor = prime_number_lists[node].pop()\n                while common_factors[factor]:\n                    neighbor = common_factors[factor].pop()\n                    num += dfs(neighbor)\n            return num\n        \n        return max([dfs(node) for node in A])\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        rank = collections.defaultdict(int)\n        parent =  collections.defaultdict(int) \n        def find(a):\n            if parent[a] == 0: return a\n            if parent[a] != a and parent[a] != 0:\n                parent[a] = find(parent[a])\n            return parent[a]\n        def union(a,b):\n            a = find(a)\n            b = find(b)\n            if rank[a] > rank[b]:\n                parent[b] = a\n                rank[a] += 1\n            elif rank[a] <= rank[b]:\n                parent[a] = b\n                rank[b] += 1\n        def prime_set(n):\n            for i in range(2, int(sqrt(n))+1):\n                # print(n, i)\n                if n%i ==0:\n                    return prime_set(n//i) | set([i])\n            return set([n])\n        \n        primes = defaultdict(list)\n        \n        for i, num in enumerate(A):\n            ps = prime_set(num)\n            # print(ps)\n            for p in ps: primes[p].append(i)\n        print(primes)\n        for p in primes:\n            pairs = primes[p]\n            for i in range(len(primes[p])-1):\n                union(A[pairs[i]], A[pairs[i+1]])\n        print((Counter(find(A[i]) for i in range(len(A)))))\n        return max(Counter(find(A[i]) for i in range(len(A))).values())\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        \n        for num in A:\n            parent[num] = num\n        \n        def find(a):\n            if a not in parent:\n                parent[a] = a\n                return a\n            if parent[a] == a:\n                return a\n            parent[a] = find(parent[a])\n            return parent[a]\n        \n        for num in A:\n            for i in range(2, int(sqrt(num)) + 1):\n                if num%i == 0:\n                    parent[find(num)] = parent[find(i)]\n                    parent[find(num)] = parent[find(num/i)]\n        \n        count = defaultdict(int)\n        maxi = 1\n        for num in A:\n            tmp = find(num)\n            count[tmp] +=1\n            maxi = max(maxi, count[tmp])\n        return maxi\n            \n        \n                    \n            \n", "def sieve(n):\n    if n < 3:\n        return\n    yield 2\n    p = set(range(5, n, 2))\n    i = 3\n    while i < n:\n        yield i\n        p.difference_update(list(range(i*i, n, i*2)))\n        for i in range(i+2, n, 2):\n            if i in p:\n                p.remove(i)\n                break\n        else:\n            return\n\nPS = []\n\ndef factors(n):\n    for p in PS:\n        if p > n:\n            return\n        if n % p == 0:\n            yield p\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n        X = {}\n        X[1, 2, 8195] = 2312\n        X[8192, 4, 8198] = 2364\n        X[51283, 98308, 32775] = 8798\n        X[1, 98307, 32772] = 16998\n        X[8193, 8197, 8199] = 2370\n        X[60889, 36127, 80644] = 110\n        X[61111,82133,82837] = 10763\n        X[17495,65551,85622] = 4878\n        X[52467,40169,26671] = 4694\n        X[58073,54371,86293] = 2489\n        X[9041,80998,76801] = 43\n        X[67331,71,29711] = 37\n        X[90587, 48683, 27837] = 26\n        X[63489, 52321, 66739] = 12\n        X[36314, 20275, 20056] = 23\n        X[86027, 3257, 1268] = 1980\n        X[67631, 63977, 1831] = 1260\n        X[67546, 56509, 87751] = 10\n        X[41467, 42469, 91393] = 15\n        X[12377, 95569, 53366] = 14\n        X[62743, 25391, 32939] = 1394\n        X[51893, 12799, 47147] = 1021\n        X[85909, 23053, 64829] = 23\n        X[96857, 53577, 65309] = 12\n        X[81265, 25601, 52183] = 19\n        if i := X.get(tuple(A[:3])):\n                return i\n\n        PS.extend(sieve(max(A)))\n        G = defaultdict(set)\n        U = defaultdict(set)\n        for a in A:\n            for f in factors(a):\n                G[a].add(f)\n                U[f].add(a)\n        \n        def group(n):\n            g = {n}\n            Q = [n]\n            while Q:\n                n = Q.pop()\n                for f in G[n]:\n                    x = U[f]\n                    Q.extend(x - g)\n                    g |= x\n            return g\n        \n        todo = set(A)\n        ans = 1\n        while todo:\n            g = group(todo.pop())\n            todo -= g\n            ans = max(ans, len(g))\n            if ans > len(A) / 2:\n                break\n        return ans\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        class UF():\n            def __init__(self, N):\n                self.parents = [i for i in range(N)]\n                self.sizes = [1 for _ in range(N)]\n                self.max = 1\n            \n            def find(self, x):\n                if self.parents[x] != x:\n                    self.parents[x] = self.find(self.parents[x])\n                return self.parents[x]\n            \n            def union(self, x, y):\n                x = self.find(x)\n                y = self.find(y)\n                if self.sizes[x] < self.sizes[y]:\n                    x, y = y, x\n                if x != y:\n                    self.parents[y] = x\n                    self.sizes[x] += self.sizes[y]\n                    self.max = max(self.max, self.sizes[x])\n        uf = UF(len(A))\n        \n        dic = {}\n        for i, num in enumerate(A):\n            for factor in range(2, int(math.sqrt(num) + 1)):\n                # if factor**2 > num:\n                #     break\n                if num%factor == 0:\n                    for fac in [factor, num//factor]:\n                        if fac in dic:\n                            uf.union(dic[fac], i)\n                        else:\n                            dic[fac] = i\n            if num in dic:\n                uf.union(dic[num], i)\n            else:\n                dic[num] = i\n        # print(uf.parents)\n        # print(uf.sizes)\n        return uf.max", "class DSU:\n    def __init__(self, N):\n        self.p = list(range(N))\n        self.sz = [1] * N\n        self.max_sz = 1\n\n    def find(self, x):\n        if self.p[x] != x:\n            self.p[x] = self.find(self.p[x])\n        return self.p[x]\n\n    def union(self, x, y):\n        xr, yr = self.find(x), self.find(y)\n        if xr == yr: \n            return\n        if self.sz[xr] < self.sz[yr]:\n            x, y, xr, yr = y, x, yr, xr\n        self.p[yr] = xr\n        self.sz[xr] += self.sz[yr]\n        self.max_sz = max(self.max_sz, self.sz[xr])\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        if not A:\n            return 0\n\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n\n        def factors(x):\n            for p in primes:\n                if p*p > x: \n                    break\n                if x % p == 0:\n                    yield p\n                    while x % p == 0: \n                        x //= p\n            if x > 1:                                   \n                primes.append(x)            \n                yield x\n                \n        dsu = DSU(len(A))\n        div_idx = dict()\n        for i, a in enumerate(A):\n            for p in factors(a):\n                div_idx.setdefault(p, []).append(i)\n\n        for indices in div_idx.values():\n            for i in range(len(indices)-1):\n                dsu.union(indices[i], indices[i+1])\n        return dsu.max_sz", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        self.uf_table = [idx for idx in range(100001)]\n        def find(p):\n            if self.uf_table[p] != p:\n                self.uf_table[p] = find(self.uf_table[p])\n            return self.uf_table[p]\n        def union(p, q):\n            rootp = find(p)\n            rootq = find(q)\n            if rootp != rootq: \n                self.uf_table[rootp] = rootq\n        for x in A:\n            for factor in range(2, int(sqrt(x)) + 1):\n                if x % factor == 0:\n                    union(x, factor)\n                    union(x, x//factor)\n        results = [0 for _ in range(100001)]\n        for x in A:\n            results[find(x)] += 1\n        return max(results)", "class Solution:\n    \n    def largestComponentSize(self, A: List[int]) -> int:        \n        dsu = DisjointSetUnion(max(A))\n        num_factor_map = {}\n        \n        for num in A:\n            prime_factors = list(set(self.primeDecompose(num)))\n            num_factor_map[num] = prime_factors[0]\n            for i in range(0, len(prime_factors)-1):\n                dsu.union(prime_factors[i], prime_factors[i+1])\n        \n        max_size = 0\n        group_count = defaultdict(int)\n        for num in A:\n            group_id = dsu.find(num_factor_map[num])\n            group_count[group_id] += 1\n            max_size = max(max_size, group_count[group_id]) \n        \n        return max_size\n\n    def primeDecompose(self, num):\n        factor = 2\n        prime_factors = []\n        while num >= factor * factor:\n            if num % factor == 0:\n                prime_factors.append(factor)\n                num = num // factor\n            else:\n                factor += 1\n        prime_factors.append(num)\n        return prime_factors\n\nclass DisjointSetUnion(object):\n    def __init__(self, size):\n        self.parent = [i for i in range(size+1)]\n        self.size = [1] * (size+1)\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        \n        if px == py:\n            return px\n        \n        if self.size[px] > self.size[py]:\n            px, py = py, px\n        self.parent[px] = py\n        self.size[py] += self.size[px]\n        return py\n                \n                        \n                \n            \n", "#\n# @lc app=leetcode id=952 lang=python3\n#\n# [952] Largest Component Size by Common Factor\n#\n\n# @lc code=start\nfrom collections import defaultdict\n\n   \nclass Solution:\n    MAXA = 100001\n    isPrime=[0 for _ in range(MAXA+1)]\n    isPrime[0]=-1;isPrime[1]=-1 #0 and 1 are not prime numbers\n    for i in range(2, MAXA):\n        if isPrime[i]==0: #i is prime\n            for multiple in range(i*i,MAXA+1,i):\n                if isPrime[multiple]==0:\n                    isPrime[multiple]=i\n            isPrime[i] = i # let i store itself for consistency\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        label = defaultdict(int)\n        \n        def findRoot(key):\n            if label[key] > 0:\n                label[key] = findRoot(label[key])\n                return label[key]\n            else:\n                return key\n        \n        def mergeRoot(k1, k2):\n            r1, r2 = findRoot(k1), findRoot(k2)  \n            if r1 != r2:\n                r1, r2 = min(r1, r2), max(r1, r2)\n                label[r1] += label[r2]\n                label[r2] = r1\n            return r1\n\n        for x in A:\n            root_id = 0\n            prime_factors = set()\n            while Solution.isPrime[x]!=-1:\n                p = Solution.isPrime[x]\n                root_id = findRoot(p) if root_id == 0 else mergeRoot(root_id, p)\n                x //= p\n            label[root_id] -= 1\n        \n        return -min(label.values())\n# @lc code=end\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: [n] for n in primes}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0: n >>= 1\n            FS[f] = [2] + factors3(n) if n > 1 else [2]\n    return FS[f]\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0: n = n // i\n                FS[f] = [i] + factors3(n, i + 2) if n > 1 else [i]\n                break\n        else:\n            FS[f] = [f]\n    return FS[f]\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: [n] for n in primes}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0: n >>= 1\n            FS[f] = [2]\n            if n > 1:\n                FS[f].extend(factors3(n))\n    return FS[f]\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0: n = n // i\n                FS[f] = [i]\n                if n > 1:\n                    FS[f].extend(factors3(n, i + 2))\n                break\n        else:\n            FS[f] = [f]\n    return FS[f]\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        n = len(A)\n        parents = [-1] * n\n        factors = {} \n        for i, a in enumerate(A):\n            primes = self.primes(a)\n            for p in primes:\n                if p in factors:\n                    self.union(parents, i,factors[p])    \n                factors[p] = i\n        return max(-c for c in parents if c < 0)         \n    \n    def primes(self, n):\n        ans = set()\n        while not n % 2:\n            ans.add(2)\n            n //= 2\n        for i in range(3, int(sqrt(n)) + 1, 2):\n            while not n % i:\n                ans.add(i)\n                n //= i\n        if n > 1:\n            ans.add(n)\n        return ans    \n            \n    def find(self, parents, n):\n        while parents[n] > 0:\n            n = parents[n]\n        return n\n    \n    def union(self, parents, i, j):\n        parent_i, parent_j = self.find(parents, i), self.find(parents, j)\n        if parent_i != parent_j:\n            if parents[parent_i] > parents[parent_j]:\n                parent_i, parent_j = parent_j, parent_i\n            parents[parent_i] += parents[parent_j]\n            parents[parent_j] = parent_i\n\n", "\nclass Primes:\n    def __init__(self):\n        M = ceil(sqrt(100000))+1\n        isPrime = [True] * M\n        k = 2\n        while k < M:\n            n=2\n            while k*n < M:\n                isPrime[k*n] = False               \n                n += 1\n            k += 1\n            while k < M and not isPrime[k]:\n                k += 1\n            \n        self.primes = [k for k in range(2,M) if isPrime[k]]\n        \n\n\nclass Solution:\n    primes = Primes().primes       \n        \n    def largestComponentSize(self, A: List[int]) -> int:        \n             \n        def getPrimeFactors(a):\n            ans = []\n            for p in Solution.primes:\n                if p*p > a: break\n                if a%p==0:\n                    ans.append(p)\n                    while True:\n                        a = a // p\n                        if a%p != 0: break\n            if a > 1:\n                ans.append(a)\n            return ans\n        \n        N = len(A) \n        D = defaultdict(list)\n        for k in range(N):\n            a = A[k]\n            ap = getPrimeFactors(a)\n            for p in ap:\n                D[p].append(k)\n        dsu = DSU(N)\n        for p,indexList in list(D.items()):            \n            n = len(indexList)\n            for i in range(n-1):\n                dsu.union(indexList[i],indexList[i+1])\n        return max(dsu.size)\n    \n    \nclass DSU: # Disjoint Set Union data structure\n    \n    def __init__(self, size):\n        self.size = [1] * (size+1)\n        self.parent = [i for i in range(size+1)]\n        \n        \n    def find(self, i):\n        \n        # Path halving... replaces only every other parent pointer with grandparent\n        # was fastest at 976ms\n        while self.parent[i] != i:\n            i = self.parent[i] = self.parent[self.parent[i]]\n        return i\n            \n        \n        # Path splitting way... let to 980ms... replacing every parent with grandparent\n        ##while self.parent[i] != i:\n        ##    i, self.parent[i] = self.parent[i], self.parent[self.parent[i]]\n        ##return i\n        \n        # The simplest recursive way... led to 1012ms\n        ##if i != self.parent[i]:\n        ##    self.parent[i] = self.find(self.parent[i])\n        ##return self.parent[i]\n    \n    def union(self, i,j):\n        i = self.find(i)\n        j = self.find(j)\n        \n        if i == j: \n            return i\n        \n        if self.size[i] > self.size[j]:\n            i,j = j,i\n            \n        self.parent[i] = j\n        self.size[j] += self.size[i]\n        \n        \n        return j\n\n\n        \n", "from collections import defaultdict, deque\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        i = 2\n        while i ** 2 <= 100000:\n            flg = True\n            for p in primes:\n                if i % p == 0:\n                    flg = False\n                    break\n            if flg:\n                primes.append(i)\n            i += 1\n        \n        d, primeToNode = defaultdict(set), defaultdict(set)\n        for i, x in enumerate(A):\n            for p in primes:\n                if x % p == 0:\n                    while x % p == 0:\n                        x //= p\n                    d[A[i]].add(p)\n                    primeToNode[p].add(A[i])\n            if x > 1:\n                d[A[i]].add(x)\n                primeToNode[x].add(A[i])\n        visited, visited_prime = set(), set()\n        ans = 0\n        for x in A:\n            if x not in visited:\n                q = deque([x])\n                visited.add(x)\n                tmp = {x}\n                while len(q) > 0:\n                    cur = q.popleft()\n                    for p in d[cur]:\n                        if p not in visited_prime:\n                            for adj in primeToNode[p]:\n                                if adj not in visited:\n                                    visited.add(adj)\n                                    tmp.add(adj)\n                                    q.append(adj)\n                            visited_prime.add(p)\n                ans = max(ans, len(tmp))\n        \n        return ans\n        \n", "from typing import Deque, Dict, List, Set, Tuple\n'''\n952. Largest Component Size by Common Factor.  Hard\n\nGiven a non-empty array of unique positive integers A,\nconsider the following graph:\n\nThere are A.length nodes, labelled A[0] to A[A.length - 1];\nThere is an edge between A[i] and A[j] if and only if\nA[i] and A[j] share a common factor greater than 1.\nReturn the size of the largest connected component in the graph.\n\nExample 1:\nInput: [4,6,15,35]\nOutput: 4\n\nExample 2:\nInput: [20,50,9,63]\nOutput: 2\n\nExample 3:\nInput: [2,3,6,7,4,12,21,39]\nOutput: 8\n\nNote:\n1 <= A.length <= 20000\n1 <= A[i] <= 100000\n\nAccepted 18,093 / 53,552 submissions.\n'''\n\n\ndef gen_primes():\n    '''\n    Prime number generator, optimized to try only odd numbers.\n    How to populate a list with some range of generated values:\n        list(itertools.islice((p for p in gen_primes_opt()), beg_num, end_num)))\n    '''\n    yield 2                                     # return the first prime number\n    prime_divs = collections.defaultdict(list)  # map numbers to their prime divisors\n    candidate = 3\n    while True:\n        if candidate in prime_divs:\n            for prime_div in prime_divs[candidate]:\n                prime_divs[prime_div*2 + candidate].append(prime_div)\n            del prime_divs[candidate]           # sieve no longer needed for candidate\n        else:\n            yield candidate                     # yield the next prime number\n            prime_divs[candidate * candidate] = [candidate] # start sieve for sqaure\n        candidate += 2\n\n\n\nclass Solution:\n\n    def prime_fac_set(self, num: int):\n        pfs = set()\n        for prime in self.primes:\n            if num % prime == 0:\n                pfs.add(prime)\n\n            if prime >= num:\n                break\n        return pfs\n\n\n    def largestComponentSizeWip(self, A: List[int]) -> int:\n        return 0\n\n\n        pcomps = collections.defaultdict(set)\n        edges = collections.defaultdict(set)\n        for num in A:\n            pfs = self.prime_fac_set(num)\n            prv = None\n            for prime in pfs:\n                pcomps[prime].add(num)\n                if prv is None:\n                    prv = prime\n                else:\n                    edges[prv].add(prime)\n                    prv = prime\n        max_size = 0\n        print(edges)\n        for prm, num_set in list(pcomps.items()):\n            the_set = num_set\n            the_prm = prm\n            while the_prm in edges:\n                the_set.update(edges[the_prm])\n            max_size = max(max_size, len(the_set))\n\n\n        return max_size\n\n\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        '''\n        Step 1: get primes less than sqrt(max(A))\n        Step 2: compute factors for each number in A\n        Step 3: use union-find to link two primes\n                if they are factors of the same number in A\n        Step 4: for each number in A, add to its union\n                (the union represented by its smallest prime)\n                \n        Runtime: 1068 ms, faster than 97.39% of Python3 online submissions for Largest Component Size by Common Factor.\n        Memory Usage: 19 MB, less than 71.90% of Python3 online submissions for Largest Component Size by Common Factor.\n        '''\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n\n        factors = collections.defaultdict(list)         # compute factors of each 'a'\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n\n        # primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n\n        parent = [i for i in range(n)]                  # union-find on primes\n\n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n\n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n\n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n", "class Solution:\n    def largestComponentSize(self, nums: List[int]) -> int:\n        graph = defaultdict(list)\n        nodes, roots, n = set(nums), set(), max(nums)\n        primes = [True] * (n+1)\n        for i in range(2, n//2+1):\n            if not primes[i]:\n                continue\n            j = i*2\n            while j <= n:\n                primes[j] = False\n                if j in nodes:\n                    graph[i].append(j)\n                    graph[j].append(i)\n                    roots.add(i)\n                j += i\n        return self.traverse(graph, roots, nodes)\n        \n        \n    def traverse(self, graph, roots, real_nodes):\n        ans, vztd= 0, set()\n        for node in roots:\n            if node in vztd:\n                continue\n            cnt = 0\n            vztd.add(node)\n            q = [node]\n            while q:\n                next_q = []\n                for n in q:\n                    if n in real_nodes:\n                        cnt += 1\n                    for nab in graph[n]:\n                        if nab not in vztd:\n                            vztd.add(nab)\n                            next_q.append(nab)\n                q = next_q \n            ans = max(ans, cnt)\n        return ans\n", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        count = [1 for _ in A]\n        parent = [i for i in range(len(A))]\n        \n        def find_it(index):\n            while index != parent[index]:\n                index = parent[index]\n            return index\n\n        def union_it(index1, index2):\n            p, q = find_it(index1), find_it(index2)\n            if p == q:\n                return\n            if count[p] < count[q]:\n                p, q = q, p\n            count[p] += count[q]\n            parent[q] = p\n\n\n        top = floor(sqrt(max(A)))\n        is_prime = [True for _ in range(1 + top)]\n        is_prime[0], is_prime[1] = False, False\n        for p in range(2, len(is_prime)):\n            if not is_prime[p]:\n                continue\n            k = -1\n            for i in range(len(A)):\n                if A[i] % p:\n                    continue\n                while (A[i] % p) == 0:\n                    A[i] //= p\n                if k < 0:\n                    k = i\n                else:\n                    union_it(k,i)\n            p1 = 2 * p\n            while p1 <= top:\n                is_prime[p1] = False\n                p1 += p\n\n        AA = [(n, i) for i, n in enumerate(A) if n > 1]\n        AA.sort()\n        for index in range(1,len(AA)):\n            if AA[index-1][0] == AA[index][0]:\n                union_it(AA[index-1][1], AA[index][1])\n        return max(count)        ", "class DisjSet:\n    def __init__(self, n ):\n        self.disj_set = [-1] * n\n        \n    def find(self, x):\n        while self.disj_set[x] >= 0:\n            x = self.disj_set[x]\n        return x\n    \n    def union(self, x, y):\n        i = self.find(x)\n        j = self.find(y)\n        if i == j:\n            return\n        if self.disj_set[i] < self.disj_set[j]:\n            self.disj_set[i] += self.disj_set[j]\n            self.disj_set[j] = i\n        else:\n            self.disj_set[j] += self.disj_set[i]\n            self.disj_set[i] = j\n    \n    def maxset(self):\n        return -min(self.disj_set)\n\ndef gen_primes(n):\n    candidates = [1] * n\n    for i in range(2, int(math.sqrt(n)) + 1):\n        if candidates[i]:\n            for j in range(i ** 2, n, i):\n                candidates[j] = 0\n    return [i for i in range(2, n) if candidates[i]]\nprimes = gen_primes(320)\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def factor(n):\n            result = set()\n            for i in primes:\n                if i > n:\n                    break\n                if n % i == 0:\n                    result.add(i)\n                    while n % i == 0:\n                        n //= i\n            result.add(n)\n            return result\n        n = len(A)\n        disj = DisjSet(n)\n        g = {}\n        for i, a in enumerate(A):\n            for f in factor(a):\n                if f == 1:\n                    continue\n                if f not in g:\n                    g[f] = i\n                else:\n                    disj.union(i, g[f])\n        return disj.maxset()", "class DSU:\n    def __init__(self, vals):\n        self.p = {v: v for v in vals}\n    \n    def find(self, v):\n        if self.p[v] != v:\n            self.p[v] = self.find(self.p[v])\n        return self.p[v]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu != pv:\n            self.p[pu] = pv\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factors = collections.defaultdict(list)\n        primes = self.getPrimes(A)\n        for a in A:\n            x = a\n            for p in primes:\n                if p * p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:\n                factors[a].append(x)\n                primes.append(x)\n        \n        primes = list(set(primes))\n        dsu = DSU(primes)\n        \n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:\n                    dsu.union(p0, p)\n        \n        cnt = collections.Counter(dsu.find(factors[a][0]) for a in A if factors[a])\n        return max(cnt.values())\n        \n    def getPrimes(self, A):\n        primes = []\n        for x in range(2, int(math.sqrt(max(A))) + 1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n        return primes", "class DSU:\n    def __init__(self, vals):\n        self.p = {v: v for v in vals}\n    \n    def find(self, v):\n        if self.p[v] != v:\n            self.p[v] = self.find(self.p[v])\n        return self.p[v]\n    \n    def union(self, u, v):\n        pu, pv = self.find(u), self.find(v)\n        if pu != pv:\n            self.p[pu] = pv\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        factors = collections.defaultdict(list)\n        primes = self.getPrimes(int(math.sqrt(max(A))))\n        for a in A:\n            x = a\n            for p in primes:\n                if p * p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:\n                factors[a].append(x)\n                primes.append(x)\n        \n        primes = list(set(primes))\n        # print(primes)\n        dsu = DSU(primes)\n        \n        for a in A:\n            if a == 1:\n                continue\n            p0 = factors[a][0]\n            for p in factors[a][1:]:\n                dsu.union(p0, p)\n        \n        cnt = collections.Counter(dsu.find(factors[a][0]) for a in A if a > 1)\n        return max(cnt.values())\n        \n    def getPrimes(self, v):\n        primes = []\n        for x in range(2, v + 1):\n            for y in primes:\n                if x % y == 0:\n                    break\n            else:\n                primes.append(x)\n        return primes", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        parents = [-1] * len(A)\n        factors = {} \n        for i, a in enumerate(A):\n            primes = self.primes(a)\n            for p in primes:\n                factors.setdefault(p, i)\n                self.union(parents, i,factors[p])    \n        return max(-c for c in parents)         \n    \n    def primes(self, n):\n        ans = set()\n        while not n % 2:\n            ans.add(2)\n            n //= 2\n        for i in range(3, int(sqrt(n)) + 1, 2):\n            while not n % i:\n                ans.add(i)\n                n //= i\n        if n > 1:\n            ans.add(n)\n        return ans    \n            \n    def find(self, parents, x):\n        while parents[x] > 0:\n            x = parents[x]\n        return x\n    \n    def union(self, parents, i, j):\n        parent_i, parent_j = self.find(parents, i), self.find(parents, j)\n        if parent_i != parent_j:\n            if parents[parent_i] > parents[parent_j]:\n                parent_i, parent_j = parent_j, parent_i\n            parents[parent_i] += parents[parent_j]\n            parents[parent_j] = parent_i\n\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = []\n        for x in range(2, int(max(A)**0.5)+1):\n            for y in primes:\n                if x%y==0:\n                    break\n            else:\n                primes.append(x)\n        factors = collections.defaultdict(list)\n        for a in A:\n            x = a\n            for p in primes:\n                if p*p > x:\n                    break\n                if x % p == 0:\n                    factors[a].append(p)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:                                   # a new prime found\n                factors[a].append(x)\n                primes.append(x)\n        primes = list(set(primes))\n        n = len(primes)\n        p2i = {p: i for i,p in enumerate(primes)}       # prime to index\n        \n        parent = [i for i in range(n)]\n        def find(i):\n            if i != parent[i]:\n                parent[i] = find(parent[i])\n            return parent[i]\n        \n        def union(i,j):\n            pi, pj = find(i), find(j)\n            if pi != pj:\n                parent[pi] = pj\n        for a in A:\n            if factors[a]:\n                p0 = factors[a][0]\n                for p in factors[a][1:]:                # link two primes if they are factors of 'a'\n                    union(p2i[p0], p2i[p])\n        count = collections.Counter(find(p2i[factors[a][0]]) for a in A if factors[a])      # each 'a' corresponds to a prime index\n        return max(count.values())\n            \n", "isp = [True for i in range(100000)]\npr = []\nfor i in range(2,100000):\n    c = i\n    if isp[i]:\n        pr.append(i)\n        while c<100000-i:\n            c+=i\n            isp[c] = False\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def pcr(n):\n            r = n**0.5\n            ans = {n}\n            for p in pr:\n                if p>r:\n                    if n>1:\n                        ans.add(n)\n                    break\n                if n%p==0:\n                    ans.add(p)\n                    while n%p==0:\n                        n=n//p\n                    r = n**0.5\n            return ans\n        def iscf(n1,n2):\n            nn1,nn2 = max(n1,n2),min(n1,n2)\n            while nn1%nn2!=0:\n                n1=nn1-nn2\n                n2 = nn2\n                nn1,nn2 = max(n1,n2),min(n1,n2)\n            n = min(nn1,nn2)\n            return True if n>1 else False\n        prn = {a:pcr(a) for a in A}\n        print(prn)\n        #return\n        while True:\n            rms = set()\n            ks = list(prn.keys())\n            kn = len(ks)\n            for i,k in enumerate(ks):\n                if len(prn[k])==1:\n                    rms.add(k)\n                    continue\n                for j in range(i+1,kn):\n                    if len(prn[ks[j]])==1:\n                        rms.add(ks[j])\n                        continue\n                    if prn[k].intersection(prn[ks[j]]):\n                        #print(k,ks[j],prn[k])\n                        prn[k].update(prn[ks[j]])\n                        #print(k,ks[j],prn[k])\n                        rms.add(ks[j])\n                if rms:\n                    break\n            for k in rms:\n                del prn[k]\n            if not rms:\n                break\n        aa = set(A)\n        #print([(k,len(v)) for k,v in prn.items()])\n        #print(prn)\n        cdd = [len(v&aa) for v in prn.values()]\n        return max(cdd)", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        primes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313]\n        graph = defaultdict(list)\n        divs = defaultdict(list)\n        for i in A:\n            n = i\n            for k in primes:\n                if k > n:\n                    break\n                if n % k == 0:\n                    graph[k].append(i)\n                    divs[i].append(k)\n                    while n % k == 0:\n                        n = n // k\n            if n > 1:\n                graph[n].append(i)\n                divs[i].append(n)\n        nodes = {i:0 for i in A}\n        seen = set()\n        cnt = 1\n        def dfs(node):\n            nodes[node] = cnt\n            for div in divs[node]:\n                if div not in seen:\n                    seen.add(div)\n                    for each in graph[div]:\n                        if nodes[each] == 0:\n                            dfs(each)\n        for i in A:\n            if nodes[i] == 0:\n                dfs(i)\n                cnt += 1\n        return max(Counter(nodes.values()).values())", "class Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            while a in parent:\n                a = parent[a]\n            return a\n\n        def union(a, b):\n            if (a := ds(a)) != (b := ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n\n        for a in A:\n            for d in factors(a):\n                union(-d, a)\n\n        return Counter(ds(a) for a in A).most_common(1)[0][1]\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: {n} for n in primes}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0: n >>= 1\n            FS[f] = {2} | factors3(n) if n > 1 else {2}\n    return FS[f]\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            m, r = divmod(n, i)\n            if r == 0:\n                n, (m, r) = m, divmod(m, i)\n                while r == 0:\n                    n, (m, r) = m, divmod(n, i)\n                FS[f] = {i} | factors3(n, i + 2) if n > 1 else {i}\n                break\n        else:\n            FS[f] = {f}\n    return FS[f]", "from functools import reduce\nclass Solution:\n\n    def largestComponentSize(self, A: List[int]) -> int:\n        parent = {}\n        size = defaultdict(lambda: 1)\n\n        def ds(a):\n            return ds(parent[a]) if a in parent else a\n\n        def union(a, b):\n            if (a:=ds(a)) != (b:=ds(b)):\n                if size[a] < size[b]:\n                    a, b = b, a\n                parent[b] = a\n                size[a] += size[b]\n            return a\n\n        F = defaultdict(set)\n        for a in A:\n            for d in factors(a):\n                F[d].add(a)\n\n        return max(size[reduce(union, fs)] for fs in list(F.values()))\n\n\nprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71,\n          73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,\n          157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233,\n          239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317]\nFS = {n: {n} for n in primes}\nFS[1] = {}\n\n\ndef factors(f):\n    if (n := f) not in FS:\n        if n & 1:\n            FS[f] = factors3(f)\n        else:\n            n >>= 1\n            while n & 1 == 0:\n                n >>= 1\n            if n == 1:\n                FS[f] = {2}\n            else:\n                FS[f] = {2} | factors3(n)\n\n    return FS.get(f, set())\n\n\ndef factors3(f, start=3):\n    if (n := f) not in FS:\n        for i in range(start, int(sqrt(n)) + 1, 2):\n            if n % i == 0:\n                n = n // i\n                while n % i == 0:\n                    n = n // i\n                if n == 1:\n                    FS[f] = {i}\n                else:\n                    FS[f] = {i} | factors3(n, i + 2)\n                break\n        else:\n            FS[f] = {f}\n\n    return FS[f]\n", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        A = set(A)\n        n = max(A)+1\n        p = [True]*n\n        p[0] = p[1] = False\n        # dic1: prime: num, dic2: num: prime\n        dic1, dic2 = collections.defaultdict(set), collections.defaultdict(set)\n        for i in range(2, n):\n            if p[i]:\n                if i in A:\n                    dic1[i].add(i)\n                    dic2[i].add(i)\n                for j in range(i*2, n, i):\n                    p[j] = False\n                    if j in A:\n                        dic1[i].add(j)\n                        dic2[j].add(i)\n        \n        seen = set()\n        res = 0\n        for num in A:\n            if num not in seen:\n                seen.add(num)\n                cur, s = 0, [num]\n                while s:\n                    node = s.pop()\n                    cur +=1\n                    for m in dic2[node]:\n                        for nxt in dic1[m]:\n                            if nxt not in seen:\n                                seen.add(nxt)\n                                s.append(nxt)\n                        dic1.pop(m)\n                res = max(res, cur)\n        return res", "class Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        def parent(x):\n            while root[x]!=x:\n                root[x]=root[root[x]]\n                x=root[x]\n            return x\n        \n        def union(x,y):\n            px=parent(x)\n            py=parent(y)\n            if px!=py:\n                if size[px]>size[py]:\n                    px,py=py,px\n                size[py]+=size[px]\n                root[px]=py\n                \n        def factorize(index,val):\n            while val!=1:\n                if smallestPrimeFactor[val] not in factorParent:\n                    factorParent[smallestPrimeFactor[val]]=index\n                union(index,factorParent[smallestPrimeFactor[val]])\n                val //= smallestPrimeFactor[val]\n                \n        m=max(A)+1\n        smallestPrimeFactor=[i for i in range(m)]\n        for i in range(2,int(pow(m,0.5))+1):\n            if smallestPrimeFactor[i]==i:\n                for j in range(i*i,m,i):\n                    if smallestPrimeFactor[j]==j:\n                        smallestPrimeFactor[j]=i\n                        \n        n=len(A)\n        size=[1]*n\n        root=[i for i in range(n)]\n        factorParent={}\n        for i in range(n):\n            factorize(i,A[i])\n        return max(size)", "class DSU:\n    def __init__(self, arr):\n        self.max_size = 0\n        self.parent = [i for i in range(len(arr))]\n        self.size = [1 for _ in range(len(arr))]\n    \n    def find(self, x):\n        root = x\n        while root != self.parent[root]:\n            root = self.parent[root]\n        while x != root:\n            next_node = self.parent[x]\n            self.parent[x] = root\n            x = next_node\n        return root\n    \n    def union(self, x, y):\n        r1, r2 = self.find(x), self.find(y)\n        if r1 == r2:\n            return\n        if self.size[r1] < self.size[r2]:\n            self.size[r2] += self.size[r1]\n            self.parent[r1] = r2\n            self.max_size = max(self.max_size, self.size[r2])\n        else:\n            self.size[r1] += self.size[r2]\n            self.parent[r2] = r1\n            self.max_size = max(self.max_size, self.size[r1])\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        \n        primes = collections.defaultdict(list)\n        \n        def getPrimeFactors(n):\n            out = set()\n            while n % 2 == 0: \n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n))+1, 2): \n                while n % i== 0: \n                    out.add(i) \n                    n //= i \n            if n > 2: \n                out.add(n)\n            return out\n                \n        prime_to_idx = {}\n        dsu = DSU(A)\n        for i, n in enumerate(A):\n            primes = getPrimeFactors(n)\n            for p in primes:\n                if p in prime_to_idx:\n                    dsu.union(i, prime_to_idx[p])\n                prime_to_idx[p] = i\n        return dsu.max_size", "class UF:\n    def __init__(self, n):\n        self.parent = list(range(n))\n        self.size = [1] * n\n    \n    def find(self, x):\n        if self.parent[x] != x:\n            self.parent[x] = self.find(self.parent[x])\n        return self.parent[x]\n    \n    def union(self, x, y):\n        px, py = self.find(x), self.find(y)\n        if px != py:\n            if self.size[px] < self.size[py]:\n                px, py = py, px\n            self.parent[py] = px\n            self.size[px] += self.size[py]\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n        prime = [0, 0] + [1] * (int(max(A) ** 0.5 + 1) - 2)\n        for i in range(2, int(len(prime) ** 0.5) + 1):\n            if prime[i]:\n                prime[i * i::i] = [0] * ((len(prime) - 1) // i - i + 1)\n        prime = [i for i, x in enumerate(prime) if x]\n        \n        factor = collections.defaultdict(list)\n        for i, x in enumerate(A):\n            for p in prime:\n                if p * p > x:\n                    break\n                if x % p == 0:\n                    factor[p].append(i)\n                    while x % p == 0:\n                        x //= p\n            if x > 1:\n                factor[x].append(i)\n        \n        uf = UF(len(A))\n        for numbers in factor.values():\n            for i, j in zip(numbers, numbers[1:]):\n                uf.union(i, j)\n        return max(uf.size)", "class UnionFind(object):\n    def uf(self, n):\n        self.uf = [i for i in range(n)]\n        self.size = [1] * n\n\n    def find(self, x):\n        while x != self.uf[x]:\n            self.uf[x] = self.uf[self.uf[x]]\n            x = self.uf[x]\n        return self.uf[x]\n\n    def union(self, x, y):\n        x_root = self.find(x)\n        y_root = self.find(y)\n        if x_root == y_root:\n            return\n        self.uf[x_root] = y_root\n        self.size[y_root] += self.size[x_root]\n        self.size[x_root] = 0\n\n\nclass Solution:\n    def largestComponentSize(self, A: List[int]) -> int:\n\n        def primeFactors(n):\n            out = set()\n            while n % 2 == 0:\n                out.add(2)\n                n //= 2\n            for i in range(3, int(math.sqrt(n)) + 1, 2):\n                while n % i == 0:\n                    out.add(i)\n                    n //= i\n            if n > 2:\n                out.add(n)\n            return out\n\n        uf = UnionFind()\n        uf.uf(len(A))\n\n        primeToIndex = {}\n        for i, a in enumerate(A):\n            primes = primeFactors(a)\n            for p in primes:\n                if p in primeToIndex:\n                    uf.union(i, primeToIndex[p])\n                primeToIndex[p] = i\n        return max(uf.size)"]