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


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

class UnionFind():
	"""docstring for UnionFind"""
	def __init__(self, n):
		self.parents = [-1]*n

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

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

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

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

		
n,m=input2()
S=[input_array() for _ in range(m)]

uf=UnionFind(n) 

for s in S:
	uf.union(s[0]-1,s[1]-1)
ans=min(uf.parents)

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

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

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

Solution (Python):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
from collections import Counter
def resolve():
    n, m = map(int, input().split())
    E = [[] for _ in range(n)]

    for _ in range(m):
        u, v = map(int, input().split())
        u -= 1; v -= 1
        E[u].append(v)
        E[v].append(u)


    cnt = 0
    color = [-1] * n
    def dfs(v):
        if color[v] != -1:
            return False
        color[v] = cnt
        queue = [v]
        for v in queue:
            for nv in E[v]:
                if color[nv] == -1:
                    color[nv] = cnt
                    queue.append(nv)
        return True

    for v in range(n):
        cnt += dfs(v)

    print(Counter(color).most_common()[0][1])
resolve()

Solution (Python):
def root(x, root_ls):
  if root_ls[x] < 0:
    return x
  else:
    root_ls[x] = root(root_ls[x], root_ls)
    return root_ls[x]

def unite(a, b, root_ls):
  a = root(a, root_ls)
  b = root(b, root_ls)
  if a != b:
    root_ls[a] += root_ls[b]
    root_ls[b] = a
  
n, m = list(map(int, input().rstrip().split(" ")))
members = [-1 for i in range(n)]
max_idx = 0
for mm in range(m):
  a, b = list(map(int, input().rstrip().split(" ")))
  unite(a-1, b-1, members)
print(max([-m for m in members]))

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):
import sys
INF = 1 << 60
MOD = 10**9 + 7 
sys.setrecursionlimit(2147483647)
input = lambda:sys.stdin.readline().rstrip()
from collections import Counter
def resolve():
    n, m = map(int, input().split())
    E = [[] for _ in range(n)]

    for _ in range(m):
        u, v = map(int, input().split())
        u -= 1; v -= 1
        E[u].append(v)
        E[v].append(u)


    cnt = 0
    color = [-1] * n
    def dfs(v):
        if color[v] != -1:
            return False
        color[v] = cnt
        queue = [v]
        for v in queue:
            for nv in E[v]:
                if color[nv] == -1:
                    color[nv] = cnt
                    queue.append(nv)
        return True

    for v in range(n):
        cnt += dfs(v)

    for key, val in Counter(color).most_common():
        print(val)
        return
resolve()

Solution (Python):
from collections import Counter
import sys
sys.setrecursionlimit(10000000)

class UnionFind:
    def __init__(self, N: int) -> None:
        
        
        self.par = [-1 for i in range(N)]
    
    def root(self, x: int) -> bool:
        if self.par[x] < 0: 
            return x
        else:
            
            self.par[x] = self.root(self.par[x])
            return self.par[x]

    def unite(self, x: int, y: int) -> None:
        rx = self.root(x)
        ry = self.root(y)
        if rx == ry:
            return
        else:
            if rx > ry:
                rx, ry = ry, rx
            self.par[rx] += self.par[ry]
            self.par[ry] = rx
    
    def same(self, x: int, y: int) -> bool:
        return self.root(x) == self.root(y)
    
    def size(self, x: int) -> int:
        root = self.root(x)
        return -self.par[root]


def main():
    N, M = map(int, input().split())
    uf = UnionFind(N)
    for _ 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)

if __name__ == '__main__':
    main()

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

P=[-1]*n

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

def unite(x,y):
  x=find(x)
  y=find(y)
  if x==y:
    return

  if P[x]>P[y]:
    P[y]+=P[x]
    P[x]=y
  else:
    P[x]+=P[y]
    P[y]=x

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

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

print(-min(P))

Solution (Python):
class Union:
    def __init__(self, number):
        self.__number = number
        self.parentList = [-1] * number
 
    def getNumber(self):
        return self.__number 

    def getRoot(self, index):
        if self.parentList[index] < 0:
            return index
        root = self.getRoot(self.parentList[index])
        self.parentList[index] = root
        return root
      
    def unite(self, i, j):
        i = self.getRoot(i)
        j = self.getRoot(j)
        if i != j:
            if i > j:
                i, j = j, i
            self.parentList[i] += self.parentList[j]
            self.parentList[j] = i
 
    def getSize(self, i):
        return -self.parentList[self.getRoot(i)]
 
n, m = map(int, input().split())
 
friendUnion = Union(n)
for i in range(m):
  a, b = map(int, input().split())
  friendUnion.unite(a-1, b-1)
 
unionSizes = [friendUnion.getSize(i) for i in range(friendUnion.getNumber())]
print(max(unionSizes))

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.r = [-1] * n
    
    def root(self, x):
        if self.r[x] < 0:
            return x
        self.r[x] = self.root(self.r[x])
        return self.r[x]

    def merge(self, x, y):
        x, y = self.root(x), self.root(y)
        if x == y:
            return False
        if self.r[x] > self.r[y]:
            x, y = y, x
        self.r[x] += self.r[y]
        self.r[y] = x
        return True

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


N, M = map(int, input().split())
f, uf = [set() for i in range(N)], UnionFind(N)

for _ in range(M):
    A, B = map(lambda x: int(x)-1, input().split())
    uf.merge(A, B)

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

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 = list(map(int,input().split()))
Network = UnionFind(N)

out=0
for i in range(M):
    a,b = list(map(int,input().split()))
    Network.union(a-1,b-1)
print(-1*min(Network.parents))

Solution (Python):
import collections
import sys
import resource
sys.setrecursionlimit(1000000)

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

f = [x for x in range(n)]

def find(x):
  if f[x] == x:
    return x
  root = find(f[x])
  f[x] = root
  return root

for i in range(m):
  a, b = map(int, input().split(' '))
  a -= 1
  b -= 1
  if find(a) != find(b):
    f[find(a)] = find(b)

for i in range(n):
  find(i)
  
print(max(collections.Counter(f).values()))

Solution (Python):
from collections import deque

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

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

check = [False] * N
ans = 0

for i in range(N):
  if check[i] == False:
    check[i] = True
    D = deque(friends[i])
    tmp = 1
    while D:
      f = D.popleft()
      if check[f] == False:
        check[f] = True
        tmp += 1
        for j in friends[f]:
          D.append(j)
    ans = max(ans, tmp)

print(ans)

Solution (Python):
import sys

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

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

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

        if x == y:
            return

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

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


N, M = map(int, input().split())
info = [()] * M
for i in range(M):
    info[i] = map(int, input().split())

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

ans = min(uf.parents)

print(-ans)

Solution (Python):


def solve():
    class UnionFindVerSize():
        def __init__(self, N):
            """ N個のノードのUnion-Find木を作成する """
            
            self._parent = [n for n in range(0, N)]
            
            self._size = [1] * N

        def find_root(self, x):
            """ xの木の根(xがどのグループか)を求める """
            if self._parent[x] == x: return x
            self._parent[x] = self.find_root(self._parent[x]) 
            return self._parent[x]

        def unite(self, x, y):
            """ xとyの属するグループを併合する """
            gx = self.find_root(x)
            gy = self.find_root(y)
            if gx == gy: return

            
            if self._size[gx] < self._size[gy]:
                self._parent[gx] = gy
                self._size[gy] += self._size[gx]
            else:
                self._parent[gy] = gx
                self._size[gx] += self._size[gy]

        def get_size(self, x):
            """ xが属するグループのサイズ（個数）を返す """
            return self._size[self.find_root(x)]

        def is_same_group(self, x, y):
            """ xとyが同じ集合に属するか否か """
            return self.find_root(x) == self.find_root(y)

        def calc_group_num(self):
            """ グループ数を計算して返す """
            N = len(self._parent)
            ans = 0
            for i in range(N):
                if self.find_root(i) == i:
                    ans += 1
            return ans

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

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

    print(ans)


if __name__ == "__main__":
    solve()

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)]
        self.size = [1 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
            self.size[x] += self.size[y]

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

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


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

u = UnionFind(N+1)

for i in range(M):
    A, B = map(int, input().split())
    u.union(A, B)

print(max([u.get_size(i) for i in range(1, N+1)]))

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

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

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

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

uf = UnionFind(N+1)

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

print(max(uf.size(num) for num in uf.roots()))

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):
class UnionFind():

    def __init__(self, N):
        
        self.parent = [n for n in range(N)]

        
        self.rank = [1] * N
        
    def find(self, u):
        if self.parent[u] == u:
            return u
        else:
            
            return self.find(self.parent[u])
    
    def union(self, u, v):
        pu = self.find(u)
        pv = self.find(v)

        
        if pu == pv: 
            return

        
        if self.rank[pu] < self.rank[pv]:
            pu, pv = pv, pu

        self.rank[pu] += self.rank[pv]
        self.parent[pv] = pu
 
N, M = map(int, input().split())
UF = UnionFind(N)
for _ in range(M):
    A, B = map(int, input().split())
    A, B = A-1, B-1
    UF.union(A, B)


ret = 0

for n in range(N):
    ret = max(ret, UF.rank[n])

print(ret)

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

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

n, m = readInt()

root = [-1] * n

def r(x):
    
    if root[x] < 0:
        
        return x
    else:
        root[x] = r(root[x])
        
        return root[x]

def unite(x, y):
    x = r(x)
    y = r(y)
    if x == y:
        return
    root[x] += root[y]
    root[y] = x
    

def size(x):
    x = r(x)
    
    return -root[x]

for i in range(m):
    x, y = readInt()
    x -= 1
    y -= 1
    unite(x, y)

max_size = 0

for i in range(n):
    max_size = max(max_size, size(i))

print(max_size)

Solution (Python):
class UnionFind():
    def __init__(self, N):
        self.N = N
        self.par = [n for n in range(N)]
        self.rank = [1] * N
        
    def find(self, u):
        if self.par[u] == u:
            return u
        else:
            return self.find(self.par[u])
    
    def union(self, u, v):

        pu = self.find(u)
        pv = self.find(v)

        if pu == pv: 
            return

        if self.rank[pu] < self.rank[pv]:
            self.par[pu] = pv
            self.rank[pv] += self.rank[pu]

        else: 
            self.par[pv] = pu
            self.rank[pu] += self.rank[pv]
 
N, M = map(int, input().split())
UF = UnionFind(N)
for _ in range(M):
    A, B = map(int, input().split())
    A, B = A-1, B-1
    UF.union(A, B)


ret = 0

for n in range(N):
    ret = max(ret, UF.rank[n])

print(ret)

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

union = UnionFind(N)

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

ans = 0
for i in range(N):
    ans = max(ans, union.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 {root: self.members(root) for root in self.roots()}

    def __str__(self):
        return '\n'.join(f'{root}: {self.members(root)}' for root 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)

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

Solution (Python):
n, m = map(int, input().split())
data2 = []
for i in range(m):
    data2.append(input().split())

graph = [[] for i in range(n)]
for i in range(0,m):
    a, b = map(lambda z: int(z) - 1, data2[i])
    graph[a].append(b)
    graph[b].append(a)

size = [0 for i in range(n)]
check = [True for i in range(n)]
for i in range(n):
    if check[i]:
        tmp = 1
        stack = [i]
        check[i] = False
        while stack:
            now = stack.pop()
            size[now] = tmp
            tmp += 1
            for to in graph[now]:
                if check[to]:
                    check[to] = False
                    stack.append(to)
print(max(size))

Solution (Python):
import sys
from collections import defaultdict as dd
from collections import deque
from functools import *
from fractions import Fraction as f
from copy import *
from bisect import *	
from heapq import *

from itertools import permutations ,product
 
def eprint(*args):
    print(*args, file=sys.stderr)
zz=1
 

if zz:
	input=sys.stdin.readline
else:	
	sys.stdin=open('input.txt', 'r')
	sys.stdout=open('all.txt','w')
def inc(d,c):
	d[c]=d[c]+1 if c in d else 1
def bo(i):
	return ord(i)-ord('A')	
def li():
	return [int(xx) for xx in input().split()]
def fli():
	return [float(x) for x in input().split()]	
def comp(a,b):
	if(a>b):
		return 2
	return 2 if a==b else 0		
def gi():	
	return [xx for xx in input().split()]
def fi():
	return int(input())
def pro(a): 
	return reduce(lambda a,b:a*b,a)		
def swap(a,i,j): 
	a[i],a[j]=a[j],a[i]	
def si():
	return list(input().rstrip())	
def mi():
	return 	map(int,input().split())			
def gh():
	sys.stdout.flush()
def isvalid(i,j):
	return 0<=i<n and 0<=j<n	
def bo(i):
	return ord(i)-ord('a')	
def graph(n,m):
	for i in range(m):
		x,y=mi()
		a[x].append(y)
		a[y].append(x)


t=1
def find(a,i):
	if i==a[i]:
		return a[i]
	a[i]=find(a,a[i])
	return a[i]
def union(a,x,y):
	xs=find(a,x)
	ys=find(a,y)
	if xs!=ys:
		if rank[xs]<rank[ys]:
			xs,ys=ys,xs
		a[ys]=xs
		rank[xs]+=1			

while t>0:
	t-=1
	n,m=mi()
	a=[i for i in range(n+1)]
	rank=[0]*(n+1)
	for i in range(m):
		x,y=mi()
		union(a,x,y)
	d=[0]*(n+1)	
	for i in range(1,n+1):	
		a[i]=find(a,i)
		d[a[i]]+=1
	print(max(d))

Solution (Python):
import sys


def union(parent, rank, i, j):
    i_id = find(parent, i)
    j_id = find(parent, j)

    if i_id == j_id:
        return
    if rank[i_id] > rank[j_id]:
        parent[j_id] = i_id
    else:
        parent[i_id] = j_id
        if rank[i_id] == rank[j_id]:
            rank[j_id] += 1

def find(parent, i):
    v = list()
    while i != parent[i]:
        i = parent[i]
        v.append(i)
    for j in v:
        parent[j] = i
    return i


def main():
    input = sys.stdin.read()
    data = list(map(int, input.split()))

    n, m = data[0], data[1]
    rank = [0]*(n+1)
    parent = [i for i in range(n+1)]

    for i in range(2,len(data)-1,2):
        union(parent, rank, data[i], data[i+1])

    s = [0]*(n+1)

    
    

    for i in range(1,n+1):
        s[find(parent,i)] += 1
        

    print(max(s))


if __name__ == '__main__':
    main()

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

class UnionFind():
  def __init__(self, n):
    self.n = n
    self.d = [-1] * n
  
  def find(self, x):
    if (self.d[x] < 0):
      return x
    else:
      self.d[x] = self.find(self.d[x])
      return self.d[x]
  
  def unite(self, x, y):
    x = self.find(x)
    y = self.find(y)
    if (x == y): return
    if (self.d[x] > self.d[y]):
      x, y = y, x
    self.d[x] += self.d[y]
    self.d[y] = x
  def same(self, x, y): return self.find(x) == self.find(y)
  def size(self, x): return -self.d[self.find(x)]

n, m = map(int, input().split())
uf = UnionFind(n)
for i in range(m):
  a, b = map(int, input().split())
  a -= 1
  b -= 1
  uf.unite(a,b)
ans = 0
for i in range(n):
  ans = max(ans, uf.size(i))
print(ans)

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

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

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

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return;
        if x>y:
            x, y = y, x
        self.li[x]+=self.li[y]
        self.li[y] = x

x = unionfind(n)
ans = 0
for _ in range(m):
    a,b = map(int,input().split())
    x.union(a,b)
print(-min(x.li))

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

class unionfind():
    def __init__(self,n):
        self.li = [i for i in range(n+1)]
        self.group = [1]*(n+1)

    def find(self, x):
        while self.li[x]!=x:
            x = self.li[x]
        return x

    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return;
        elif x>y:
            self.li[y] = x
            self.group[x] += self.group[y]
        else:
            self.li[x] = y
            self.group[y] += self.group[x]
x = unionfind(n)
ans = 0
for _ in range(m):
    a,b = map(int,input().split())
    x.union(a,b)
print(max(x.group))

Solution (Python):
n, m = map(int, input().split())
a, b = [], []
for i in range(m):
  _, __ = map(int, input().split())
  _ -= 1
  __ -= 1
  a.append(_)
  b.append(__)
  



parent = [-1 for i in range(n)]


depth = [0 for i in range(n)]


def find_root(k):
  while parent[k] != -1:
    k = parent[k]
  return k 

for i in range(m):
  
  root_a = find_root(a[i])
  root_b = find_root(b[i])
  if root_a == root_b: continue
  
  
  if depth[root_a] > depth[root_b]:
    root_a, root_b = root_b, root_a
  parent[root_a] = root_b
  depth[root_b] = max(depth[root_a]+1, depth[root_b])
  
group = [find_root(i) for i in range(n)]

from collections import Counter
print(Counter(group).most_common()[0][1])

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


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

group = [-1 for i in range(n)]


for i in range(n):
  if group[i] != -1: continue
  
  newly_visited = [i]
  group[i] = i
  while len(newly_visited) > 0:
    now = newly_visited.pop()
    for j in adj_list[now]:
      if group[j] != -1: continue
      newly_visited.append(j)
      group[j] = i

hist = [0 for i in range(n)]
for g in group:
  hist[g] += 1
print(max(hist))

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)
cnt=0
for i in range(n):
    cnt=max(cnt, uf.size(i))
print(cnt)

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 = list(map(int,input().split()))
uf = UnionFind(N)
for _ in range(M):
  A,B = list(map(int,input().split()))
  uf.union(A-1,B-1)
print(abs(min(uf.parents)))

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

    def _root(self, x):
        stack = []
        while self._table[x] >= 0:
            stack.append(x)
            x = self._table[x]
        for y in stack:
            self._table[y] = x
        return x
    
    def unite(self, x, y):
        x, y = self._root(x), self._root(y)
        if x == y:
            return
        if x > y:
            x, y = y, x
        self._table[x] += self._table[y]
        self._table[y] = x

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

    def count_members(self, x):
        return -self._table[self._root(x)]

    def count_groups(self):
        return len({self._root(i) for i in range(self._n)})

    def __iter__(self):
        return (self._root(i) for i in range(self._n))

    def __str__(self):
        return str([self._root(i) for i in range(self._n)])

    def __repr__(self):
        return repr([self._root(i) for i in range(self._n)])

n, m, *AB = map(int, open(0).read().split())
uf = UnionFind(n)
for a, b in zip(AB[::2], AB[1::2]):
    uf.unite(a-1, b-1)
print(max(uf.count_members(group) for group in set(uf)))