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):
N,M = map(int,input().split())

color = []
colorStorage = []
for i in range(N):
    color.append(i)
    colorStorage.append([i])

for _ in range(M):
    p,q = map(int,input().split())
    p -= 1
    q -= 1
    if color[p] == color[q]:
        continue
    else:
        x = color[p]
        y = color[q]
        if len(colorStorage[x]) >= len(colorStorage[y]):
            for elem in colorStorage[y]:
                color[elem] = x
                colorStorage[x].append(elem)
            colorStorage[y] = []
        else:
            for elem in colorStorage[x]:
                color[elem] = y
                colorStorage[y].append(elem)
            colorStorage[x] = []
maxL = 0
for colorList in colorStorage:
    if maxL < len(colorList):
        maxL = len(colorList)
print(maxL)

Solution (Python):
class union_find:
    def __init__(self, N):
        
        self.par = [-1 for i in range(N)]
    
    def root(self, i):
        if self.par[i] < 0:
            return i
        else:
            
            self.par[i] = self.root(self.par[i])
            return self.par[i]
    
    def same(self, a, b):
        return self.root(a) == self.root(b)
    
    def unite(self, a, b):
        if not self.same(a, b):
            self.par[self.root(a)] += self.par[self.root(b)]
            self.par[self.root(b)] = self.root(a)

N, M = list(map(int, input().split()))
UF = union_find(N)
for _ in range(M):
    A, B = list(map(lambda x: int(x) - 1, input().split()))
    UF.unite(A, B)
    
print(-min(UF.par))

Solution (Python):
n, m = map(int, input().split())
class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [i for i in 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):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            self.parents[x] = y
            self.size[y] += self.size[x] 
        else:
            self.parents[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

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

    

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

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

    
    def roots(self):
        return [i for i, x in enumerate(self.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()}


uf = UnionFind(n)


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

print(max([uf.group_size(x) for x in uf.parents]))

Solution (Python):
import sys
import bisect
from functools import lru_cache
from collections import defaultdict
inf = float('inf')
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10**6)
def input(): return sys.stdin.readline().rstrip()
def read():
  return int(readline())
def reads():
  return map(int, readline().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 unite(self,x,y):
        
        x,y=self.find(x),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 roots(self):
        
        return [i for i, x in enumerate(self.parents) if x<0]
    def group_count(self):
        
        return len(self.roots())
    def members(self, x):
        root = self.find(x)
        return len([i for i in range(self.n) if self.find(i) == root])
    
    

n,m=reads()
uf=UnionFind(n)
a,b=[0 for i in range(m)],[0 for i in range(m)]
for i in range(m):
    a,b=reads()
    uf.unite(a-1,b-1)
ls=uf.roots()
dic=defaultdict(int)
max=0
y=0
for i in range(n):
    dic[uf.find(i)]+=1

for num in dic.values():
    if num>max:
        max=num
print(max)

Solution (Python):
n,m = map(int,input().split())
import sys
sys.setrecursionlimit(10**9)
rks = [None] *n
p = [set([]) for i in range(n)]
flist = [[] for i in range(n)]
for i in range(m):
    a,b = map(int,input().split())
    flist[a-1].append(b-1)
    flist[b-1].append(a-1)
def dfs(graph,w,c):
    if rks[w] is None:
        rks[w] = 0
    for i in range(len(graph[w])):
        if rks[graph[w][i]] is not None:
            continue
        p[c].add(flist[w][i])
        dfs(graph, graph[w][i],c)
c = -1
for w in range(n):
    c += 1
    if rks[w] is None:
        dfs(flist,w,c)
ans = 0
for i in range(n):
    ans = max(ans,len(p[i])+1)
print(ans)

Solution (Python):



from fractions import gcd
from itertools import combinations,permutations,accumulate, product 

from collections import deque,defaultdict,Counter
import decimal
import re
import math
import bisect














import sys
sys.setrecursionlimit(10000000)
mod = 10**9 + 7


from sys import stdin
readline = stdin.readline
def readInts():
  return list(map(int,readline().split()))
def readTuples():
    return tuple(map(int,readline().split()))
def I():
  return int(readline())
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 = readInts()






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

Solution (Python):

MOD = 10 ** 9 + 7
INFI = 10**10

import math
from collections import deque
import itertools
import heapq

from fractions import Fraction
import copy
from functools import lru_cache
from collections import defaultdict
import pprint




def sosuhante(n):
    for k in range(2, int(math.sqrt(n))+1):
        if n% k ==0:
            return False
    return True
def cmb(n, r):
    if n - r < r: r = n - r
    if r == 0: return 1
    if r == 1: return n

    numerator = [n - r + k + 1 for k in range(r)]
    denominator = [k + 1 for k in range(r)]

    for p in range(2,r+1):
        pivot = denominator[p - 1]
        if pivot > 1:
            offset = (n - r) % p
            for k in range(p-1,r,p):
                numerator[k - offset] /= pivot
                denominator[k] /= pivot

    result = 1
    for k in range(r):
        if numerator[k] > 1:
            result *= int(numerator[k])

    return result

def kingaku(a,b,n):
    keta=len(str(n))
    return a*n+b*keta

def my_index(l, x, default=False):
    if x in l:
        return l.index(x)
    else:
        return default




def ret(a):
    c=[None]*(len(a)-1)
    if len(a)==1:
        return a[0]
    elif len(a)==0:
        return 0
    for i in range(1,len(a)):
        c[i-1]=abs(a[i]-a[i-1])
    return ret(c)

def soinsubunkai(n):
    a = []
    i = 1
    while i*i <= n:
        if n % i == 0 and i!=1:
            a.append(i)
            n=n//i

        if n% i !=0 or i==1:
            i += 1
    nokori=[n]
    return a + nokori

def make_divisors(n):
    lower_divisors , upper_divisors = [], []
    i = 1
    while i*i <= n:
        if n % i == 0:
            lower_divisors.append(i)
            if i != n // i:
                upper_divisors.append(n//i)
        i += 1
    return lower_divisors + upper_divisors[::-1]

def main():
    
    n,m = map(int, input().split())
    tomo=[[] for i in range(n)]
    for i in range(m):
        a,b=map(int,input().split())
        tomo[a-1].append(b-1)
        tomo[b-1].append(a-1)
    visited=[0 for i in range(n)]
    stack=[]
    group=0
    temp=0
    for i in range(n):
        visited[i]=1
        temp=1
        for j in tomo[i]:
            if visited[j]==0:
                stack.append(j)
                visited[j]=1
                temp+=1
        while len(stack)>=1:
            v = stack.pop(-1)
            for j in tomo[v]:
                if visited[j]==0:
                    stack.append(j)
                    visited[j]=1
                    temp+=1
        group=max(group,temp)
    print(group)






if __name__ == "__main__":

    main()

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

    G=[[] for i in range(N)]

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

    trace=[-1 for i in range(N)]
    GroupN=[]

    for i in range(N):
        stack=[]
        if trace[i]==-1:
            trace[i]=0
            stack.append(i)
        Group_tmp=[]
        while len(stack)>0:
            index=stack.pop()
            Group_tmp.append(index)
            for j in G[index]:
                if trace[j]==-1:
                    trace[j]=0
                    stack.append(j)
        if len(Group_tmp)!=0:
            GroupN.append(len(Group_tmp))

    print(max(GroupN))


if __name__=="__main__":
    main()

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

from collections import deque
 
def bfs():
  ans = 1
  done = set()
  for i in range(N):
    if i in done: continue
    queue = deque([i])
    num = 0
    while queue:
      p = queue.popleft()
      for p2 in F[p]:
        if p2 in done: continue
        done.add(p2)
        queue.append(p2)
        num += 1
    ans = max(ans,num)
  return ans
print(bfs())

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)

print(max([uf.size(i) for i in range(N)]))

Solution (Python):
from sys import stdin,stdout
from collections import defaultdict
import math
from bisect import bisect
input=stdin.readline

n,m=map(int,input().split())
l=[0]*n
d=defaultdict(set)
for i in range(m):
    v1,v2=map(int,input().split())
    d[v1-1].add(v2-1)
    d[v2-1].add(v1-1)
for i in d:
    d[i]=list(d[i])
ans=[]
for i in range(n):
    s=[]
    c=0
    if not l[i]:
        s.append(i)
        l[i]=1
        c=1
        for j in s:
            for k in d[j]:
                if not l[k]:
                    s.append(k)
                    l[k]=1
                    c+=1
        ans.append(c)

print(max(ans))

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

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

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

    def same(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        return rx == ry

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

    def group_size(self):
        return {i: -v for i, v in enumerate(self.parents) if v < 0}

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

Solution (Python):



  
class DisjSet: 
    def __init__(self, n): 
        
        
        self.rank = [1] * n 
        self.parent = [i for i in range(n)] 
  
  
    
    def find(self, x): 
          
        
        
        if (self.parent[x] != x): 
              
            
            
            
            self.parent[x] = self.find(self.parent[x]) 
              
            
            
            
  
        return self.parent[x] 
  
  
    
    
    def Union(self, x, y): 
          
        
        xset = self.find(x) 
        yset = self.find(y) 
  
        
        if xset == yset: 
            return
  
        
        
        
        if self.rank[xset] < self.rank[yset]: 
            self.parent[xset] = yset 
  
        elif self.rank[xset] > self.rank[yset]: 
            self.parent[yset] = xset 
  
        
        
        
        else: 
            self.parent[yset] = xset 
            self.rank[xset] = self.rank[xset] + 1
  

'''obj = DisjSet(5) 
obj.Union(0, 2) 
obj.Union(4, 2) 
obj.Union(3, 1) 
if obj.find(4) == obj.find(0): 
    print('Yes') '''
n,m=map(int,input().split())
obj = DisjSet(n)
for i in range(m):
    a,b=map(int,input().split())
    obj.Union(a-1,b-1) 
c=0
l1=[0]*n
for i in range(n):
    l1[obj.find(i)]+=1
print(max(l1))

Solution (Python):
from collections import Counter

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

par = [i for i in range(n + 1)]
rank = [0 for _ in range(n + 1)]

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

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

def unite(x, y):
    x = root(x)
    y = root(y)

    if rank[x] < rank[y]:
        par[x] = y
    else:
        par[y] = x
        if rank[x] == rank[y]:
            rank[x] += 1

for a, b in edges:
    unite(a, b)

roots = [0 for _ in range(n + 1)]
for i in range(1, n + 1):
    roots[i] = root(i)

roots_cnt = Counter(roots)
print(max(roots_cnt.values()))

Solution (Python):
N, M = map(int, input().split())
ad_list = {}
for i in range(M):
  a, b = map(int, input().split())
  if a in ad_list:
    ad_list[a].add(b)
  else:
    ad_list[a] = {b}
  if b in ad_list:
    ad_list[b].add(a)
  else:
    ad_list[b] = {a}


ans = 0
done = [True for i in range(N+1)]

import queue
q = queue.Queue()

for i in range(1, N+1):
  if done[i]:
    done[i] = False
    tmp = 1
    if i in ad_list:
      q.put(i)
      while not q.empty():
        x = q.get()
        for y in ad_list[x]:
          if done[y]:
            tmp += 1
            done[y] = False
            q.put(y)
    ans = max(ans, tmp)

print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10000000)

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

for i in range(m):
  a,b=map(int,input().split())
  if a-1 in friend:
    friend[a-1].append(b-1)
  else:
    friend[a-1] = [b-1]
  if b-1 in friend:
    friend[b-1].append(a-1)
  else:
    friend[b-1] = [a-1]

memo = [0]*n

def dfs(who,v):
  if memo[who]:
    return 0
  memo[who] = v
  res = 1
  if who not in friend:
    return 1
  for x in friend[who]:
    res += dfs(x, v)
  return res

ans = 0
c = 1
for i in range(n):
  if not memo[i]:
    ans = max(ans, dfs(i,c))
    c += 1
print(ans)

Solution (Python):
class UnionFind():
    def __init__(self, n):
        self.n = n
        
        self.root = [-1]*(n)
        
        self.rank = [0]*(n)
        
        self.maxmem = 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.rank[x] > self.rank[y]:
            self.root[x] += self.root[y]
            self.root[y] = x
            if self.maxmem < -1*self.root[x]:
                self.maxmem = -1*self.root[x]
        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            if(self.rank[x] == self.rank[y]):
                self.rank[y] += 1
            if self.maxmem < -1*self.root[y]:
                self.maxmem = -1*self.root[y]
    def same(self, x, y):
        return self.find_root(x) == self.find_root(y)
    
    def count(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, x in enumerate(self.root) if x < 0]

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

    def all_group_members(self):
        return {r: self.members(r) for r in self.roots()}
    
n, m = map(int,input().rstrip().split())
ab = [list(map(int,input().split()))for _ in range(m)]

u = UnionFind(n)
for a,b in ab:
    u.unite(a-1,b-1)
print(u.maxmem)

Solution (Python):
n, m  = map(int,  input().split())
vertices = range(1,n+1)
adj =  {v: set() for  v  in vertices}
for _  in range(m):
    s, t  = map(int,  input().split())
    adj[s].add(t)
    adj[t].add(s)

ans = 0
reached = {v: False for v in vertices}
for v in vertices:
    if not reached[v]:
        i = 1
        reached[v] = True
        stack = [v]
        while stack:
            w = stack.pop()
            for u in  adj[w]:
                if not reached[u]:
                    reached[u] = True
                    stack.append(u)
                    i += 1
        ans = max(ans, i)
print(ans)

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 range(N):
    ans = max(ans, uf.size(i))
print(ans)

Solution (Python):
def resolve():
    
    
    
    
    n,m=map(int,input().split())
    f=[set() for _ in range(n)]
    for i in range(m):
        a,b=map(int,input().split())
        f[a-1].add(b-1)
        f[b-1].add(a-1)
    chk=[False]*n
    q=[]
    ans=0
    for i in range(n):
        if chk[i]==True:
            continue
        q.append(i)
        chk[i]=True
        cnt=1
        while q:
            x=q.pop()
            for nx in f[x]:
                if chk[nx]==True:
                    continue
                q.append(nx)
                chk[nx]=True
                cnt+=1
        ans=max(ans,cnt)
    print(ans)

if __name__ == '__main__':
    resolve()

Solution (Python):
from __future__ import division, print_function
import sys
if sys.version_info[0] < 3:
    from __builtin__ import xrange as range
    from future_builtins import ascii, filter, hex, map, oct, zip

import os, sys, bisect, copy
from collections import defaultdict, Counter, deque

if os.path.exists('in.txt'): sys.stdin=open('in.txt','r')
if os.path.exists('out.txt'): sys.stdout=open('out.txt', 'w')

def input(): return sys.stdin.readline()
def mapi(arg=0): return map(int if arg==0 else str,input().split())



n,m = mapi()
gr = defaultdict(list)
sz = [1]*(n+1)
par = {i:i for i in range(n+1)}
def find(a):
    if par[a]==a:return a
    par[a] = find(par[a])
    return par[a]
def union(a,b):
    a = find(a)
    b = find(b)
    if a==b:return
    if sz[a]>sz[b]:a,b = b,a
    sz[b]+=sz[a]
    par[a] = b

for i in range(m):
    x,y = mapi()
    union(x,y)
    
    
res = 0
for i in range(1,n+1):
    res = max(res,sz[i])
print(res)

Solution (Python):


import sys
iim = lambda: map(int, sys.stdin.readline().rstrip().split())

def resolve():
    N, M = iim()
    it = map(int, sys.stdin.read().split())

    dp = [-1] * N

    def find(x):
        if dp[x] < 0:
            return  x

        ans = dp[x] = find(dp[x])
        return ans

    def union(x, y):
        x1 = find(x)
        y1 = find(y)

        if x1 == y1:
            return

        xr = dp[x1]
        yr = dp[y1]
        if xr <= yr:
            dp[y1] = x1
            dp[x1] += yr
        else:
            dp[x1] = y1
            dp[y1] += xr

    for ai, bi in zip(it, it):
        union(ai-1, bi-1)

    d1 = [0]*N
    for i in range(N):
        d1[find(i)] += 1
    print(max(d1))

if __name__ == "__main__":
    resolve()

Solution (Python):
from collections import deque

R = lambda: map(int, input().split())

n, m = R()
g = [None] + [set() for _ in range(n)]

for _ in range(m):
  u, v = R()
  g[u].add(v)
  g[v].add(u)

V = [None] + [False] * n
q = deque()

def bfs(u):
  r = 0
  V[u] = True
  q.append(u)
  while(q):
    u = q.popleft()
    r += 1
    for v in g[u]:
      if not V[v]:
        V[v] = True
        q.append(v)
  return r

print(max(bfs(u) for u in range(1, n + 1) if not V[u]))

Solution (Python):

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

    
    def Find_Root(self, x):
        if(self.root[x] < 0):
            return x
        else:
            
            self.root[x] = self.Find_Root(self.root[x])
            return self.root[x]
    
    def Unite(self, x, y):
        
        x = self.Find_Root(x)
        y = self.Find_Root(y)
        
        if(x == y):
            return 
        
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

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

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

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

for i in range(M):
    A, B = map(int,input().split())
    uf.Unite(A, B)
M = 0
for i in range(N):
    cnt = uf.Count(i)
    if cnt>M:
        M = cnt

print(M)

Solution (Python):
import collections
import itertools
import operator


class UnionFind:
    def __init__(self, elems=None):
        class KeyDict(dict):
            def __missing__(self, key):
                self[key] = key
                return key

        self.parent = KeyDict()
        self.rank = collections.defaultdict(int)

        if elems is not None:
            for elem in elems:
                _, _ = self.parent[elem], self.rank[elem]

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

    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if 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 are_same(self, x, y):
        return self.find(x) == self.find(y)

    def grouper(self):
        roots = [(x, self.find(x_par)) for x, x_par in self.parent.items()]
        root = operator.itemgetter(1)
        for _, group in itertools.groupby(sorted(roots, key=root), root):
            yield [x for x, _ in group]


uf = UnionFind()


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

g = list(uf.grouper())

ans = 1
for i in g:
    ans = max(ans, len(i))

print(ans)

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

    def root(self, A):
        
        
        
        if self.parent[A] < 0:
            return A
        self.parent[A] = self.root(self.parent[A])
        return self.parent[A]

    def size(self, A):
        
        return -self.parent[self.root(A)]

    def unite(self, A, B):
        
        
        A = self.root(A)
        B = self.root(B)

        if A == B:
            return False  

        if self.size(A) < self.size(B):
            
            
            A, B = B, A

        
        self.parent[A] += self.parent[B]
        
        self.parent[B] = A

        return True

    def same(self, A, B):
        return self.root(A) == self.root(B)


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

uf = UnionFind(N)

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

fri = [0] * N
for i in range(N):
    fri[i] = uf.size(i)

print(max(fri))

Solution (Python):
from collections import deque
n,m=map(int,input().split())
nm=[[] for _ in range(n+1)]
for i in range(m):
    a,b=map(int,input().split())
    nm[a].append(b)
    nm[b].append(a)
for i in range(n):
    nm[i]=list(set(nm[i]))
visited=[0]*(n+1)
count=0
for i in range(n):
    if visited[i]==0:
        stack=deque()
        stack.append(i)
        visited[i]+=1
        temp=1
        while stack:
            x=stack.pop()
            
            for j in nm[x]:
                if visited[j]==0:
                    visited[j]+=1
                    stack.append(j)
                    temp+=1
        count=max(temp,count)
print(count)

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


N, M = map(int, input().split())
to = [[] for _ in range(N)]
count = 0

for _ in range(M):
    A, B = map(lambda x:int(x) - 1, input().split())
    to[A].append(B)
    to[B].append(A)


def dfs(v, to, seen):
    global count
    seen[v] = True
    count += 1
    for nv in to[v]:
        if seen[nv]:
            continue
        dfs(nv, to, seen)


def main():
    global count
    seen = [False] * N
    cnts = []
    for i in range(N):
        if not seen[i]:
            dfs(i, to, seen)
            cnts.append(count)
            count = 0
    
    print(max(cnts))


if __name__ == "__main__":
    main()

Solution (Python):
n,m=map(int,input().split())

global fri
fri=[]
global tab
tab=[0]*n
def run(nn):
  
  global cnt
  if tab[nn]:
    return
  tab[nn]=1
  cnt+=1
  for i in fri[nn]:
    que.append(i)
for i in range(n):
  fri.append([])
for i in range(m):
  a,b=map(int,input().split())
  fri[a-1].append(b-1)
  fri[b-1].append(a-1)
i=0
mx=0

while i<n:
  if tab[i]:
    i+=1
    continue
  que=[i]
  cnt=0
  while len(que)!=0:
    run(que.pop())
  mx=max(cnt,mx)
  i+=1
print(mx)

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
g = uf.roots()
for i in g:
    ans = max(ans, uf.size(i))

print(ans)