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):
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):
    uf.union(*(int(x) - 1 for x in input().split()))
print(max(uf.size(x) for x in range(n)))

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())
c=UnionFind(n)
for _ in range(m):
    a,b=map(int,input().split())
    c.union(a-1,b-1)
ans=0
for i in range(n):
    ans=max(ans,c.size(i))
print(ans)

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

N,M=map(int,input().split())
P=[i for i in range(N+1)]
size=[1 for i in range(N+1)]

def find(a):
    if a==P[a]:
        return a
    else:
        return find(P[a])
        
def union(b,c):
    B=find(b)
    C=find(c)
    if size[B]<size[C]:
        P[B]=P[C]
        size[C]+=size[B]
    else:
        P[C]=P[B]
        size[B]+=size[C]

for i in range(M):
    a,b=map(int,input().split())
    if find(a)==find(b):
        P[a]=find(a)
        P[b]=find(b)
        continue
    else:
        union(a,b)
for i in range(N+1):
    P[i]=find(P[i])

D={}
for i in range(1,N+1):
    if P[i] not in D:
        D[P[i]]=1
    else:
        D[P[i]]+=1
ans=0
for k,v in D.items():
    if ans<v:
        ans=v
print(ans)

Solution (Python):
from sys import stdin, setrecursionlimit
input = stdin.buffer.readline
setrecursionlimit(10 ** 7)

from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
from collections import deque, defaultdict, Counter
from itertools import combinations, permutations, combinations_with_replacement
from itertools import accumulate
from math import ceil, sqrt, pi, radians, sin, cos

MOD = 10 ** 9 + 7
INF = 10 ** 18

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

root = [i for i in range(N + 1)]
size = [1] * (N + 1)
 
def find(x):
  y = root[x]
  if x == y:
    return x
  else:
    z = find(y)
    root[x] = z
    return z

def union(x, y):
  rx = find(x)
  ry = find(y)
  sx = size[rx]
  sy = size[ry]
  if rx == ry:
    return 0
  else:
    if sx >= sy:
      root[ry] = rx
      size[rx] = sx + sy
    else:
      root[rx] = ry
      size[ry] = sx + sy
    return sx * sy

cnt = [0] * (N + 1)

for a, b in AB:
    union(a, b)
for i in range(1, N + 1):
    cnt[find(i)] += 1

print(max(cnt))

Solution (Python):
import sys, re
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians
from itertools import accumulate, permutations, combinations, product
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from bisect import bisect, bisect_left
from fractions import gcd
from heapq import heappush, heappop
from functools import reduce
def input(): return sys.stdin.readline().strip()
def INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(): return list(map(int, input().split()))
def ZIP(n): return zip(*(MAP() for _ in range(n)))
sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7

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()
L = [LIST() for i in range(M)]

tree = UnionFind(N)
friends = defaultdict(list)
for a, b in L:
    friends[a-1].append(b-1)
    friends[b-1].append(a-1)
    tree.union(a-1, b-1)


dic = defaultdict(int)
for i in range(N):
    al = tree.find(i)
    
    dic[al] += 1


l = list(dic.values())





l.sort()
sl = set(l)
tmp = 0
ans = 0
for y in sl:
    
    y -= tmp
    ans += y
    tmp += y

    
print(ans)

Solution (Python):

from sys import stdin
from sys import setrecursionlimit
setrecursionlimit(10 ** 7)

n,m = map(int,stdin.readline().rstrip().split())

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())

f = UnionFind(n)

for _ in range(m):
    a,b = map(int,stdin.readline().rstrip().split())
    a -= 1
    b -= 1
    f.union(a,b)

ma = 0

for i in range(n):
    ma = max(ma,f.size(i))

print(ma)

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())
if m == 0:
    print(1)
    exit()
uf = UnionFind(n)
ans = 0
for i in range(m):
    a, b = map(int, input().split())
    uf.union(a-1, b-1)
    ans = max(ans, uf.size(a-1))
print(ans)

Solution (Python):
from collections import deque
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)

li = []
seen = [False]*n
for i in range(n):
    if seen[i]:
        continue
    q = deque([i])
    seen[i] = True
    cnt = 1
    while q:
        node = q.popleft()
        for i in graph[node]:
            if seen[i]:
                continue
            seen[i] = True
            cnt += 1
            q.append(i)
    li.append(cnt)
print(max(li))

Solution (Python):
def find(x):
	while x!=p[x]:
		x=p[x]
	return x

def union(a,b):
	x=find(a)
	global con
	y=find(b)
	if x!=y:
		p[y]=p[x]=min(x,y);con-=1
		r[min(x,y)]+=r[max(x,y)];con=max(con,r[min(x,y)])
n,m=map(int,input().split())
p=[i for i in range(n+1)]
con=1
r=[1]*(n+1)
for i in range(m):
  u,v=map(int,input().split())
  union(u,v)
print(max(r))

Solution (Python):
import sys
sys.setrecursionlimit(2*10**9)

N, M = map(int, input().split())
friends = [[] for _ in range(N)]
for k in range(M):
  A, B = map(int, input().split())
  A -= 1
  B -= 1
  friends[A].append(B)
  friends[B].append(A)
group = []
sgn = [0 for _ in range(N)] 
def make_group(person, groupnum):
  sgn[person] = 1
  for f in friends[person]:
    if sgn[f] == 0:
      group[groupnum].append(f)
      make_group(f, groupnum)
  return None

c = 0
for k in range(N):
  if sgn[k] == 0:
    group.append([k])
    make_group(k, c)
    c += 1
ans = 0
for g in group:
  ans = max(len(g), ans)
print(ans)

Solution (Python):

import sys
N,M=map(int, sys.stdin.readline().split())

par=[ i for i in range(N+1) ]
size=[ 1 for i in range(N+1) ]


def root(x):
    while par[x]!=x:
        x=par[x]
    return x

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

def unite(x,y):
    x=root(x)
    y=root(y)
    if x==y: return
    if size[y]<size[x]: x,y=y,x  
    size[y]+=size[x]
    par[x]=y 

def getsize(x):
	return size[root(x)]

for _ in range(M):
    a,b=map(int, sys.stdin.readline().split())
    unite(a,b)

ans=float("-inf")
for i in range(1,N+1):
    ans=max(ans,getsize(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 = list(map(int, input().split()))
u = UnionFind(N)
for i in range(M):
    a, b = list(map(int, input().split()))
    a, b = a - 1, b - 1
    u.union(a, b)
n_size = 0
for i in range(N):
    n_size = max(n_size, u.size(i))
print(n_size)

Solution (Python):
from collections import deque
N,M=map(int,input().split())
ans=0
friendset=[0]*N
pset=set()
for h in range(N):
    pset.add(h)
    friendset[h]=set()
for p in range(M):
    A,B=map(int,input().split())
    A-=1
    B-=1
    friendset[A].add(B)
    friendset[B].add(A)

while(len(pset)!=0):
    kouho=1
    d=deque()
    i=pset.pop()
    d.append(i)
    while(len(d)!=0):
        person=d.popleft()
        for k in friendset[person]:
            if k in pset:
                
                d.append(k)
                pset.remove(k)
                friendset[k].remove(person)
                kouho+=1
    ans=max(kouho,ans)
print(ans)

Solution (Python):
n,m=map(int, input().split())
tomodati=[[] for i in range(n+1)]
syozoku=[0]*(n+1)
group_list=[0]*(10**6)
for i in range(m):
    a,b=map(int, input().split())
    tomodati[a].append(b)
    tomodati[b].append(a)

from collections import deque
tomo_que=deque()
group=0
for i in range(1,n+1):
    group+=1
    tomo_que.append(i)
    while tomo_que:
        moto=tomo_que.popleft()
        if syozoku[moto]==0:
            syozoku[moto]=group
            group_list[group]+=1

        for i in tomodati[moto]:
            if syozoku[i]==0:
                syozoku[i]=group
                tomo_que.append(i)
                group_list[group]+=1

print(max(group_list))

Solution (Python):
from collections import deque
n, m= map(int, input().split())
lis = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    lis[a].append(b)
    lis[b].append(a)

seen = [False] * n
ans = 1
for i in range(n):
    if seen[i] == False:
        queue = deque([i])
        seen[i] = True
        tmp =0
        while queue:
            now = queue.pop()
            tmp += 1
            for j in lis[now]:
                if seen[j] == True:
                    continue
                else:
                    seen[j] = True
                    queue.append(j)
        ans = max(ans, tmp)
print(ans)

Solution (Python):
from collections import defaultdict

def bfs(s):
  q = [s]
  visited[s] = True
  c = 0
  while q != []:
    p = q[0]
    c += 1
    del q[0]
    for node in adj[p]:
      if not visited[node]:
        visited[node] = True
        q.append(node)
  return c

n,m = map(int,input().split())
adj = defaultdict(list)
visited = [False]*(n+1)
ans = 0
for _ in range(m):
  a,b = map(int,input().split())
  adj[a].append(b)
  adj[b].append(a)
for i in range(1,n+1):
  if not visited[i]:
    ans = max(ans,bfs(i))
print(ans)

Solution (Python):
import sys
from collections import Counter as cc
def input(): return sys.stdin.readline().rstrip()
def ii(): return int(input())
def mi(): return map(int, input().split())
def li(): return list(mi())
class UnionFind():
    def __init__(self, n):
        self.parent = [i for i in range(n)]
        self.height = [0]*n

    def get_root(self, i):
        if self.parent[i] == i:
            return i
        else:
            self.parent[i] = self.get_root(self.parent[i])
            return self.parent[i]
        
    def unite(self, i, j):
        root_i = self.get_root(i)
        root_j = self.get_root(j)
        if root_i != root_j:
            if self.height[root_i] < self.height[root_j]:
                self.parent[root_i] = root_j
            else:
                self.parent[root_j] = root_i
                if self.height[root_i] == self.height[root_j]:
                    self.height[root_i] += 1
    
    def is_in_group(self, i, j):
        if self.get_root(i) == self.get_root(j):
            return True
        else:
            return False

def main():
    n, m = mi()
    uf = UnionFind(n)
    for i in range(m):
        a, b = mi()
        a -= 1
        b -= 1
        uf.unite(a, b)
    for i in range(n):
        uf.get_root(i)
    c = cc(uf.parent)
    ans = max(c.values())
    print(ans)




if __name__ == '__main__':
    main()

Solution (Python):
N, M = map(int, input().split())
arr = list([] for i in range(N+1))
for i in range(M):
    A,B = map(int, input().split())
    arr[A].append(B)
    arr[B].append(A)

from collections import deque
q = deque()
vis = [0 for i in range(N+1)]

def BFS(t):
    count = 1
    q.append(t)
    while q:
        x = q.popleft()
        for i in arr[x]:
            if vis[i] == 0:
                vis[i] = 1
                count += 1
                q.append(i)
    return count

ans = 0
for i in range(1,N+1):
    if vis[i] == 0:
        vis[i] = 1
        ans = max(BFS(i),ans)

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 i in range(m):
    a, b = map(int, input().split())
    uf.union(a-1, b-1)
nux = 0
for r in uf.roots():
    nux = max(nux, uf.size(r))

print(nux)

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 i in range(M):
    A,B = map(int, input().split())
    uf.union(A-1,B-1)
ans = 0
for i in range(N):
    ans = max(ans,uf.size(i))

print(ans)

Solution (Python):
N,M = map(int,input().split())    
       
AB = [None]*M
for i in range(M):
    a,b = map(int,input().split())
    if a>b:
        a,b=b,a
    AB[i] = (a-1,b-1)

AB=set(AB)

tree=[[] for _ in range(N)]
for a,b in AB:
    tree[a].append(b)
    tree[b].append(a) 

from collections import deque

groups=[]
been=[0]*N
for i in range(N):
    if been[i]==0:
        group=[i]
        been[i]=1
        q = deque([(i,togo) for togo in tree[i]]) 
        while q:
            parent,x = q.popleft()
            if been[x]==1:
                continue
            been[x]=1
            group.append(x)
            for y in tree[x]:
                if y == parent:
                    continue
                q.append((x,y))
        groups.append(group)

print(max( len(g) for g in groups))

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

class UF:
    def __init__(self, num):
        self.parent = [i for i in range(num + 1)]
        self.rank = [1] * (num + 1)

    def unite(self, x, y):
        xpar = self.find(x)
        ypar = self.find(y)
        if xpar == ypar:
            return
        if self.rank[xpar] == self.rank[ypar]:
            self.parent[ypar] = self.parent[xpar]
            self.rank[xpar] += 1
        elif self.rank[xpar] > self.rank[ypar]:
            self.parent[ypar] = self.parent[xpar]
        else:
            self.parent[xpar] = self.parent[ypar]

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

groups = UF(N)

for i in range(M):
    a, b = map(int, input().split())
    groups.unite(a, b)

counts = {i:0 for i in range(N+1)}

for i in range(N+1):
    counts[groups.find(i)] += 1

print(max(counts.values()))

Solution (Python):
n,m=map(int, input().split())
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())
uf=UnionFind(n)
for i in range(m):
    a,b=map(int, input().split())
    uf.union(a-1,b-1)
ans=0
for i in uf.roots():
    ans=max(ans,uf.size(i))
print(ans)

Solution (Python):
import sys
read = sys.stdin.read
readlines = sys.stdin.readlines
def main():
    def find(x):
        if par[x] < 0:
            return x
        else:
            par[x] = find(par[x])
            return par[x]

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

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

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

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

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

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

    n, m = map(int, input().split())
    par = [-1] * n
    m = map(int, read().split())
    ab = zip(m, m)
    abs = set()
    for a, b in ab:
        a -= 1
        b -= 1
        tmp = (min(a, b), max(a, b))
        abs.add(tmp)
    for abse in abs:
        unite(abse[0], abse[1])
    rs = roots()
    r = 0
    for rse in rs:
        r = max(r, size(rse))
    print(r)
if __name__ == '__main__':
    main()

Solution (Python):
import sys, re
from math import ceil, floor, sqrt, pi, factorial, gcd
from copy import deepcopy
from collections import Counter, deque
from heapq import heapify, heappop, heappush
from itertools import accumulate, product, combinations, combinations_with_replacement
from bisect import bisect, bisect_left, bisect_right
from functools import reduce
from decimal import Decimal, getcontext

def i_input(): return int(input())
def i_map(): return map(int, input().split())
def i_list(): return list(i_map())
def i_row(N): return [i_input() for _ in range(N)]
def i_row_list(N): return [i_list() for _ in range(N)]
def s_input(): return input()
def s_map(): return input().split()
def s_list(): return list(s_map())
def s_row(N): return [s_input for _ in range(N)]
def s_row_str(N): return [s_list() for _ in range(N)]
def s_row_list(N): return [list(s_input()) for _ in range(N)]
def lcm(a, b): return a * b // gcd(a, b)
sys.setrecursionlimit(10 ** 6)
INF = float('inf')
MOD = 10 ** 9 + 7
num_list = []
str_list = []

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

    
    def findRoot(self, x):
        if(self.root[x] < 0): 
            return x
        else:
            
            self.root[x] = self.findRoot(self.root[x])
            return self.root[x]
    
    def unite(self, x, y):
        
        x = self.findRoot(x)
        y = self.findRoot(y)
        
        if x == y:
            return 
        
        if self.rank[x] > self.rank[y]:
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1
    
    def isSameGroup(self, x, y):
        return self.findRoot(x) == self.findRoot(y)

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

def main():
    n, m = i_map()

    uf = UnionFind(n)

    for _ in range(m):
        a, b = i_map()
        
        if uf.isSameGroup(a, b):
            continue
        else:
            uf.unite(a, b)

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

    print(max_count)

if __name__ == '__main__':
    main()

Solution (Python):
import collections
import sys
sys.setrecursionlimit(10**6)
N, M = map(int, input().split())
AB = [tuple(map(int, input().split())) for i in range(M)]


class unionFind:
    parent = []

    def __init__(self, N):
        self.parent = [i for i in range(N)]

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

    def same(self, x, y):
        x, y = x-1, y-1
        return(self.root(x) == self.root(y))

    def unite(self, x, y):
        x, y = x-1, y-1
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return
        else:
            self.parent[x] = y
            return


G = unionFind(N)

for a, b in AB:
    G.unite(a, b)

for i in range(N):
    G.root(i)

C = collections.Counter(G.parent).most_common()

print(C[0][1])

Solution (Python):
def main():
    N, M = (int(i) for i in input().split())

    par = [i for i in range(N)]
    size = [1 for i in range(N)]

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

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

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

    def get_size(x):
        return size[find(x)]

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

    ans = max(get_size(i) for i in range(N))

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import defaultdict as dd
n, m = map(int, input().split())

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())

uf = UnionFind(n+1)
for i in range(m):
    a, b = map(int, input().split())
    uf.union(a, b)

max_mem = 0
for i in range(n+1):
    max_mem = max(max_mem, uf.size(i))
print(max_mem)