Problem:
 Score : 400 points    Problem Statement There are N persons called Person 1 through Person N .  You are given M facts that "Person A_i and Person B_i are friends." The same fact may be given multiple times.  If X and Y are friends, and Y and Z are friends, then X and Z are also friends. There is no friendship that cannot be derived from the M given facts.  Takahashi the evil wants to divide the N persons into some number of groups so that every person has no friend in his/her group.  At least how many groups does he need to make?      Constraints  2 \leq N \leq 2\times 10^5  0 \leq M \leq 2\times 10^5  1\leq A_i,B_i\leq N  A_i \neq B_i         Input Input is given from Standard Input in the following format:  N  M  A_1  B_1  \vdots  A_M  B_M       Output Print the answer.        Sample Input 1 5 3
1 2
3 4
5 1      Sample Output 1 3  Dividing them into three groups such as \{1,3\} , \{2,4\} , and \{5\} achieves the goal.       Sample Input 2 4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4      Sample Output 2 4       Sample Input 3 10 4
3 1
4 1
5 9
2 6      Sample Output 3 3

Solution (Python):
def cin():  return list(map(int,input().split()))

N, M = cin()
A = [cin() for _ in range(M)]

class UnionFind():
    
    
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n
    
    
    def find(self, x):
        if self.parents[x] < 0:  return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]
    
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:  return
        if self.parents[x] > self.parents[y]:  x, y = y, x
        self.parents[x] += self.parents[y]
        self.parents[y] = x
    
    
    def size(self, x):  return -self.parents[self.find(x)]
    
    
    def same(self, x, y):  return self.find(x) == self.find(y)
    
    
    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]
    
    
    def roots(self):  return [i for i, x in enumerate(self.parents) if x < 0]
    
    
    def group_count(self):  return len(self.roots())
      
uf = UnionFind(N)
for i in range(M):
    uf.union(A[i][0] - 1, A[i][1] - 1)
ans = 0
for i in range(N):
	ans = max(ans, uf.size(i))
print(ans)

Solution (Python):
class UnionFind():
    
    
    def __init__(self, n):
        self.n = n
        
        
        self.root = [-1]*(n+1)
        
        self.rnk = [0]*(n+1)
    
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            
            self.root[x] = self.Find_Root(self.root[x])
            return self.root[x]
    
    def Unite(self, x, y):
        
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        
        if(x == y):
            return 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x
        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    
    def isSameGroup(self, x, y):
        return self.Find_Root(x) == self.Find_Root(y)
    
    def Count(self, x):
        return -self.root[self.Find_Root(x)]

n,m = map(int,input().split())
uf = UnionFind(n)
for i in range(m):
  a,b = map(int,input().split())
  a -= 1
  b -= 1
  uf.Unite(a,b)
ans = 0
for i in range(n):
  ans = max(uf.Count(i),ans)
print(ans)

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.ps = [-1] * (n + 1)

    def find(self, x):
        if self.ps[x] < 0:
            return x
        else:
            self.ps[x] = self.find(self.ps[x])
            return self.ps[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.ps[x] > self.ps[y]:
            x, y = y, x
        self.ps[x] += self.ps[y]
        self.ps[y] = x
        return True

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        x = self.find(x)
        return -self.ps[x]


n, m = map(int, input().split())

uf = UnionFind(n)

for _ in range(m):
    a, b = map(int, input().split())
    uf.union(a, b)

print(min(uf.ps) * -1)

Solution (Python):
N, M = map(int, input().split())


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.rank = [0] * n
        self.size = [1] * n

    
    def find(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
            self.size[x] = 0
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            self.size[y] = 0
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def all_find(self):
        for n in range(len(self.par)):
            self.find(n)


UF = UnionFind(N)
for i in range(M):
    a, b = map(int, input().split())
    a, b = a - 1, b - 1
    UF.union(a, b)
UF.all_find()

print(max(UF.size))

Solution (Python):
import sys
from collections import Counter


class UnionFind:
    def __init__(self, n):
        
        
        self.table = [-1] * n
        self.n = n

    def _root(self, x):
        stack = []
        tbl = self.table
        while tbl[x] >= 0:
            stack.append(x)
            x = tbl[x]
        for y in stack:
            tbl[y] = x
        return x

    def find(self, x, y):
        return self._root(x) == self._root(y)

    def union(self, x, y):
        r1 = self._root(x)
        r2 = self._root(y)
        if r1 == r2:
            return
        
        d1 = self.table[r1]
        d2 = self.table[r2]
        if d1 <= d2:
            self.table[r2] = r1
            if d1 == d2:
                self.table[r1] -= 1
        else:
            self.table[r1] = r2

    def max_root(self):
        roots = []
        for i in range(self.n):
            roots.append(self._root(i))
        cnt = Counter(roots)
        return cnt.most_common(1)[0][1]


def main():
    input = sys.stdin.buffer.readline
    n, m = map(int, input().split())
    uf = UnionFind(n)
    for i in range(m):
        a, b = map(int, input().split())
        uf.union(a - 1, b - 1)
    print(uf.max_root())


if __name__ == "__main__":
    main()

Solution (Python):

class UnionFind():
    
    def __init__(self, n):  
        self.parent = list(range(n)) 
        self.rank = [0] * n   
        self._size = [1] * n 
        self._nsets = n  

    def root_of(self, x):
        children = [x]
        while self.parent[x] != x:
            x = self.parent[x]
            children.append(x)

        for ch in children:
            self.parent[ch] = x
        return x

    
    def union(self, x, y):
        rx = self.root_of(x)
        ry = self.root_of(y)
        if rx == ry:
            return
        if self.rank[rx] < self.rank[ry]: 
            self.parent[rx] = ry  
            self._size[ry] += self._size[rx]
        else:
            self.parent[ry] = rx
            self._size[rx] += self._size[ry]
            if self.rank[rx] == self.rank[ry]:
                self.rank[rx] += 1
        self._nsets -= 1

    
    def same(self, x, y):
        return self.root_of(x) == self.root_of(y)

    
    def get_size(self, x):
        return self._size[self.root_of(x)]

    
    def get_nsets(self):
        return self._nsets


n, m = [int(x) for x in input().split()]
uf = UnionFind(n)
for i in range(m):
    a, b = [int(x) - 1 for x in input().split()]
    uf.union(a, b)

ans = 0
for j in range(n):
    ans = max(ans, uf.get_size(j))

print(ans)

Solution (Python):
import sys

sys.setrecursionlimit(10 ** 7)

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    
    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    
    def same(self, x, y):
        return self.find(x) == self.find(y)

    
    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return "\n".join("{}: {}".format(r, self.members(r)) for r in self.roots())


N, M = map(int, input().split())
AB = [list(map(int, input().split())) for _ in range(M)]

U = UnionFind(N + 1)

for a, b in AB:
    if not U.same(a, b):
        U.union(a, b)

ans = 0
for i in range(1, N + 1):
    ans = max(ans, U.size(i))

print(ans)

Solution (Python):
from sys import stdin
input = stdin.readline

def bfs(s):
    q = [s]
    vst[s] = True
    ret = 1
    for u in q:
        for v in adj[u]:
            if not vst[v]:
                vst[v] = True
                q.append(v)
                ret += 1
    return ret


if __name__ == "__main__":
    N, M = map(int, input().split())
    adj = [set() for _ in range(N)]
    for _ in range(M):
        a, b = map(int, input().split())
        adj[a - 1].add(b - 1)
        adj[b - 1].add(a - 1)
    vst = [False] * N
    ans = 0
    for i in range(N):
        if not vst[i]:
            ans = max(ans, bfs(i))
    print(ans)

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

N,M = map(int, input().split())
UF = UnionFind(N)
      
for _ in range(M):
  a,b = map(int, input().split())
  UF.union(a-1,b-1)

answer = 0
for x in UF.roots():
  answer = max(answer, UF.size(x))

print(answer)

Solution (Python):
from sys import setrecursionlimit
setrecursionlimit(10 ** 9)

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.d = [-1] * n

    def find(self, x):
        if self.d[x] < 0:
            return x
        else:
            self.d[x] = self.find(self.d[x])
            return self.d[x]
    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return False
        else:
            if self.d[x] > self.d[y]:
                x, y = y, x
            self.d[x] += self.d[y]
            self.d[y] = x
            return True

    def same(self, x, y):
        return self.find(x) == self.find(y)


    def size(self, x):
        return -self.d[self.find(x)]


N, M = map(int,input().split())
uf = UnionFind(N)
for i in range(M):
    A,B = map(int,input().split())
    A -= 1
    B -= 1
    uf.unite(A,B)
ans = 0
for i in range(N):
    ans = max(ans,uf.size(i))
print(ans)

Solution (Python):

class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())

N, M = map(int, input().split())
ABs = [list(map(lambda x:int(x)-1, input().split())) for _ in range(M)]

uf = UnionFind(N)

for AB in ABs:
    uf.union(AB[0], AB[1])

roots = uf.roots()
answer = 0
for root in roots:
    size = uf.size(root)
    if size > answer:
        answer = size
print(answer)

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.parents[self.find(x)]

N, M = list(map(int, input().split()))

tree = UnionFind(N)

for i in range(M):
    a, b = list(map(int, input().split()))
    tree.union(a-1, b-1)

group_size_max = 0
for j in range(N):
    group_size_max = max(group_size_max, tree.size(j))

print(group_size_max)

Solution (Python):

from collections import deque

n, m = list(map(int, input().split()))
edges = [list(map(int, input().split())) for _ in range(m)]

neighbor = [[] for _ in range(n)]
for edge in edges:
    neighbor[edge[0]-1].append(edge[1]-1)  
    neighbor[edge[1]-1].append(edge[0]-1)


visited = [-1] * n
ans = 1
for idx in range(n):
    if visited[idx] == -1:
        queue = deque()
        queue.append(idx)
        group_population = 1
        visited[idx] = 0
        while len(queue) > 0:
            vertex = queue.popleft()
            for nei in neighbor[vertex]:
                if visited[nei] == -1:
                    visited[nei] = 0
                    queue.append(nei)
                    group_population += 1
    
    ans = max(ans, group_population)
        
print(ans)

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parent = [i for i in range(n)]  
        self.rank = [1] * n  
        self.size = [1] * n  

    def find(self, x):  
        if self.parent[x] == x:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])  
            return self.parent[x]

    def unite(self, x, y):  
        x = self.find(x)
        y = self.find(y)
        if x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[y] = x
                self.size[x] += self.size[y]
                if self.rank[x] == self.rank[y]:
                    self.rank[x] += 1

    def is_same(self, x, y):  
        return self.find(x) == self.find(y)

    def group_size(self, x):  
        return self.size[self.find(x)]

n, m = map(int, input().split())
uf = UnionFind(n)
for i in range(m):
    a, b = map(int, input().split())
    a -= 1; b -= 1
    uf.unite(a, b)
x = 0
for i in range(n):
    x = max(x, uf.group_size(i))
print(x)

Solution (Python):
"""
UnionFind
"""
class UnionFind:
    def __init__(self, n: int) -> None:
        self.forest = [-1] * n

    def union(self, x: int, y: int) -> None:
        x = self.findRoot(x)
        y = self.findRoot(y)
        if x == y:
            return
        if self.forest[x] > self.forest[y]:
            x,y = y,x
        self.forest[x] += self.forest[y]
        self.forest[y] = x
        return

    def findRoot(self, x: int) -> int:
        if self.forest[x] < 0:
            return x
        else:
            self.forest[x] = self.findRoot(self.forest[x])
            return self.forest[x]

    def issame(self, x: int, y: int) -> bool:
        return self.findRoot(x) == self.findRoot(y)
    
    def size(self,x: int) -> int:
        return -self.forest[self.findRoot(x)]

n,m = map(int,input().split())

u = UnionFind(n)
for _ in range(m):
    a,b = map(int,input().split())
    a -= 1
    b -= 1
    u.union(a,b)
ans = 0
for i in range(n):
    ans = max(ans,u.size(i))
print(ans)

Solution (Python):
import sys
input = sys.stdin.readline

class UnionFind():
    def __init__(self, n):
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

n, m = map(int, input().split())
ab = [list(map(int, input().split())) for _ in range(m)]

uf = UnionFind(n)

for ai, bi in ab:
    uf.union(ai-1, bi-1)

for i in range(n):
    p = uf.find(i)

print(-min(uf.parents))

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self, x):
        return -self.parents[self.find(x)]

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())



N,M = map(int,input().split())
F = UnionFind(N)

for i in range(M):
  A,B = map(int,input().split())
  F.union(A-1,B-1)
  
res = 0
for i in range(N):
  res = max(res,F.size(i))
  
print(res)

Solution (Python):
class UnionFind():
    def __init__(self,n):
        self.n = n
        self.parents = [-1] * n

    def find(self,x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self,x,y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.parents[x] > self.parents[y]:
            x,y = y,x
        self.parents[x] += self.parents[y]
        self.parents[y] = x

    def size(self,x):
        return -self.parents[self.find(x)]

    def same(self,x,y):
        return self.find(x) == self.find(y)

    def members(self,x):
        root = self.find(x)
        return [i for i in range(self.n)if self.find(i) == root]

    def roots(self):
        return [i for i,x in enumerate(self.parents) if x < 0]

    def group_count(self):
        return len(self.roots())

    def all_group_members(self):
        return {r:self.members(r) for r in self.roots()}

N,M = map(int,input().rstrip().split(" "))
uft = UnionFind(N)
ans = 0
for i in range(M):
    a,b = map(int,input().rstrip().split(" "))
    uft.union(a-1,b-1)
for i in range(N):
    ans = max(ans,uft.size(i))
print(ans)

Solution (Python):
import sys


class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x


def read():
    return sys.stdin.readline().rstrip()


def main():
    n, m = map(int, read().split())
    uf = UnionFind(n)
    for _ in range(m):
        a, b,  = [int(i) - 1 for i in read().split()]
        uf.union(a, b)
    print(-min(uf.parents))


if __name__ == '__main__':
    main()

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.root = [-1]*(n+1)
        self.rnk = [0]*(n+1)

    def find(self, x):
        if(self.root[x] < 0):
            return x
        else:
            self.root[x] = self.find(self.root[x])
            return self.root[x]

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if(x == y):
            return
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1

    def is_in_same(self, x, y):
        return self.find(x) == self.find(y)

    def count(self, x):
        return -self.root[self.find(x)]


n, m = map(int, input().split())
uf = UnionFind(n)
for _ in range(m):
    a, b = map(int, input().split())
    uf.unite(a-1, b-1)

val = 0
for i in range(n):
    val = max(val, uf.count(i))

print(val)

Solution (Python):

import sys 
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines



def find(x):
    if par[x] < 0:
        return x
    else:
        par[x] = find(par[x])
        return par[x]

def union(x,y):
    x = find(x)
    y = find(y)
    if x != y:
        
        if par[x] > par[y]:
            x,y = y,x
        par[x] += par[y] 
        par[y] = x 
        return 


def same(x,y):
    return find(x) == find(y)


def size(x):
    return -par[find(x)]

N,Q = map(int,readline().split())

par = [-1]*(N+1)
for _ in range(Q):
    x,y = map(int,readline().split())
    union(x,y)

print(-min(par))

Solution (Python):
from sys import stdin, setrecursionlimit
from collections import Counter, deque, defaultdict
from math import floor, ceil
from bisect import bisect_left
from itertools import combinations
setrecursionlimit(100000)

class UnionFind(object):
    def __init__(self, n):
        self.par = [-1] * n
    
    def find(self, x):
        if self.par[x] < 0:
            return x
        else:
            self.par[x] = self.find(self.par[x])
            return self.par[x]

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        
        if x == y:
            return False
        else:
            if self.par[x] > self.par[y]:
                x, y = y, x
            self.par[x] += self.par[y]
            self.par[y] = x
            return True

    def same(self, x, y):
        return self.find(x) == self.find(y)

    def size(self, x):
        return -self.par[self.find(x)]

    def members(self, x):
        root = self.find(x)
        return [i for i in range(self.n) if self.find(i) == root]

    def roots(self):
        return [i for i, x in enumerate(self.par) if x < 0]

    def group_count(self):
        return len(self.roots())

def main():
    from builtins import int, map
    N, M = map(int, input().split())
    uf = UnionFind(N)
    for _ in range(M):
        ai, bi = map(lambda x: int(x) - 1, input().split())
        uf.unite(ai, bi)

    
    ans = -1
    for n in range(N):
        ans = max(ans, uf.size(n))
        
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)

N, M = map(int, input().split())


class UnionFind:
    def __init__(self, N):
        self.parent = list(range(N + 1))
        self.size = [1] * (N + 1)

    def __getitem__(self, x):
        parent = self.parent
        while parent[x] != x:
            parent[x] = parent[parent[x]]
            x = parent[x]
        return x

    def merge(self, x, y):
        x = self[x]
        y = self[y]
        if x == y:
            return
        sx, sy = self.size[x], self.size[y]
        if sx < sy:
            x, y = y, x
            sx, sy = sy, sx
        self.parent[y] = x
        self.size[x] += sy


uni = UnionFind(N)
for i in range(M):
    a, b = map(int, input().split())
    uni.merge(a, b)


max_size = 0
for i in range(1, N+1):
    max_size = max(max_size, uni.size[i])

print(max_size)

Solution (Python):
class UF:
  def __init__(self,n=0):
    self.vertices=n
    self.mother=[-1 for i in range(self.vertices)]
  
  def root(self,x):
    normalize_v=[]
    while x!=-1:
      normalize_v.append(x)
      y=x
      x=self.mother[x]
    for i in normalize_v[:-1]:
      self.mother[i]=y
    return y
  
  def union(self,x,y):
    root_y=self.root(y)
    root_x=self.root(x)
    if root_x!=root_y:
      self.mother[root_x]=root_y
  
  def find(self,x,y):
    if self.root(x)==self.root(y):
      return True
    else:
      return False

n,m=map(int,input().split())
uf=UF(n)
for i in range(m):
  q=list(map(lambda x:int(x)-1,input().split()))
  uf.union(q[0],q[1])

l=[0 for i in range(n)]
ml=0
for i in range(n):
  r=uf.root(i)
  l[r]+=1
  ml=max(ml,l[r])

print(ml)

Solution (Python):
from collections import Counter
N, M = map(int, input().split())


parent = [i for i in range(N)]
rank = [1] * N
def get_root(node):
  global parent
  if parent[node] == node:
    return node
  root = get_root(parent[node])
  parent[node] = root
  return root

def union(a, b):
  global parent
  global rank
  root_a = get_root(a)
  rank_a = rank[root_a]
  root_b = get_root(b)
  rank_b = rank[root_b]
  if root_a == root_b:
    return
  if rank_a < rank_b:
    parent[root_a] = root_b
  else:
    parent[root_b] = root_a
    if rank_a == rank_b:
      rank[root_a] += 1

for _ in range(M):
    a, b = map(int, input().split())
    union(a-1, b-1)

for i in range(N):
    get_root(i)

ct = Counter(parent)
print(ct.most_common()[0][1])

Solution (Python):
import sys
input = sys.stdin.readline

n,m=map(int, input().split())
es=[[] for _ in range(n)]
for i in range(m):
    a,b=map(int, input().split())
    es[a-1].append(b-1)
    es[b-1].append(a-1)

ans=0
from collections import deque
used=[0 for _ in range(n)]
for i in range(n):
    if used[i]==0:
        d=deque([i])
        cnt=0
        while d:
            now=d.popleft()
            cnt+=1
            used[now]=1
            for e in es[now]:
                if used[e]==0:
                    used[e]=1
                    d.append(e)
        ans=max(cnt,ans)
print(ans)

Solution (Python):
import sys
from collections import Counter
from scipy.sparse.csgraph import connected_components
from scipy.sparse import csr_matrix

input = sys.stdin.buffer.readline
int1 = lambda x: int(x) - 1

N, M = map(int, input().split())

frm, to = [0] * M, [0] * M
for i in range(M):
    a, b = map(int1, input().split())
    frm[i] = a
    to[i] = b

matr = csr_matrix(([1] * M, (frm, to)), shape=(N, N))
_, labels = connected_components(matr, directed=False)
print(max(Counter(labels).values()))

Solution (Python):
import sys


class UnionFind():
    def __init__(self, n):
        self.parents = [-1] * n

    def find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

        if self.parents[x] > self.parents[y]:
            x, y = y, x

        self.parents[x] += self.parents[y]
        self.parents[y] = x


N, M = map(int, input().split())
info = [tuple(map(lambda x: int(x) - 1, s.split())) for s in sys.stdin.readlines()]

uf = UnionFind(N)
for a, b in info:
    uf.union(a, b)

ans = min(uf.parents)

print(-ans)

Solution (Python):

import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
MOD = 10**9 + 7

class DisjointSet:
    def __init__(self, n):
        self.par = [i for i in range(n)]
        self.size = [1] * n
        self.rank = [0] * n

    def root(self, x):
        if self.par[x] == x:
            return x
        else:
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def has_same_root(self, x, y):
        return self.root(x) == self.root(y)

    def get_size(self, x):
        return self.size[self.root(x)]

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x] 
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
 
n, m = map(int, input().split())
DS = DisjointSet(n)
for _ in range(m):
    a, b = map(int, input().split())
    a -= 1; b -= 1
    DS.unite(a, b)
ans = 0
for i in range(n):
    ans = max(ans, DS.get_size(i))
print(ans)