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

def input(): return sys.stdin.readline().strip()
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 INT(): return int(input())
def MAP(): return map(int, input().split())
def LIST(N=None): return list(MAP()) if N is None else [INT() for i in range(N)]
def Yes(): print('Yes')
def No(): print('No')
def YES(): print('YES')
def NO(): print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** -10

class UnionFind:
    """ Union-Find木 """

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

    def find(self, x):
        """ 根の検索(グループ番号の取得) """
        t = []
        while self.par[x] != x:
            t.append(x)
            x = self.par[x]
        for i in t:
            self.par[i] = x
        return self.par[x]

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

        if x == y:
            self.tree[x] = False
            return
        if not self.tree[x] or not self.tree[y]:
            self.tree[x] = self.tree[y] = False

        self.grpcnt -= 1
        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 is_same(self, x, y):
        """ 同じ集合に属するか判定 """
        return self.find(x) == self.find(y)

    def get_size(self, x=None):
        if x is not None:
            """ あるノードの属する集合のノード数 """
            return self.size[self.find(x)]
        else:
            """ 集合の数 """
            return self.grpcnt
    
    def is_tree(self, x):
        """ 木かどうかの判定 """
        return self.tree[self.find(x)]

N, M = MAP()
uf = UnionFind(N)
for i in range(M):
    a, b = MAP()
    a -= 1; b -= 1
    uf.union(a, b)

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

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 main():
    N, M = map(int, input().split())
    unf = UnionFind(N)
    for i in range(M):
        A, B = map(int, input().split())
        if not unf.same(A-1, B-1):
            unf.union(A-1, B-1)

    print(-min(unf.parents))

    
if __name__ == '__main__':
    main()

Solution (Python):
import sys
from collections import deque

stdin = sys.stdin
def ns(): return stdin.readline().rstrip()
def ni(): return int(stdin.readline().rstrip())
def nm(): return map(int, stdin.readline().split())
def nl(): return list(map(int, stdin.readline().split()))


def main():
    n, m = nm()
    friends = [set() for _ in range(n)]
    for i in range(m):
        a, b = nm()
        friends[a - 1].add(b - 1)
        friends[b - 1].add(a - 1)

    groups = []
    in_group = [False] * n
    for i in range(n):
        if in_group[i]:
            continue
        d = deque(friends[i])
        group = [i]
        in_group[i] = True
        while d:
            c = d.pop()
            if in_group[c]:
                continue
            group.append(c)
            in_group[c] = True
            for friend in friends[c]:
                if not in_group[friend]:
                    d.append(friend)
        groups.append(group)

    ans = 0
    for group in groups:
        ans = max(ans, len(group))
    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
import random
import sys

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

group = {i: 0 for i in range(1, n+1)}
edge = {}
g_mem = {}
g_num = 0
g_con = set()

for i in range(m):
    a, b = map(int, input().split())
    
    if group[a]==0 and group[b] == 0:
        g_num += 1
        group[a] = g_num
        group[b] = g_num
        g_mem[g_num] = 2
    elif group[a] == 0:
        group[a] = group[b]
        g_mem[group[b]] += 1
    elif group[b] == 0:
        group[b] = group[a]
        g_mem[group[a]] += 1
    elif group[a] != group[b]:
        if edge.get(group[a]):
            edge[group[a]].add(group[b])
        else:
            edge[group[a]] = {group[b]}
        if edge.get(group[b]):
            edge[group[b]].add(group[a])
        else:
            edge[group[b]] = {group[a]}





g_reached = {i: 0 for i in range(1, g_num+1)}
ans = list(g_mem.values())
for now in range(1, g_num+1):
    if g_reached[now] == 0:
        g_reached[now] = 1
        if edge.get(now):
            count = g_mem[now]
            queue = set(edge[now])
            while len(queue) > 0:
                next_now = queue.pop()
                if g_reached[next_now] == 0:
                    g_reached[next_now] = 1
                    count += g_mem[next_now]
                    queue |= edge[next_now]
                queue -= {now}
                now = next_now
            ans.append(count)



if len(ans) > 0:
    print(max(ans))
else:
    print(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)

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

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

print(ans)

Solution (Python):
from collections import defaultdict, deque
n, m = map(int, input().split())
g = defaultdict(set)

if m == 0:
    print(1)

else:
    for _ in range(m):
        a, b = map(int, input().split())
        g[a - 1].add(b - 1)
        g[b - 1].add(a - 1)


    visited = [False]*n
    ans = 0
    for i in range(n):
        if not visited[i]:
            
            count = 1
            q = deque([i])
            visited[i] = 1
            while q:
                node = q.pop()
                for nbr in g[node]:
                    if not visited[nbr]:
                        q.append(nbr)
                        visited[nbr] = True
                        count += 1
                
            
            ans = max(ans, count)

    print(ans)

Solution (Python):

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

par = [i for i in range(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:
    par[x] = y
    find(x)
  else:
    par[y] = x
    find(y)
if M > 0:  
  for i in range(M):
    a, b = map(int, input().split())
    unite(a - 1, b - 1)
  
  ans = [0] * N
  Max = 0
  for i in range(N):
    find(i)
  for i in par:
    ans[i] += 1
  for i in ans:
    if i > Max:
      Max = i
  
  print(Max)
else:
  print(1)

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 _ in range(m):
    a,b = map(int,input().split())
    unite(a-1,b-1)

arr = []
for i in range(n):
    if par[i]<0:
        arr.append(-par[i])

print(max(arr))

Solution (Python):
def resolve():
    '''
    code here
    '''
    N, M = [int(item) for item in input().split()]

    edges = [[int(item) for item in input().split()] for _ in range(M)]
    links = [set() for _ in range(N+1)]


    for a, b in edges:
        links[a].add(a) 
        links[a].add(b)
        links[b].add(a)
        links[b].add(b)


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

    uf = UnionFind(N+1)
    for i, item in enumerate(links):
        for j in item:
            uf.Unite(i,j)

    res = 0
    for i in range(1, N+1):
        res = max(res, uf.Count(i))
        

    print(res)

        


if __name__ == "__main__":
    resolve()

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

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

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

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

for _ in range(m):
    a, b = map(int, input().split())
    unite(a - 1, b - 1)
max = 0
for x in range(n):
    s = size(x)
    if s > max:
        max = s
print(max)

Solution (Python):
from collections import defaultdict


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())
R = [tuple(map(int, input().split())) for _ in range(M)]

uf = UnionFind(N)
for a, b in R:
    uf.union(a-1, b-1)

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

print(ans)

Solution (Python):
n,m = map(int,input().split())
g = [set() for i in range(n)]
visited = [False] * n
group = []

for i in range(m):
    a,b = map(int,input().split())
    a -= 1
    b -= 1
    g[a].add(b)
    g[b].add(a)

for i in range(n):
    if visited[i]:
        continue
    s = set()
    q = [i]
    while len(q) > 0:
        p = q.pop()
        visited[p] = True
        s.add(p)
        for x in g[p]:
            if visited[x]:
                continue
            q.append(x)
    group.append(s)

ans = 0
for x in group:
    ans = max(ans, len(x))
print(ans)

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

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

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

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

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

Solution (Python):
import base64
import subprocess


exe_bin = "e??420s

exe_bin = base64.b85decode(exe_bin)

with open("./kyomu", 'wb') as f:
    f.write(exe_bin)

subprocess.run(["chmod +x ./kyomu"], shell=True)
subprocess.run(["./kyomu"], shell=True)

Solution (Python):

import sys

input = sys.stdin.readline


def I():
    return int(input())


def MI():
    return map(int, input().split())


class UnionFind:
    def __init__(self, n):
        self.rank = [-1 for _ in range(n)]  

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

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

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


N, M = MI()

if M == 0:
    print(1)
    exit()

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

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

print(ans)

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

a=list(range(n))
def find(x):
  g = x
  while g != a[g]: g = a[g]
  a[x] = g
  return g

for _ in range(m):
  x,y=map(int,input().split())
  x,y=find(x-1),find(y-1)
  if x == y: continue
  a[y]=x

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

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_counts(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(lambda x: int(x)-1, input().split())
    uf.union(a, b)

ans = 0
for a in uf.roots():
    ans = max(ans, uf.size(a))
print(ans)

Solution (Python):
import sys


def _ia(): return map(int, sys.stdin.readline().strip().split())


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

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

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(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

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


def main():
    n, m = _ia()
    uf = UnionFind(n)
    for _ in range(m):
        a, b = map(lambda x: x-1, _ia())
        uf.unite(a, b)
    return max(uf.size(i) for i in range(n))


if __name__ == "__main__":
    print(main())

Solution (Python):
n, m = list(map(int, input().split()))
abm = [list(map(int, input().split())) for _ in range(m)]
abm = set(tuple(sorted(item)) for item in abm)
edges = {}
for a, b in abm:
    if a not in edges:
        edges[a] = [b]
    else:
        edges[a].append(b)
    if b not in edges:
        edges[b] = [a]
    else:
        edges[b].append(a)

import collections
vis = [False for _ in range(n + 1)]
gr = {}
def create_group(s):
    if vis[s]:
        return None
    
    deq = collections.deque()
    deq.append(s)
    group = []
    while len(deq):
        node = deq.popleft()
        if vis[node]:
            continue
        group.append(node)
        vis[node] = True
        for e in edges.get(node, []):
            deq.append(e)

    for g in group:
        gr[g] = s
    return group


groups = [create_group(i) for i in range(1, n + 1)]
groups = list(filter(lambda x:x, groups))

ans = max(map(len, groups))
print(ans)

Solution (Python):
import sys

def _ia(): return map(int, sys.stdin.readline().strip().split())


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

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

    def unite(self, x, y):
        x = self.root(x)
        y = self.root(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

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


def main():
    n, m = _ia()
    uf = UnionFind(n)
    for _ in range(m):
        a, b = map(lambda x: x-1, _ia())
        uf.unite(a, b)
    return max(uf.size(i) for i in range(n))


if __name__ == "__main__":
    print(main())

Solution (Python):



import sys
from collections import deque

s2nn = lambda s: [int(c) for c in s.split(' ')]
ss2nn = lambda ss: [int(s) for s in list(ss)]
ss2nnn = lambda ss: [s2nn(s) for s in list(ss)]
i2s = lambda: sys.stdin.readline().rstrip()
i2n = lambda: int(i2s())
i2nn = lambda: s2nn(i2s())
ii2ss = lambda n: [i2s() for _ in range(n)]
ii2nn = lambda n: ss2nn(ii2ss(n))
ii2nnn = lambda n: ss2nnn(ii2ss(n))

class node:
    def __init__(self, i):
        self.i = i
        self.adj = {self}
        self.visited = False
    
    def join(self, B):
        self.adj.add(B)
        B.adj.add(self)

def bfs(tar):
    q = deque()
    q.append(tar)
    cnt = 0
    while (q):
        tar = q.popleft()
        if not tar.visited:
            cnt += 1
        tar.visited = True
        q.extend(adj for adj in tar.adj if not adj.visited)
    return cnt

def main():
    N, M = i2nn()
    G = [node(i) for i in range(N + 1)]
    for _ in range(M):
        A, B = i2nn()
        G[A].join(G[B])
    ans = 0
    for tar in G[1:]:
        if not tar.visited:
            ans = max(bfs(tar), ans)
    print(ans)
    return

main()

Solution (Python):
from collections import deque
N,M = map(int,input().split())
graph = [[] for _ in range(N)]
for i in range(M):
    x,y = map(int,input().split())
    x -= 1
    y -= 1
    graph[x].append(y)
    graph[y].append(x)

seen = [None]*N
ans = -1

for i in range(N):
    if seen[i]:
        continue
    seen[i] = True
    tmp = 0
    d = deque()
    d.append(i)
    while d:
        v = d.popleft()
        for i in graph[v]:
            if seen[i]:
                continue
            seen[i] = True
            d.append(i)
            tmp += 1
    ans = max(ans,tmp)
print(ans+1)

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 is_in_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())
    uf.unite(a-1, b-1)

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

print(ans)

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

par = [i for i in range(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:
    par[x] = y
    find(x)
  else:
    par[y] = x
    find(y)
if M > 0:  
  for i in range(M):
    a, b = map(int, input().split())
    unite(a - 1, b - 1)
  
  ans = [0] * N
  Max = 0
  for i in range(N):
    find(i)
  for i in par:
    ans[i] += 1
  for i in ans:
    if i > Max:
      Max = i
  
  print(Max)
else:
  print(1)

Solution (Python):
class DisjoinSet:
    def __init__(self, N):
        self.par = [-1] * N
        self.sz = [1] * N

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

    def unite(self, a, b):
        a = self.root(a)
        b = self.root(b)
        if a == b:
            return
        if self.sz[a] > self.sz[b]:
            a, b = b, a
        self.par[a] = b
        self.sz[b] += self.sz[a]

    def same(self, a, b):
        return self.root(a) == self.root(b)

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

    def __str__(self):
        clusters = defaultdict(list)
        for x in range(N):
            clusters[self.root(x)].append(x)
        return str(list(clusters.values()))


N, M = map(int, input().split())
dsu = DisjoinSet(N)
for _ in range(M):
    x, y = map(int, input().split())
    x, y = x - 1, y - 1
    dsu.unite(x, y)

ans = max([dsu.size(x) for x in range(N)])
print(ans)

Solution (Python):
n, m = map(int, input().split())
tree = [0]+[i+1 for i in range(n)]
size = [0] + [1 for i in range(n)]
def find(c):
    pc = tree[c]
    if pc == c:
        return pc
    else:
        return find(pc)

for _ in range(m):
    a, b = map(int, input().split())
    pa, pb = find(a), find(b)
    if pa!=pb:
        if size[pa] < size[pb]:
            tree[pa] = pb
            size[pa], size[pb] = size[pa]+size[pb], size[pa]+size[pb]
        else:
            tree[pb] = pa
            size[pa], size[pb] = size[pa]+size[pb], size[pa]+size[pb]
            
print(max(size))

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 same(self, x, y):
        return self.find(x) == self.find(y)
      
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.parents[uf.find(i)])
  
print(ans)

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

d = defaultdict(list)

if m==0:
    print(1)
    exit()

visited = [-1] + [False]*n
for i in range(m):
    a,b = map(int,input().split())
    d[a].append(b)
    d[b].append(a)
maxi = 1
for i in range(1,n+1):
    if visited[i]:
        continue
    cnt = 0
    que = deque([i])
    while que:
        v = que.pop()
        if not visited[v]:
            visited[v] = True
            cnt += 1
        for j in d[v]:
            if not visited[j]:
                que.append(j)
    maxi = max(maxi,cnt)
print(maxi)

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

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

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

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

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


n,m = map(int,input().split())
ab = [tuple(map(int,input().split())) for i in range(m)]
uf = UnionFind(n)
for ai,bi in ab:
    uf.union(ai-1,bi-1)
ans = 0
for i in range(n):
    ans = max(ans,uf.size(i))
print(ans)

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

d = defaultdict(set)

for _ in range(m):
    
    a,b = list(map(int, input().split()))
    d[a].add(b)
    d[b].add(a)
    
visited = set()

def dfs(node):
    
    c = 0
    stack = deque([node])
    visited.add(node)
    while stack:
        n = stack.popleft()
        c+=1
        for i in d[n]:
            if  i not in visited:
                visited.add(i)
                stack.append(i)
                
    return c
    

ans = 1

for key in list(d.keys()):
    if key not in visited:

        c = dfs(key)
        ans = max(ans, c)
        


print(ans)