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 collections 









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())
lis = [list(map(int,input().split())) for _ in range(m)]

road = [[] for i in range(n)] 
 
for i in lis:
    i[0]-=1
    i[1]-=1
    road[i[0]].append(i[1])
    road[i[1]].append(i[0])

cmax  = 0
 
uf = UnionFind(n)

for i in lis:
    uf.union(i[0],i[1])

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

print(cmax)

Solution (Python):
n,m = map(int,input().split())
ab = [list(map(int,input().split())) for _ in range(m)]
from collections import deque
e = [list() for _ in range(n)]
for i in range(m):
    e[ab[i][0]-1] += [ab[i][1]-1]
    e[ab[i][1]-1] += [ab[i][0]-1]

stack = deque()
visited = [0]*n

def dfs(x):
    num = 0
    stack.append(x)
    while stack:
        v = stack.pop()
        for k in e[v]:
            if visited[k]==0:
                num +=1
                visited[k]=1
                stack.append(k)
    return num


li = []

for i in range(n):
    li += [dfs(i)]

ans = max(li)
if ans ==0:
    print(1)
else:
    print(ans)

Solution (Python):
from collections import defaultdict
from collections import deque


def main():
    N, M = map(int, input().split())
    A = [0] * M
    B = [0] * M

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

    friends = defaultdict(set)

    for i in range(M):
        a, b = A[i], B[i]
        friends[a].add(b)
        friends[b].add(a)

    seen = [False] * N

    

    def dfs(start):
        cnt = 0
        nodes = []

        todo = deque([start])
        while len(todo) > 0:
            v = todo.pop()
            cnt += 1
            nodes.append(v)

            for next_v in friends[v]:
                if seen[next_v]:
                    continue
                else:
                    todo.append(next_v)
                    seen[next_v] = True

        return cnt, nodes

    trees = []
    counts = []
    for v in range(N):
        if seen[v]:
            continue
        else:
            seen[v] = True
            c, nodes = dfs(v)
            counts.append(c)
            trees.append(nodes)

    
    
    print(max(counts))


if __name__ == '__main__':
    main()

Solution (Python):
import bisect,collections,copy,itertools,math,string
import sys
def I(): return int(sys.stdin.readline().rstrip())
def LI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def S(): return sys.stdin.readline().rstrip()
def LS(): return list(sys.stdin.readline().rstrip().split())
def main():
    n,m = LI()
    route = [[] for _ in range(n+1)]
    for _ in range(m):
        a,b = LI()
        route[a].append(b)
        route[b].append(a)
    explored = set()

    sstock = collections.deque([i for i in range(1,n+1)])
    ans = 0
    while len(sstock)!=0:
        nnext = sstock.pop()
        if nnext not in explored:
            cnt = 0
            stock = collections.deque([nnext])
            explored.add(nnext)
            while len(stock) != 0:
                next = stock.pop()
                cnt += 1   
                for i in route[next]:
                    if i not in explored:
                        stock.append(i)
                        explored.add(i)
            ans = max(ans,cnt)
    print(ans)
main()

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.par = [0] * n
        self.chi = [0] * n
        for i in range(n):
            self.par[i] = i
            self.chi[i] = 1
        self.max_child = 1
    def root(self, x):
        if self.par[x] == x:
            return x
        rx = self.root(self.par[x])
        self.par[x] = rx
        
        
        return self.par[x]
    def unite(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        
        
        
        self.par[rx] = ry
        self.chi[ry] += self.chi[rx]
        if self.max_child < self.chi[ry]:
            self.max_child = self.chi[ry]
    def same(self, x, y):
        rx = self.root(x)
        ry = self.root(y)
        return rx == ry

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

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

print(u.max_child)

Solution (Python):
from collections import Counter



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 max_children(self):
        return max([self.size(x) for x in range(self.n)])

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


N, M = map(int,(input().split()))
ABs = []
for _ in range(M):
    ABs.append(tuple(map(lambda x:int(x)-1,(input().split()))))

uf = UnionFind(N)
for AB in ABs:
    A, B = AB
    uf.union(A, B)
    

print(uf.max_children())

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 = []

for i in range(m):
    a,b = map(int, input().split())
    a -= 1
    b -= 1
    uf.union(a,b)
    fr.append((a,b))
c = []

for i in range(n):
    c.append(uf.size(i))
    

c = set(c)
c = list(c)
c.sort(reverse=1)
if len(c) == 1:
    print(c[0])
else:
    ans = c[1]
    ans += c[0]-c[1]
    print(ans)

Solution (Python):
from collections import deque

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

flag = [True for i in range(n)]
max_grupe = 0
for i in range(n):
  if(flag[i] == False):
    continue
  num = 0
  queue = deque([i])
  flag[i] = False
  while queue:
    now = queue.popleft()
    num += 1
    for j in friend[now]:
      if(flag[j]):
        queue.append(j)
        flag[j] = False
        
  max_grupe = max(max_grupe, num)
  
print(max_grupe)

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


u = UnionFind(N+1)
for _ in range(M):
    a, b = map(int, input().split())
    u.union(a, b)

mx = 0
for i in range(1, N+1):
    mx = max(mx, u.size(i))

print(mx)

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)

max_num = 0
for i in range(N):
    max_num = max(max_num, size(i))
print(max_num)

Solution (Python):


from collections import deque
import collections

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

for i in range(m):
    a,b=map(int,input().split())
    friends[a-1].append(b-1)
    friends[b-1].append(a-1)
dist=[-1 for i in range(n)]
ans=0

for j in range(n):
    if dist[j]==-1:
        dist[j]=ans
        d=deque([j])
    
        while d:
            v=d.popleft()
            for i in friends[v]:
                if dist[i]!=-1:
                    continue
                dist[i]=ans
                d.append(i)
        ans+=1   
c = collections.Counter(dist)
print(c.most_common()[0][1])

Solution (Python):
import collections
n,m=map(int,input().split())
par=[i for i in range(n+1)]
def find(x):
    if par[x]==x:
        return x
    else:
        par[x]=find(par[x])
        return par[x]
for _ in range(m):
    a,b=map(int,input().split())
    A=find(a)
    B=find(b)
    par[max(A,B)]=par[min(A,B)]
l=[]
for i in range(1,n+1):
    l.append(find(i))
l=collections.Counter(l)
print(max(l.values()))

Solution (Python):

def main():
    from collections import deque

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

    seen = [False] * N
    friends_group = []
    for i in range(N):
        if seen[i]:
            continue
        q = deque([i])
        tmp_group = set([i])
        while q:
            now = q.popleft()
            if seen[now]:
                continue
            seen[now] = True
            for j in friends_input[now]:
                if not seen[j]:
                    q.append(j)
                    tmp_group.add(j)
        friends_group.append(tmp_group)
    ans = 0
    for i in friends_group:
        ans = max(ans, len(i))
    print(ans)


if __name__ == '__main__':
    main()

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

print(main())

Solution (Python):



def mp(): return map(int, input().split())
def lmp(): return list(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())

n,m = mp()
uf = UnionFind(n)
used = set()
for i in range(m):
    a,b = mp()
    if (a,b) not in used:
        uf.union(a-1,b-1)
        used.add((a,b))
        used.add((b,a))
ans = -1
for i in range(n):
    ans = max(uf.size(i), ans)
print(ans)

Solution (Python):
N,M = map(int,input().split())
AB = [list(map(int,input().split())) for _ in range(M)]
from collections import deque
friends = [deque() for _ in range(N)]
ans = 0

for a,b in AB:
  a -= 1
  b -= 1
  friends[a].append(b)
  friends[b].append(a)
  
flag = [False] * N
for i in range(N):
  if flag[i]:
    continue
  else:
    x = friends[i]
    tmp = 1
    flag[i] = True
    while len(x)!=0:
      y = x.pop()
      if flag[y]:
        continue
      else:
        tmp += 1
        for j in friends[y]:
          x.append(j)
        flag[y] = True
    ans = max(tmp,ans)
    
print(ans)

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

    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 x != y:
            if self.rank[x] < self.rank[y]:
                x, y = y, x
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
            self.par[y] = x

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

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

for i in range(n):uf1.find(i)
X = uf1.par

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

Solution (Python):
from collections import deque

N, M = map(int, input().split())
Node = [[] for _ in range(N + 1)]

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


seek = [False]*(N+1)
que = deque()
R = []


for n in range(1, N + 1):
    if seek[n] == True:
        
        continue
    result = []
    que.append(n)
    result.append(n)
    seek[n] = True
    while len(que) > 0:
        start = que.pop()
        for node in Node[start]:
            if seek[node] == False:
                result.append(node)
                que.append(node)
                seek[node] = True
    R.append(result)

Max = 0
for l in R:
    if len(l) > Max:
        Max = len(l)
print(Max)

Solution (Python):

"""
@author: H_Hoshigi

Union-Find木の実装は下記サイトを参考にした。
https://note.nkmk.me/python-union-find/
"""

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 main():
    N, M = map(int, input().split())
    Edge_lsit = []
    for i in range(M):
        A, B = map(int, input().split())
        Edge_lsit.append((min(A, B), max(A, B)))
    Edge_lsit.sort()

    uf = UnionFind(N)
    for Edge in Edge_lsit:
        uf.union(Edge[0]-1, Edge[1]-1)
    
    max_size = 0
    for i in range(N):
        max_size = max(max_size, uf.size(i))
    print(max_size)

if __name__ == "__main__":
    main()

Solution (Python):
import collections

class UnionFind():
  def __init__(self, n):
    self.n = n
    self.parent = [i for i in range(self.n)]
    self.rank = [0] * self.n
  
  def find_root(self, x):
    if self.parent[x] == x:
      return x
    else:
      self.parent[x] = self.find_root(self.parent[x])
      return self.parent[x]
  
  def unite(self, x, y):
    rx = self.find_root(x)
    ry = self.find_root(y)
    if rx == ry:
      return
    if self.rank[rx] < self.rank[ry]:
      self.parent[rx] = ry
    else:
      self.parent[ry] = rx
      if self.rank[rx] == self.rank[ry]:
        self.rank[rx] += 1
  
  def is_same(self, x, y):
    return self.find_root(x) == self.find_root(y)

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)

for i in range(N):
  uf.find_root(i)
c = collections.Counter(uf.parent)
print(c.most_common()[0][1])

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

    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 x != y:
            if self.rank[x] < self.rank[y]:
                self.parent[x] = y
                self.size[y] += self.size[x]
            else:
                self.parent[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 group_size(self, x):  
        return self.size[self.find(x)]


N, M = map(int, input().split())
A, B = [0] * M, [0] * M  

direct =[[] for _ in range(N)]  
uf = UnionFind(N)  

for i in range(M):
    A[i], B[i] = map(int, input().split())
    A[i] -= 1
    B[i] -= 1
    direct[A[i]].append(B[i])
    direct[B[i]].append(A[i])
    uf.unite(A[i], B[i])

ans = [0] * N
for i in range(N):
    ans[i] = uf.group_size(i)
print(max(ans))

Solution (Python):
n,m=map(int,input().split())
ab=[list(map(int,input().split())) for i in range(m)]
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
      
      
uf = UnionFind(n+1)
for i in range(m):
  if uf.same(ab[i][0], ab[i][1]) == False:
    uf.union(ab[i][0], ab[i][1])
ans=0
for i in range(1,n+1):
  if ans <uf.size(i):
    ans=uf.size(i)
print(ans)

Solution (Python):

from collections import defaultdict,deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10**5)
input = sys.stdin.readline
sqrt = math.sqrt
def LI(): return list(map(int, input().split()))
def LF(): return list(map(float, input().split()))
def LI_(): return list(map(lambda x: int(x)-1, input().split()))
def II(): return int(input())
def IF(): return float(input())
def S(): return input().rstrip()
def LS(): return S().split()
def IR(n): return [II() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def FR(n): return [IF() for _ in range(n)]
def LFR(n): return [LI() for _ in range(n)]
def LIR_(n): return [LI_() for _ in range(n)]
def SR(n): return [S() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
mod = 1000000007
inf = float("INF")


def solve():
    n, m = LI()
    ab = LIR(m)
    par = [i for i in range(n)]
    size = [1] * n
    def root(x):
        if par[x] == x:
            return x
        par[x] = root(par[x])
        return par[x]
    def unite(a, b):
        a = root(a)
        b = root(b)
        if a == b:
            return
        if size[a] < size[b]: a, b = b, a
        par[b] = a
        size[a] += size[b]
    for a, b in ab:
        a -= 1
        b -= 1
        unite(a, b)
    
    print(max(size))
    return



if __name__ == '__main__':
    solve()

Solution (Python):
from collections import defaultdict
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 _ in range(M):
  a,b = map(int,input().split())
  uf.union(a-1,b-1)
ans = 0
for i in range(N):
  if uf.size(i) > ans:
    ans = uf.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)

ab_list = []
ans =0
for i in range(M):
    a,b = map(int, input().split())
    a, b = a-1, b-1
    uf.union(a, b)

ans = 0
ans_list = uf.roots()
for i in range(len(ans_list)):
    ans = max(ans, uf.size(ans_list[i]))

print(ans)

Solution (Python):
import sys

input = sys.stdin.readline

n,m = list(map(int,input().split()))
N = [[] for _ in range(n)]
V = [0] * n

for _ in range(m):
  a,b = list(map(int,input().split()))
  a -= 1
  b -= 1
  N[a].append(b)
  N[b].append(a)
  
for i in range(n):
  N[i] = list(set(N[i]))
ans = 0

for i in range(n):
  if V[i] == 0:
    cnt = 1
    Q = [i]
    V[i] = 1
    
    while Q:
      node = Q.pop()
      for child in N[node]:
        if V[child]==0:
          Q.append(child)
          V[child] = 1
          cnt += 1
    ans = max(ans, cnt)
          
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 9)
n, m = map(int, input().split())

friend = [set() for i in range(n)]

for i in range(m):
  a = list(map(int, input().split()))
  a.sort()
  x, y = a[0]-1,a[1]-1
  friend[x].add(y)
  friend[y].add(x)

def dfs(s):
  if vis[s] == False:
    vis[s] = True
    ary.append(s)
    for j in friend[s]:
      dfs(j)
vis = [False for i in range(n)]
ans = 0
for i in range(n):
  ary = []
  dfs(i)
  ans = max(ans,len(ary))
print (ans)

Solution (Python):
from collections import deque

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

directcount = [0] * n 
visited = [-1]  * n 
colorcount = [-1] * n 

g = []
for _ in range(n):
    g.append(deque(list()))


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


q = deque(list()) 
for i in range(n):
    q.append(i)
    color = i
    
    cnt = 1
    while len(q) > 0:
        nextnode = q.popleft() 
        if visited[nextnode] != -1:
            continue
        visited[nextnode] = color
        q.extend(g[nextnode]) 
        
        cnt += 1
    
    colorcount[color]  = cnt -1

print(max(colorcount))

Solution (Python):
n, m = map(int, input().split())
ex = [0 for i in range(n)]
fri = {}

for i in range(m):
    a, b = map(int, input().split())
    if ex[a-1] == 0 and ex[b-1] == 0:
        if a > b:
            a, b = b, a
        ex[a-1] = a
        ex[b-1] = a
        fri[a] = [a, b]
    elif ex[a-1] == 0:
        ex[a-1] = ex[b-1]
        fri[ex[b-1]].append(a)
    elif ex[b-1] == 0:
        ex[b-1] = ex[a-1]
        fri[ex[a-1]].append(b)
    elif ex[a-1] == ex[b-1]:
        continue
    else:
        shozoku = min(ex[a-1], ex[b-1])
        mu = max(ex[a-1], ex[b-1])
        for j in range(len(fri[mu])):
            ex[fri[mu][j]-1] = shozoku
        fri[shozoku].extend(fri.pop(mu))

ans = 1
for key in fri:
    ans = max(ans, len(fri[key]))
print(ans)