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):
import sys
input=sys.stdin.readline


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

    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.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.Find_Root(x)==self.Find_Root(y)

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

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

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

    def group_members(self):
        return {i:self.members(i) for i in self.roots()}

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


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

UnionFind=UnionFind(n+1)
for a,b in AB:
    if UnionFind.isSameGroup(a,b) is False:
        UnionFind.Unite(a,b)

ans=0
for i in range(1,n+1):
    cnt=UnionFind.size(i)
    if ans<cnt:
        ans=cnt
print(ans)

Solution (Python):

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

par = [i for i in range(N+1)]
rank = [0 for i in range(N+1)]
 
def find(x):
    if x==par[x]:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
 
 
def unite(x,y):
    rx=find(x)
    ry=find(y)

    if rx==ry:
        return
    
    
    if rank[rx]<rank[ry]:
        par[rx]=ry
    else:
        par[ry]=rx

    if rank[rx]==rank[ry]:
        rank[rx]+=1
 

def some(x,y):
    return find(x)==find(y)
 
for i in range(M):
    a,b=map(int,input().split())
    unite(a,b)

for i in range(N):
    find(i+1)

cnt = [0 for i in range(N+1)]

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

print(max(cnt))

Solution (Python):
from math import floor,ceil,sqrt
import fractions
from collections import deque
import itertools
import collections
from heapq import *
N,M=map(int,input().split())
flship=[]
for i in range(M):
    s,e=map(int,input().split())
    if s<e:
        flship.append([s-1,e-1])
    else:
        flship.append([e-1,s-1])
flship=list(map(list, set(map(tuple, flship))))

tree=[[] for _ in range(N)]
for l in flship:
    tree[l[0]].append(l[1])
    tree[l[1]].append(l[0])

group=[-1]*N
l=[]
for i in range(N):
    d=deque()
    v=i
    if group[v]==-1:
        d.append(v)
        group[v]=i
    while len(d)>0:
        v=d.popleft()
        for j in tree[v]:
            if group[j]==-1:
                group[j]=i
                d.append(j)
    
c=collections.Counter(group)
values=list(c.values())	
key=list(c.keys())	
ans=0
for i in range(len(key)):
    ans=max(ans,values[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())

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 sys
sys.setrecursionlimit(10**9)


def unite(par, i, j):
    j = get_par(par, j)
    par[j] = get_par(par, i)

def get_par(par, p):
    while par[p] != p:
        p = par[p]
    return par[p]

def resolve():
    n,m = map(int, input().split())
    cnt = [1 for _ in range(n+1)]
    par = [i for i in range(n+1)]

    for i in range(m):
        a,b = map(int, input().split())
        aa = get_par(par, a)
        bb = get_par(par, b)
        
        if aa == bb:
            continue
        if cnt[aa] > cnt[bb]:
            par[bb] = aa
            cnt[aa] += cnt[bb]
        else:
            par[aa] = bb
            cnt[bb] += cnt[aa]
    

    
    print(max(cnt))

if __name__ == "__main__":
    resolve()

Solution (Python):

import sys;input = sys.stdin.readline
inp,ip = lambda :int(input()),lambda :[int(w) for w in input().split()]

import resource,sys

sys.setrecursionlimit(10**6)

def dfs(u):
    global graph,vis
    vis.add(u)
    for i in graph[u]:
        if i not in vis:
            dfs(i)

n,m = ip()
graph = {i:[] for i in range(1,n+1)}
for i in range(m):
    a,b = ip()
    graph[a].append(b)
    graph[b].append(a)
for i in graph:
    graph[i] = list(set(graph[i]))
vis = set()
ans = -1
prev = 0
for i in range(1,n+1):
    if i not in vis:
        dfs(i)
        t = len(vis)
        ans = max(ans,t-prev)
        prev = t
print(ans)

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

Solution (Python):
n,m=map(int,input().split())
par=[-1]*n


def find(x):
    global par
    if par[x]<0:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
        
def unite(x,y):
    x,y=find(x),find(y)
    global par
    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 size(x):
    return -par[find(x)]
def same(x,y):
    return find(x)==find(y)


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

par.sort()
print(-par[0])

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

n, m = map(int, input().split())
from collections import defaultdict
class UnionFind:
    def __init__(self, n):
        class KeyDict(dict):
            
            def __missing__(self,key):
                self[key] = key
                return key
        self.parent = KeyDict()
        self.rank = defaultdict(int)
        self.weight = defaultdict(int)

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

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

    
    def weighted_union(self, x, y, w):
        
        px = self.find(x)
        py = self.find(y)
        
        
        if self.rank[px] < self.rank[py]:
            self.parent[px] = py
            self.weight[px] = - w - self.weight[x] + self.weight[y]
        else:
            self.parent[py] = px
            self.weight[py] =  w + self.weight[x] - self.weight[y]
        if self.rank[px] == self.rank[py]:
            self.rank[px] += 1
        return 0

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

cnt = defaultdict(int)
uf = UnionFind(n)
for i in range(m):
    a,b = map(int, input().split())
    a -= 1
    b -= 1
    if not uf.judge(a,b): uf.union(a,b)
for i in range(n):
    cnt[uf.find(i)] += 1

print(max([cnt[k] for k in cnt.keys()]))

Solution (Python):
N,M=map(int,input().split())
bridge=[]
for i in range(M):
  a,b=map(int,input().split())
  bridge.append((a-1,b-1))


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])
    return par[x]
def union(a,b):
  x=find(a)
  y=find(b)
  if x!=y:
    if size[x]<size[y]:
      par[x]=par[y]
      size[y]+=size[x]
    else: 
      par[y]=par[x]
      size[x]+=size[y]
  else:
    return

for i in bridge:
    union(i[0],i[1])


print(max(size))

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)

max_size = max(map(size, range(n)))

print(max_size)

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

class UnionFindPathCompression():
    def __init__(self, n):
        self.parents = list(range(n))
        self.rank = [1]*n
        self.size = [1]*n
        

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

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

        if px == py:
            return
        else:
            if self.rank[px] < self.rank[py]:
                self.parents[px] = py
                self.size[py] += self.size[px]
            else:
                self.parents[py] = px
                self.size[px] += self.size[py]
                
                if self.rank[px] == self.rank[py]:
                    self.rank[px] += 1


N,M = map(int,input().split())
ufpc = UnionFindPathCompression(N)
AB = [list(map(int, input().split())) for _ in range(M)]
for a,b in AB:
    a,b = a-1,b-1
    ufpc.union(a,b)
    
for i in range(N):
    ufpc.find(i)

c = collections.Counter(ufpc.parents)
score_sorted = sorted(c.items(), key=lambda x:-x[1])
print(score_sorted[0][1])

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)
fr=[set() for _ in range(n)]
for i in range(m):
    a,b=map(int,input().split())
    fr[a-1].add(b-1)
    fr[b-1].add(a-1)
    uf.union(a-1,b-1)
x=0
for i in range(n):
  x=max(x,uf.size(i))
print(x)

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)
        self.size = [1] * (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
            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

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

import sys
import math
import copy
from heapq import heappush, heappop, heapify
from functools import cmp_to_key
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, Counter



input = sys.stdin.readline
getS = lambda: input().strip()
getN = lambda: int(input())
getList = lambda: list(map(int, input().split()))
getZList = lambda: [int(x) - 1 for x in input().split()]

INF = float("inf")
MOD = 10**9 + 7
divide = lambda x: pow(x, MOD-2, MOD)


class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n + 1)]
        self.rank = [0] * (n + 1)
        self.size = [1] * (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
            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

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

def solve():
    n, m = getList()
    uf = UnionFind(n + 1)
    for i in range(m):
        a, b = getList()
        if not uf.same_check(a, b):
            uf.union(a, b)

    print(max(uf.size))
def main():
    n = getN()
    for _ in range(n):
        solve()

    return
if __name__ == "__main__":
    
    solve()

Solution (Python):
import os
import sys
from io import BytesIO, IOBase

BUFSIZE = 8192
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 list2d(a, b, c): return [[c] * b for i in range(a)]
def list3d(a, b, c, d): return [[[d] * c for j in range(b)] for i in range(a)]
def list4d(a, b, c, d, e): return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]
def ceil(x, y=1): return int(-(-x // y))
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
INF = 10 ** 18
MOD = 10**9+7

from math import gcd

from types import GeneratorType
def bootstrap(func, stack=[]):
    def wrapped_function(*args, **kwargs):
        if stack:
            return func(*args, **kwargs)
        else:
            call = func(*args, **kwargs)
            while True:
                if type(call) is GeneratorType:
                    stack.append(call)
                    call = next(call)
                else:
                    stack.pop()
                    if not stack:
                        break
                    call = stack[-1].send(call)
            return call
 
    return wrapped_function

Ri = lambda : [int(x) for x in sys.stdin.readline().split()]
ri = lambda : sys.stdin.readline().strip()

n,m = Ri()
par = [i for i in range(n)]
val = [1 for i in range(n)]

@bootstrap
def find(chi):
    if par[chi] == chi:
        yield chi
    temp = yield find(par[chi])
    par[chi] = temp
    yield temp

def union(a,b):
    pa,pb = find(a),find(b)
    par[pb] = pa
    val[pa]+=val[pb]

ncc= n
for i in range(m):
    a,b = Ri();a-=1;b-=1
    pa,pb = find(a),find(b)
    if pa != pb:
        ncc-=1
        union(a,b)

lis = []
se = set()
for i in range(n):
    p = find(i)
    if p not in se:
        se.add(p)
        lis.append(val[p])
lis.sort()
ans = 0
summ = 0
for i in range(len(lis)):
    val = (lis[i]-summ)
    ans+=val
    summ+=val
print(ans)

Solution (Python):
import math,itertools,fractions,heapq,collections,bisect,sys,queue,copy

sys.setrecursionlimit(10**7)
inf=10**20
mod=10**9+7
dd=[(-1,0),(0,1),(1,0),(0,-1)]
ddn=[(-1,0),(-1,1),(0,1),(1,1),(1,0),(1,-1),(0,-1),(-1,-1)]

def LI(): return [int(x) for x in sys.stdin.readline().split()]

def I(): return int(sys.stdin.readline())
def F(): return float(sys.stdin.readline())
def LS(): return sys.stdin.readline().split()
def S(): return input()


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

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

  def find(self,k):
    if self.data[k]<0:
      return k
    self.data[k]=self.find(self.data[k])
    return self.data[k]

  def size(self,k):
    return -self.data[self.find(k)]


def main():
  N,M=LI()
  uf=UnionFind(N)

  for _ in range(M):
    a,b=LI()
    a-=1
    b-=1
    uf.unite(a,b)

  d={}
  renketsu=0
  for i in range(N):
    par=uf.find(i)
    if par not in d:
      d[par]=uf.size(i)

  l=[]
  for value in d.values():
    l.append(value)

  

  l.sort()
  ans=0
  now=0

  for x in l:
    nxt=x
    x-=now
    ans+=x
    now=nxt

  return ans


print(main())

Solution (Python):
from collections import Counter
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**9)


class UnionFind:
    def __init__(self, numV):
        self.pars = list(range(numV))
        self.ranks = [0] * numV
    def getRoot(self, x):
        par = self.pars[x]
        if par != x:
            self.pars[x] = par = self.getRoot(par)
        return par
    def merge(self, x, y):
        x, y = self.getRoot(x), self.getRoot(y)
        if x == y: return
        if self.ranks[x] < self.ranks[y]:
            self.pars[x] = y
        else:
            self.pars[y] = x
            if self.ranks[x] == self.ranks[y]:
                self.ranks[x] += 1
    def isSame(self, x, y):
        return self.getRoot(x) == self.getRoot(y)
    def updatePars(self):
        for v in range(len(self.pars)):
            self.getRoot(v)


N, M = map(int, input().split())
UF = UnionFind(N)
for _ in range(M):
    A, B = map(int, input().split())
    A, B = A-1, B-1
    UF.merge(A, B)

UF.updatePars()


cnt = Counter(UF.pars)


ans = max(cnt.values())
print(ans)

Solution (Python):


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


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


par = [-1]*n


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


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

for i in range(M):
    x,y=map(int,input().split())
    x,y=x-1,y-1
    u.union(x,y)

x=u.parents
ans=10**10
for i in x:
    ans=min(ans,i)

print(ans*(-1))

Solution (Python):
import collections

n, m = map(int, input().split())
g = [[] for _ in range(n)]
for _ in range(m):
    src, dst = map(int, input().split())
    src -= 1
    dst -= 1
    g[src].append(dst)
    g[dst].append(src)


UNDEF = -1
components = [UNDEF] * n
ncomponent = 0


for i in range(n):
    if components[i] == UNDEF:
        q = collections.deque([])
        ncomponent += 1
        q.append(i)
        components[i] = ncomponent
        while q:
            node = q.popleft()
            for other in g[node]:
                if components[other] == UNDEF:
                    components[other] = ncomponent
                    q.append(other)


print(max(collections.Counter(components).values()))

Solution (Python):
from collections import defaultdict
import sys
sys.setrecursionlimit(10 ** 6)
N, M = [int(s) for s in input().split()]
edges = defaultdict(list)
for _ in range(M):
    A, B = [int(s) for s in input().split()]
    edges[A].append(B)
    edges[B].append(A)

def dfs(node):
    for nn in edges[node]:
        if nn not in seen:
            
            
            seen.add(nn)
            unseen.remove(nn)
            dfs(nn)

maxsize = 0
unseen = set(range(1, N + 1))
seen = set()
while unseen:
    sf = len(unseen)
    node = unseen.pop()
    seen.add(node)
    dfs(node)
    maxsize = max(maxsize, sf - len(unseen))

print(maxsize)

Solution (Python):

class DisjointSet:

    def __init__(self, N):
        self.parents = [i for i in range(N)]
        self.size = [1]*N

    def find_parent(self, x):
        path = []
        while self.parents[x] != x:
            x = self.parents[x]
            path.append(x)
        for p in path:
            self.parents[p] = x
        return x

    def find_size(self, x):
        return self.size[self.find_parent(x)]

    def union(self, x, y):
        root_x = self.find_parent(x)
        root_y = self.find_parent(y)
        if root_x != root_y:
            self.parents[root_x] = root_y
            self.size[root_y] += self.size[root_x]

def read_int():
    return int(input().strip())


def read_ints():
    return list(map(int, input().strip().split(' ')))


def solve():
    N, M = read_ints()
    disjoint_set = DisjointSet(N)
    for _ in range(M):
        a, b = read_ints()
        disjoint_set.union(a-1, b-1)
    return max(disjoint_set.size)


if __name__ == '__main__':
    print(solve())

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):
        d = {}
        for i in range(self.n):
            p = self.find(i)
            d[p] = d.get(p, []) + [i]
        return d

    def __str__(self):
        return '\n'.join('{}: {}'.format(k, v) for k, v in self.all_group_members().items())


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


if __name__ == '__main__':
    resolve()

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

def main():
    N, M = map(int, input().split())
    uni = UnionFind(N)
    for _ in range(M):
        A, B = map(int, input().split())
        A -= 1
        B -= 1
        uni.union(A,B)
    cnt = 0
    for i in range(N):
        cnt = max(cnt,uni.size(i))

    print(cnt)
    



if __name__ == "__main__":
    main()

Solution (Python):


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



n,m = map(int,input().split())
par = [-1]*n
ans = 0
for i in range(m):
  x,y = map(int,input().split())
  unite(x-1,y-1)
for i in range(n):
  ans = max(ans,size(i))
print(ans)

Solution (Python):

import sys


def solve(N: int, M: int, A: "List[int]", B: "List[int]"):
    uf = UnionFind(N)
    for a, b in zip(A, B):
        uf.union(a-1, b-1)
    sizes = [uf.size(r) for r in uf.roots()]
    return max(sizes)


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



def main():
    def iterate_tokens():
        for line in sys.stdin:
            for word in line.split():
                yield word
    tokens = iterate_tokens()
    N = int(next(tokens))  
    M = int(next(tokens))  
    A = [int()] * (M)  
    B = [int()] * (M)  
    for i in range(M):
        A[i] = int(next(tokens))
        B[i] = int(next(tokens))
    print(solve(N, M, A, B))

def test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    
    main()