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):
from sys import stdin
readline = stdin.readline
def r_map(): return map(int, readline().rstrip().split())

class UnionFind:
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * (n + 1)
        self.rank = [0] * (n + 1)
        self.max_size = 1

    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) -> bool:
        x = self.root(x)
        y = self.root(y)
        if x == y:
            return False
        if self.rank[x] > self.rank[y]:
            self.parents[x] += self.parents[y]
            self.parents[y] = x
        else:
            self.parents[y] += self.parents[x]
            self.parents[x] = y
            if self.rank[x] == self.rank[y]:
                self.rank[y] += 1
        self.max_size = max(self.max_size, self.size(x))
        return True

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

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

    def is_same(self, x, y) -> bool:
        return self.root(x) == self.root(y)

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

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


def main():
    N, M = r_map()
    uf = UnionFind(N)
    for _ in range(M):
        a, b = r_map()
        uf.unite(a, b)
    print(uf.max_size)

if __name__ == "__main__":
    main()

Solution (Python):
from collections import deque


def resolve():
  N, M = map(int, input().split(" "))
  connections = []
  for _ in range(N):
    connections.append(deque())
  checked = [False] * N
  prev = [None] * N

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

  max_count = 0
  for i in range(N):
    if checked[i]:
      continue

    checked[i] = True
    count = 1 
    current = i
    
    while current != i or len(connections[current]) != 0:
      checked[current] = True
      
      next_node = connections[current].pop()
      
      while checked[next_node]:
        if len(connections[current]) != 0:
          next_node = connections[current].pop()
        else:
          
          next_node = None
          break


      
      while next_node is not None:
        prev[next_node] = current
        current = next_node
        
        count += 1
        checked[current] = True
        
        if len(connections[current]) == 0:
          break

        next_node = connections[current].pop()
        
        while checked[next_node]:
          if len(connections[current]) != 0:
            next_node = connections[current].pop()
          else:
            
            next_node = None
            break
      
      
      if prev[current] is None:
        continue
      current = prev[current]

      
      while len(connections[current]) == 0:
        if prev[current] is not None:
          current = prev[current]
        else:
          break

    max_count = max(count, max_count)
  
  print(max_count)

if __name__ == "__main__":
  resolve()

Solution (Python):
N, M = map(int, input().split())
t = [-1] * N

import sys
sys.setrecursionlimit(10 ** 6)
def find(e):
    if t[e] < 0:
        return e
    else:
        t[e] = find(t[e])
        return t[e]


def unite(a, b):
    a_root = find(a)
    b_root = find(b)
    if a_root == b_root:
        return
    t[a_root] += t[b_root]
    t[b_root] = a_root


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


def size(x):
    x = find(x)
    return -t[x]


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

Solution (Python):
n,m=map(int,input().split())
root=[-1]*n
def r(x):
  if root[x]<0:
    return x
  else:
    root[x]=r(root[x])
    return root[x]
def unite(x,y):
  x=r(x)
  y=r(y)
  if x==y:
    return
  root[x]+=root[y]
  root[y]=x
for i in range(m):
  a,b=map(int,input().split())
  a-=1
  b-=1
  unite(a,b)
ans=0
for i in range(n):
  ans=max(ans,-root[i])
print(ans)

Solution (Python):




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

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


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



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

Solution (Python):
n, m = map(int, input().split())
grid = [set() for i in range(n)]
for i in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    grid[u].add(v)
    grid[v].add(u)

cnt = 0
best = 0
visited = set()

import sys
sys.setrecursionlimit(1000000)

def dfs(x):
    global cnt
    if x in visited:
        return
    cnt += 1
    visited.add(x)
    for i in grid[x]:
        dfs(i)


for i in range(n):
    cnt = 0
    dfs(i)
    best = max(best, cnt)

print(best)

Solution (Python):
def INT():
    return int(input())

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

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

class UnionFind:
    def __init__(self, N):
        self.root = [_ for _ in range(N)]
        self.rank = [0] * N
        self.size = [1] * N
        
    def find(self, x):
        if self.root[x] == x:
            return x
        else:
            
            self.root[x] = self.find(self.root[x])
            return self.root[x]
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        else:
            if self.rank[x] > self.rank[y]:
                self.size[x] += self.size[y]
                self.root[y] = x
            else:
                self.size[y] += self.size[x]
                self.root[x] = y
                if self.rank[x] == self.rank[y]:
                    self.rank[y] += 1
            
    def same(self, x, y):
        return self.find(x) == self.find(y)
    
    def getSizeOfSet(self, x):
        return self.size[self.find(x)]

import sys
sys.setrecursionlimit(10**9)

N, M = MI()
friend = UnionFind(N)

for _ in range(M):
    A, B = MI()
    friend.union(A - 1, B - 1)
    
ans = 0
for i in range(N):
    ans = max(ans, friend.getSizeOfSet(i))
    
print(ans)

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

p = []
sz = []

def find(x):
    if(p[x] == x):
        return x
    p[x] = find(p[x])
    return p[x]

def join(u, v):
    u = find(u)
    v = find(v)
    if(u == v):
        return

    if(sz[u] > sz[v]):
        u ^= v
        v ^= u
        u ^= v

    sz[v] += sz[u]
    p[u] = v

for i in range(n+1):
    p.append(i)
    sz.append(1)

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

mx = 0
for i in range(1, n+1):
    if(p[i] != i):
        continue
    mx = max(mx, sz[i])

print(mx)

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

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

uni=UnionFind(N)

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

ans=0
for i in range(N):
    ans=max(ans, uni.Count(i))

print(ans)

Solution (Python):
N, M = map(int, input().split())
AB = [tuple(map(int,input().split())) for i in range(M)]

class UnionFind:
    def __init__(self,N):
        self.parent = [i for i in range(N)]
        self._size = [1] * N
        self.count = 0

    def root(self,a):
        if self.parent[a] == a:
            return a
        else:
            self.parent[a] = self.root(self.parent[a])
            return self.parent[a]
    def is_same(self,a,b):
        return self.root(a) == self.root(b)

    def unite(self,a,b):
        ra = self.root(a)
        rb = self.root(b)
        if ra == rb: return
        if self._size[ra] < self._size[rb]: ra,rb = rb,ra
        self._size[ra] += self._size[rb]
        self.parent[rb] = ra
        self.count += 1

    def size(self,a):
        return self._size[self.root(a)]

uf = UnionFind(N)
for a,b in AB:
    a,b = a-1,b-1
    if uf.is_same(a,b): continue
    uf.unite(a,b)

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

Solution (Python):



from sys import setrecursionlimit, stdin
 
def find(parent, i):
    
    
    t = parent[i]
    if t < 0:
        return i
    t = find(parent, t)
    parent[i] = t
    return t
 
def unite(parent, i, j):
    i = find(parent, i)
    
    j = find(parent, j)
    
    if i == j:
        return
    parent[j] += parent[i]
    parent[i] = j
    
 
readline = stdin.readline
setrecursionlimit(10 ** 6)

def resolve(): 
    N, M = map(int, readline().split())
    parent = [-1] * N
    for _ in range(M):
        A, B = map(lambda x: int(x) - 1, readline().split())
        unite(parent, A, B)
    print(-min(parent))

resolve()

Solution (Python):
def bfs(d,visit,i):
    q=[i]
    visit[i]=1
    count=1
    while(len(q)!=0):
        val=q.pop()
        for k in d[val]:
            if(visit[k]==0):
                count+=1
                visit[k]=1
                q.append(k)
    return count
    

n,m=map(int,input().split())
d=dict()
for i in range(1,n+1):
    d[i]=set()
for i in range(m):
    l,r=map(int,input().split())
    d[l].add(r)
    d[r].add(l)

visit=[0]*(n+1)

count=0
for i in range(1,n+1):
    if(visit[i]==0 and len(d[i])!=0):
        count=max(count,bfs(d,visit,i))
if(count==0):
    print(1)
else:
    print(count)

Solution (Python):
import sys
sys.setrecursionlimit(10 ** 9)
 
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)
 
ans = 0
 
for i in range(n):
    ans = max(ans, uf.Count(i))
 
print(ans)

Solution (Python):
class Unionfind:
     
    def __init__(self,n):
        self.uf = [-1]*n
 
    def find(self,x):
        if self.uf[x] < 0:
            return x
        else:
            self.uf[x] = self.find(self.uf[x])
            return self.uf[x]
 
    def same(self,x,y):
        return self.find(x) == self.find(y)
 
    def union(self,x,y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.uf[x] > self.uf[y]:
            x,y = y,x
        self.uf[x] += self.uf[y]
        self.uf[y] = x
        return True
 
    def size(self,x):
        x = self.find(x)
        return -self.uf[x]

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

M = 1
u = Unionfind(n+1)
for i in range(m):
    a,b = map(int,input().split())
    u.union(a,b)
    M = max(M,u.size(a))
print(M)

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

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)

ans = 0

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

print(ans)

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

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-1, b-1)

ans = 0

for i in range(n):
    ans = max(ans, uf.Count(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)

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

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

uf = UnionFind(n)

for a,b in friends:
    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())



p = [-1] * N

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

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

    if x == y:
        return
    p[y] += p[x] 
    p[x] = y
    return

def size(x):
    return -p[p[x]]

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

    union(a, b)





ans = max(map(size, range(N)))

print(ans)

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

class Unionfind():
    def __init__(self, n):
        self.n = n
        self.parent = [-1]*n
    
    def find(self, x):
        if self.parent[x] < 0:
            return x
        else:
            self.parent[x] = self.find(self.parent[x])
            return self.parent[x]
    
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)

        if x == y:
            return

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

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

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

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

uf = Unionfind(N)
for i in range(M):
    a,b = map(lambda x: int(x) - 1, input().split())
    uf.union(a,b)
lis = uf.parent
print(-min(lis))

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)
result=[uf.size(i) for i in range(N)]
print(max(result))

Solution (Python):
from collections import deque, defaultdict
import sys
sys.setrecursionlimit(1000000)

class Node:
    def __init__(self, id):
        self.id = id
        self.parent = self.id

N, M = [int(i) for i in input().split()]
P = [Node(i) for i in range(N)]

def root(a):
    if a.id == a.parent:
        return a.id
    else:
        id = root(P[a.parent])
        a.parent = id
        return id

def union(a, b):
    p = root(a)
    q = root(b)
    if p == q:
        return
    else:
        P[q].parent = p

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

c = defaultdict(int)
for i in range(N):
    c[root(P[i])] += 1
    maxc = 0
for key in c.keys():
    if maxc < c[key]:
        maxc = c[key]
print(maxc)

Solution (Python):
def find(A,x):
    p = A[x]
    if p == x:
        return x
    a = find(A,p)
    A[x] = a
    return a
 
def union(A, x, y):

    if find(A,x) > find(A,y):
        bx, by = find(A,y), find(A,x)
    else:
        bx, by = find(A,x), find(A,y)
    A[y] = bx
    A[by] = bx

def main():
    N, M = map( int, input().split())
    U = [ i for i in range(N)]
    AB = [ tuple( map( lambda x: int(x)-1, input().split())) for _ in range(M)]
    for a, b in AB:
        union(U, a, b)
    T = [0]*N
    for i in range(N):
        T[find(U, i)] += 1
    print(max(T))
if __name__ == '__main__':
    main()

Solution (Python):
def find(n):
    if parent[n] < 0:
        return n
    else:
        parent[n] = find(parent[n])
        return parent[n]


def union(x, y):
    root_x = find(x)
    root_y = find(y)
    if root_x == root_y:
        return
    if parent[root_x] > parent[root_y]:
        root_x, root_y = root_y, root_x
    parent[root_x] += parent[root_y]
    parent[root_y] = root_x


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


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

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

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
n,m=map(int,input().split())
l=[]
par=[-1]*n
def root(x):
    if par[x]<0:
        return x
    else:
        par[x]=root(par[x])
        return par[x]

def unite(x,y):
    x=root(x)
    y=root(y)
    if x==y:
        return
    if par[x]>par[y]:
        temp=x
        x=y
        y=temp
    par[x]+=par[y]
    par[y]=x
def size(x):
    x=root(x)
    return -par[x]
for a,b in l:
    unite(a,b)

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

Solution (Python):
N, M = map(int,input().split())
AB = [list(map(int,input().split())) for x in range(M)]

parents = [-1]*(N+1)

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

def union(x,y):
    global parents
    X = find(x)
    Y = find(y)
    if X == Y:
        return
    if X > Y:
        X,Y = Y,X

    parents[X] += parents[Y]
    parents[Y] = X



for p in range(M):
    union(AB[p][0],AB[p][1])



print(min(parents)*-1)














"""
F = [[]]
L = []

for x in range(N+1):
    F += [[x+1]]

for p in range(M):
    F[AB[p][0]] += [AB[p][1]]
    F[AB[p][1]] += F[AB[p][0]]

for q in range(N+1):
    F[q] = list(set(F[q]))

for r in range(N+1):
    L += [len(F[r])]

print(L)
print(max(L))
"""

Solution (Python):
def zero_origin(s: str):
  return int(s) - 1


class UnionFindTree:
  """Union Find Tree for disjoint-set data structure.

  Args:
    n (int): number of the vertices.
  """
  def __init__(self, n: int):
    self.parent = list(range(n))
    self.rank = [0] * n
    self.size = [1] * n

  def find(self, i: int) -> int:
    if self.parent[i] != i:
      self.parent[i] = self.find(self.parent[i])
    return self.parent[i]

  def unite(self, i: int, j: int):
    ri = self.find(i)
    rj = self.find(j)
    if ri != rj:
      if self.rank[ri] < self.rank[rj]:
        self.parent[ri] = rj
        self.size[rj] += self.size[ri]
      else:
        self.parent[rj] = ri
        self.size[ri] += self.size[rj]
        if self.rank[ri] == self.rank[rj]:
          self.rank[ri] += 1

  def is_same(self, i: int, j: int) -> bool:
    return self.find(i) == self.find(j)


n, m = map(int, input().split())
uft = UnionFindTree(n)
for _ in range(m):
  a, b = map(zero_origin, input().split())
  uft.unite(a, b)
print(max(uft.size))

Solution (Python):
from collections import Counter
n, m = map(int, input().split())
ab = [tuple(map(int, input().split())) for _ 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())

tree = UnionFind(n)
for a, b in ab:
    a,b = a-1, b-1
    if not tree.same(a, b):
        tree.union(a, b)
ans = float("-inf")
for i in range(n):
    ans = max(ans, tree.size(i))
print(ans)

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


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

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

    def union(self, x, y):
        rx, ry = self.find(x), self.find(y)
        if rx != ry:
            if self.r[rx] > self.r[ry]:
                rx, ry = ry, rx
            if self.r[rx] == self.r[ry]:
                self.r[ry] += 1
            self.p[ry] += self.p[rx]
            self.p[rx] = ry

    def count_members(self, x):
        return -self.p[self.find(x)]


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

print(max(map(lambda i: uf.count_members(i), range(n))))

Solution (Python):
N,M=map(int,input().split())
friend=[[] for _ in range(N)]
for i in range(M):
    A,B=map(int,input().split())
    friend[A-1].append(B-1)
    friend[B-1].append(A-1)
ans=0
ischecked=[0]*N
for i in range(N):
    if ischecked[i]==1:
        continue
    group=1
    ischecked[i]=1
    ship=friend[i]
    while ship:
        nex=ship.pop()
        if ischecked[nex]==1:
            continue
        ischecked[nex]=1
        group+=1
        ship.extend(friend[nex])
    ans=max(ans,group)
print(ans)

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

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

if __name__ == "__main__":
    main()

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


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

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

    def union(self, x, y):
        rx, ry = self.find(x), self.find(y)
        if rx != ry:
            if self.r[rx] > self.r[ry]:
                rx, ry = ry, rx
            if self.r[rx] == self.r[ry]:
                self.r[ry] += 1
            self.p[ry] += self.p[rx]
            self.p[rx] = ry

    def count_members(self, x):
        return -self.p[self.find(x)]


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

ans = 0
for i in range(n):
    x = uf.count_members(i)
    if ans < x:
        ans = x
print(ans)

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

  def get_root(self, i):
    if self.parent[i] < 0:
      return i
    else:
      self.parent[i] = self.get_root(self.parent[i])
      return self.parent[i]
    
    
    

  def is_same_tree(self, i, j):
    return self.get_root(i) == self.get_root(j)

  def merge(self, i, j):
    i = self.get_root(i)
    j = self.get_root(j)
    if i == j:
      return

    if self.rank[i] > self.rank[j]:
      self.parent[j] = i
      self.rank[i] = max(self.rank[i], self.rank[j] + 1)
      self.count[i] += self.count[j]
    else:
      self.parent[i] = j
      self.rank[j] = max(self.rank[j], self.rank[i] + 1)
      self.count[j] += self.count[i]


n, m = map(int, input().split())
uf = UnionFind(n)
for _ in range(m):
  a, b = [int(i) - 1 for i in input().split()]
  uf.merge(a, b)
print(max(uf.count))

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

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

  def size(self,k):
    k = self.root(k)
    return -self.par[k]

  def unite(self,u,v):
    u = self.root(u)
    v = self.root(v)
    if u==v:
      return
    if self.size(u)<self.size(v):
      u,v = v,u
    self.par[u] += self.par[v]
    self.par[v] = u

def main():
  n,m = map(int,input().split())
  uni = union_find(n+1)
  for _ in range(m):
    ai,bi = map(int,input().split())
    uni.unite(ai,bi)
  ans = max(uni.size(v)for v in range(1,n+1))
  print(ans)

main()

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

N,Q = 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(Q):
  a,b=map(int,input().split())
  a,b=a-1,b-1
  uf.union(a,b)
from collections import Counter
a=[-1]*N
for i in range(N):
  a[i]=uf.find(i)
ca=Counter(a)
ans=0
for c in ca.values():
  ans=max(ans,c)
print(ans)