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 find(target):
    if parent[target] < 0:
        return target
    else:
        parent[target] = find(parent[target])
        return parent[target]

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

def union(x, y):
    root_x = find(x)
    root_y = find(y)
    if root_x == root_y:
        return
    if parent[root_x] > parent[root_y]:
        root_x, root_y = root_y, root_x
    parent[root_x] += parent[root_y]
    parent[root_y] = root_x
def members(n, x):
    root = find(x)
    return [i for i in range(n) if find(i) == root]

def get_size(x):
    return -parent[find(x)]

def get_root():
    return [i for i, root in enumerate(parent) if root < 0]
n, m = map(int, input().split())
parent = [-1 for _ in range(n)]
for _ in range(m):
    a, b = map(lambda x: int(x) - 1, input().split())
    union(a, b)
    
ans = 0
for i in range(n):
    ans = max(ans, get_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())

uf = UnionFind(n)

for _ 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):
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

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

    def unite(self, u, v):
        u = self.find(u)
        v = self.find(v)

        if u == v:
            return

        if self.parents[u] > self.parents[v]:
            u, v = v, u

        self.parents[u] += self.parents[v]
        self.parents[v] = u

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

    def same(self, u, v):
        return self.find(u) == self.find(v)

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

ans = 0
for i in range(N):
    ans = max(ans, uf.size(i))

print(ans)

Solution (Python):
import sys, math, itertools, collections, bisect
input = lambda: sys.stdin.buffer.readline().rstrip().decode('utf-8')
inf = float('inf') ;mod = 10**9+7
mans = inf ;ans = 0 ;count = 0 ;pro = 1

class UnionFind:
    __slots__ = ['id','sz']

    def __init__(self, n):
        self.id = [-1] * n
        self.sz = n

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

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

    def union(self, x, y):
        s1, s2 = self.root(x), self.root(y)
        if s1 != s2:
            if self.id[s1] <= self.id[s2]:
                self.id[s1] += self.id[s2]
                self.id[s2] = s1
            else:
                self.id[s2] += self.id[s1]
                self.id[s1] = s2
            self.sz-=1
            return True
        return False

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.union(a,b)
M = 0
for i in range(n):
  M = min(M,uf.id[i])
print(abs(M))

Solution (Python):
n,m=[int(x) for x in input().split()]
l=[[] for i in range(n)]
for i in range(m):
  a,b=map(int,input().split())
  l[a-1].append(b-1)
  l[b-1].append(a-1)


done=[0]*n


def dfs(j):
  que=[j]
  cnt=1
  done[j]=1
  while(que):
    now=que.pop(0)

    for i in l[now]:
      if done[i]!=1:
        que.append(i)
        done[i]=1
        cnt+=1

  return cnt

ma=0
for j in range(n):
  if done[j]!=1:
    now=dfs(j)
  else:
    now=0
  ma=max(now,ma)
  
print(ma)

Solution (Python):
from collections import deque

N, M = [int(x) for x in input().split()]

friends_map = {n: set() for n in range(N)}
remain_user = set()
for m in range(M):
    a, b = [int(x) - 1 for x in input().split()]

    friends_map[a].add(b)
    friends_map[b].add(a)
    remain_user.add(a)
    remain_user.add(b)

stack = deque()
stack.appendleft(0)

max_group = 1
watch = set()
while stack:
    now = stack.popleft()

    if not now in watch:
        remain_user.discard(now)
        watch.add(now)

        for next_node in friends_map[now]:
            if not next_node in watch:
                stack.appendleft(next_node)

    if not stack:
        max_group = max(len(watch), max_group)

        if remain_user:
            stack.appendleft(remain_user.pop())
            watch = set()

print(max_group)

Solution (Python):

class UnionFindPathCompression():
    def __init__(self, n):
        self.parents = list(range(n))
        self.size = [1] * n
    
    def find_root(self, x):
        if self.parents[x] == x:
            return x
        else:
            self.parents[x] = self.find_root(self.parents[x])
            return self.parents[x]
    def make_union(self, x, y):
        x = self.find_root(x)
        y = self.find_root(y)
        
        if x == y : return
        self.size[x] += self.size[y]
        self.parents[y] = x

def main():
    n, m = map(int, input().split())
    uf = UnionFindPathCompression(n)
    for _ in range(m):
        a, b = map(int, input().split())
        uf.make_union(a - 1, b - 1)
    
    ans = max(uf.size)
    print(ans)

if __name__ == "__main__":
    main()

Solution (Python):
from collections import deque

N, M = [int(x) for x in input().split()]

friends_map = {n : set() for n in range(N)}
remain_user = set()
for m in range(M):
    a, b = [int(x) - 1 for x in input().split()]

    friends_map[a].add(b)
    friends_map[b].add(a)
    remain_user.add(a)
    remain_user.add(b)

stack = deque()
stack.appendleft(0)

max_group = 1
watch = [0] * N
count = 0
while stack:
    now = stack.popleft()

    if watch[now] == 0:
        remain_user.discard(now)
        watch[now] = 1
        count += 1

        for next_node in friends_map[now]:
            if watch[next_node] == 0:
                stack.appendleft(next_node)

    if not stack:
        max_group = max(count, max_group)

        if remain_user:
            stack.appendleft(remain_user.pop())
            count = 0

print(max_group)

Solution (Python):
import sys
from collections import defaultdict
sys.setrecursionlimit(10 + 2 * 10 ** 5)
 
n, m = map(int, input().split())
 
color = [None] * (n + 1)
for i in range(n + 1):
    color[i] = i
 
def root(x):
    global color
 
    if color[x] == x:
        return x
    color[x] = root(color[x])
    return color[x]
 
def unite(x, y):
    rx = root(x)
    ry = root(y)
    if rx == ry:
        return
    color[rx] = ry
 
for i in range(m):
    a, b = map(int, input().split())
    unite(a, b)
 
cnt = defaultdict(int)
for i in range(n):
    cnt[root(i + 1)] += 1
print(max(cnt.values()))

Solution (Python):
class union_find:
    def __init__(self, node_num):
        self.root_array = [-1] * node_num

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

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

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


def solve(n, m, ab_array):
    uf = union_find(n)
    for ab in ab_array:
        a, b = ab
        uf.unite(a - 1, b - 1)

    ans = 0
    for i in range(n):
        ans = max(ans, uf.size(i))

    return ans

if __name__ == '__main__':
    n, m = map(int, input().split())
    ab_array = [list(map(int, input().split())) for _ in range(m)]
    ans = solve(n, m, ab_array)
    print(ans)

Solution (Python):
n, m = map(int, input().split())
par = [-1 for _ in range(n)]


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


def union(x, y):
    rx, ry = root(x), root(y)
    if rx == ry:
        pass
    else:
        if par[rx] > par[ry]:
            rx, ry = ry, rx
        par[rx] += par[ry]
        par[ry] = rx


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


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

Solution (Python):
import sys
from collections import deque


def LI():
    return list(map(int, input().split()))


N, M = LI()
friend = [set() for _ in range(N)]
ans = 0
miru = set()
if M == 0:
    print(1)
    sys.exit()
for i in range(M):
    a, b = map(int, input().split())
    friend[a-1].add(b-1)
    friend[b-1].add(a-1)
    miru.add(a-1)
    miru.add(b-1)
looked = [0]*N
d = deque()
count = 0
d.append(a-1)
miru.discard(a-1)
while d:
    x = d.pop()
    for i in friend[x]:
        if looked[i] != 0:
            continue
        count += 1
        looked[i] = 1
        d.append(i)

    if len(d) == 0:
        ans = max(count, ans)
        if len(miru) == 0:
            break
        y = miru.pop()
        d.append(y)
        looked[y] = 1
        count = 1
        miru.discard(y)

print(ans)

Solution (Python):





import sys,os
from io import BytesIO, IOBase
import collections,itertools,bisect,heapq,math,string
from decimal import *


BUFSIZE = 8192

BUFSIZE = 8192
sys.setrecursionlimit(10 ** 7)
class FastIO(IOBase):
    newlines = 0

    def __init__(self, file):
        self._fd = file.fileno()
        self.buffer = BytesIO()
        self.writable = "x" in file.mode or "r" not in file.mode
        self.write = self.buffer.write if self.writable else None

    def read(self):
        while True:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            if not b:
                break
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines = 0
        return self.buffer.read()

    def readline(self):
        while self.newlines == 0:
            b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
            self.newlines = b.count(b"\n") + (not b)
            ptr = self.buffer.tell()
            self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr)
        self.newlines -= 1
        return self.buffer.readline()

    def flush(self):
        if self.writable:
            os.write(self._fd, self.buffer.getvalue())
            self.buffer.truncate(0), self.buffer.seek(0)


class IOWrapper(IOBase):
    def __init__(self, file):
        self.buffer = FastIO(file)
        self.flush = self.buffer.flush
        self.writable = self.buffer.writable
        self.write = lambda s: self.buffer.write(s.encode("ascii"))
        self.read = lambda: self.buffer.read().decode("ascii")
        self.readline = lambda: self.buffer.readline().decode("ascii")


sys.stdin, sys.stdout = IOWrapper(sys.stdin), IOWrapper(sys.stdout)
input = lambda: sys.stdin.readline().rstrip("\r\n")

def main():
    n,m=map(int,input().split())
    pairs=[]
    for i in range(m):
        a,b=map(int,input().split())
        temp=[]
        temp.append(a)
        temp.append(b)
        pairs.append(temp)
    fa=[i for i in range(n+1)]
    child=[1]*(n+1)
    def find(x):
        if x!=fa[x]:
            fa[x]=find(fa[x])
        return fa[x]
    def union(x,y):
        x = find(x)
        y = find(y)
        if x == y:  
            return
        fa[x] = y
        child[y]+=child[x]
    for (i,j) in pairs:
        union(i,j)
    
    
    
    
    
    print (max(child))

if __name__ == "__main__":
    main()

Solution (Python):
from collections import deque

def main():
    n, m = map(int, input().split())
    g = [[] for i in [0]*(n+1)]
    for _ in range(m):
        a, b = map(int, input().split())
        g[a].append(b)
        g[b].append(a)

    def bfs(n, m, adj):
        visited = [0 for i in [0]*(n+1)]
        ans = 1
        for i in range(n+1):
            if visited[i]:
                continue
            Q = deque([i])
            temp = 1
            while Q:
                q = Q.popleft()
                visited[q] = 1
                link = adj[q]
                for j in link:
                    if visited[j]:
                        continue
                    visited[j] = 1
                    temp += 1
                    Q.append(j)
            ans = max(ans, temp)
        print(ans)  
    bfs(n, m, g)
 
if __name__=="__main__":
    main()

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

    
    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 self.rank[x] < self.rank[y]:
            self.par[x] = y
        else:
            self.par[y] = x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
        
n,m = map(int,input().split())
a = [input().split() for l in range(m)]
uf = UnionFind(n)

for z in range(m):
    uf.union(int(a[z][0]), int(a[z][1]))
    
b = [0]*n

for r in range(1,n+1):
    b[uf.find(r)-1] += 1


print(max(b))

Solution (Python):
import sys
sys.setrecursionlimit(10**7)
def input(): return sys.stdin.readline().rstrip()

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 unite(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 main():
    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)
    roots = uf.roots()
    cnt = []
    for r in roots:
        cnt.append(uf.size(r))
    print(max(cnt))

if __name__ == '__main__':
    main()

Solution (Python):
class UnionFind:
    def __init__(self, N: int):
        self.parents = [-1] * N
        self.ranks = [-1] * N
        for i in range(N):
            self.ranks[i] = 0

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

    def unite(self, x, y):
        x = self.find_root(x)
        size_x = -self.parents[x]
        y = self.find_root(y)
        size_y = -self.parents[y]
        if self.ranks[x] < self.ranks[y]:
            self.parents[x] = y  
            self.parents[y] = -(size_x + size_y)
        else:
            self.parents[y] = x  
            self.parents[x] = -(size_x + size_y)
            
            if self.ranks[x] == self.ranks[y]:
                self.ranks[x] += 1

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

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


def get_input():
    N, M = (int(x) for x in input().split())
    rels = []
    for m in range(M):
        r = [int(x) - 1 for x in input().split()]  
        rels.append(r)
    return N, M, rels


N, M, rels = get_input()


tree = UnionFind(N)
for r in rels:
    x = r[0]
    y = r[1]
    if not tree.same(x, y):
        tree.unite(x, y)



max_size = 0
for i in range(N):
    s = tree.size(i)
    if max_size < s:
        max_size = s
print(max_size)

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

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

print(abs(min(uf.parents)))

Solution (Python):

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


par=[i for i in range(N)]
rank=[0]*N


def find(x):
  
  if par[x] == x:
    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
  
  if rank[x] < rank[y]:
    par[x] = y
  else:
    par[y] = x
    if rank[x] == rank[y]:
      rank[x]+=1



  

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

for i in range(N):
  find(i)
c=Counter(par)
c=c.most_common()[0][1]
print(c)

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 roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]

from sys import stdin
def input():
    return stdin.readline().strip()

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

uf = UnionFind(n)

for _ in range(m):
    i, j = map(int, input().split())
    uf.union(i-1, j-1)

ans = 0
for i in uf.roots():
    j = uf.size(i)
    if ans < j:
        ans = j

print(ans)

Solution (Python):
import math
ini = lambda : int(input())
inm = lambda : map(int,input().split())
inl = lambda : list(map(int,input().split()))
gcd = lambda x,y : gcd(y,x%y) if x%y else y
def factorization(n):
    arr = []
    temp = n
    for i in range(2, int(-(-n**0.5//1))+1):
        if temp%i==0:
            cnt=0
            while temp%i==0:
                cnt+=1
                temp //= i
            arr.append([i, cnt])
    if temp!=1:
        arr.append([temp, 1])
    if arr==[]:
        arr.append([n, 1])
    return arr
def make_divisors(n):
    divisors = []
    for i in range(1, int(n**0.5)+1):
        if n % i == 0:
            divisors.append(i)
            if i != n // i:
                divisors.append(n//i)
    divisors.sort()
    return divisors
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())
mod = 10**9 + 7



n,m = inm()
uf = UnionFind(n)
for i in range(m):
    a,b = inm()
    a -= 1
    b -= 1
    uf.union(a,b)

ans = 0
for i in range(n):
    ans = max(ans,uf.size(i))

print(ans)

Solution (Python):
import os

n,m = (int(x) for x in input().split())




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



par = [-1]*n

for i in range(m):
    a,b = (int(x)-1 for x in input().split())
    unite(a,b)

ans = 0
for i in range(0,n):
    ans = max([ans,size(i)])

print(ans)

Solution (Python):




class UnionFind():
    
    def __init__(self,N):
        self.N = 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 union(self,x,y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return 
        
        if self.par[x]>self.par[y]:
            x,y = y,x
        
        self.par[x] += self.par[y]
        self.par[y] = x
    

N,M=map(int,input().split())
uf = UnionFind(N)
for _ in range(M):
    a,b = map(int,input().split())
    a -= 1;b -= 1
    uf.union(a,b)
print(-min(uf.par))

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

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

root = [-1] * n

def r(x):
    if root[x] < 0:
        return x
    
    else:
        root[x] = r(root[x])
        return root[x]

def unite(x,y):
    x = r(x)
    y = r(y)
    if x == y:
        return
    root[x] += root[y]
    root[y] = x

def size(x):
    x = r(x)
    return -root[x]

for i in range(m):
    x,y = map(int,input().split())
    x -= 1
    y -= 1
    unite(x,y)


print(-min(root))

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)

ans = 0
for i in range(N):
  ans=max(ans, uf.size(i))
print(ans)

Solution (Python):


from collections import Counter

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



cc = [None for a in range(n + 1)] 

ccid = 0
for u in range(1, n + 1):
    if cc[u] != None:
        continue
    ccid += 1
    queue = [u]
    while len(queue) > 0:
        a = queue.pop()
        if cc[a] == None:
            cc[a] = ccid
            queue.extend(adj[a])

counter = Counter(cc)
print(max(counter.values()))

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())
A = [None] * M
B = [None] * M
for i in range(M):
    A[i], B[i] = map(int,input().split())
uf = UnionFind(N)
for j,h in zip(A,B):
    uf.Unite(j,h)
print(min(uf.root)*(-1))

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

    friends = [set() for _ in range(N)]
    for _ in range(M):
        a, b = map(lambda x: int(x)-1, input().split())
        friends[a].add(b)
        friends[b].add(a)
    

    visited = [0]*N 
    ans = 0
    for i in range(N):
        if visited[i]:
            continue
        tmp = list(friends[i])
        ans_tmp = 1
        visited[i] = 1
        while tmp:
            t = tmp.pop()
            if not visited[t]:
                visited[t] = 1
                ans_tmp += 1
                for j in friends[t]:
                    tmp.append(j)

        ans = max(ans, ans_tmp)
    print(ans)

if __name__ == '__main__':
    main()

Solution (Python):
def dfs(target, graph, visited):
    stack = []
    stack.append(target)
    visited[target] = True
    ans = 0
    while len(stack) > 0: 
        root = stack.pop()
        ans += 1
        for dst in graph[root]:
            if visited[dst] is False:
                visited[dst] = True
                stack.append(dst)
                pass 
    return ans 

n, m = map(int, input().split())
graph = {i:set() for i in range(n)}
for _ in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    graph[a].add(b)
    graph[b].add(a)
visited = [False]*n
ans = 1
for target in graph:
    if visited[target] is False:
        score = dfs(target, graph, visited)
        ans = max(ans, score)

print(ans)

Solution (Python):
N, M, *AB = [int(_) for _ in open(0).read().split()]


class UnionFind():
    def __init__(self, n):
        self.n = n
        self.root = [-1] * (n + 1)
        self.rank = [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 0
        elif 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 is_same(self, x, y):
        return self.find(x) == self.find(y)

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


uf = UnionFind(N)
for a, b in zip(AB[::2], AB[1::2]):
    uf.unite(a, b)
ans = max(uf.size(i) for i in range(1, N + 1))
print(ans)