Problem:
 Score : 400 points    Problem Statement There are N persons called Person 1 through Person N .  You are given M facts that "Person A_i and Person B_i are friends." The same fact may be given multiple times.  If X and Y are friends, and Y and Z are friends, then X and Z are also friends. There is no friendship that cannot be derived from the M given facts.  Takahashi the evil wants to divide the N persons into some number of groups so that every person has no friend in his/her group.  At least how many groups does he need to make?      Constraints  2 \leq N \leq 2\times 10^5  0 \leq M \leq 2\times 10^5  1\leq A_i,B_i\leq N  A_i \neq B_i         Input Input is given from Standard Input in the following format:  N  M  A_1  B_1  \vdots  A_M  B_M       Output Print the answer.        Sample Input 1 5 3
1 2
3 4
5 1      Sample Output 1 3  Dividing them into three groups such as \{1,3\} , \{2,4\} , and \{5\} achieves the goal.       Sample Input 2 4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4      Sample Output 2 4       Sample Input 3 10 4
3 1
4 1
5 9
2 6      Sample Output 3 3

Solution (Python):
import sys,heapq
input = sys.stdin.buffer.readline

sys.setrecursionlimit(10**7)


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

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


flag = [False]*n

def dfs(now):
    if flag[now]:
        return 0
    
    flag[now] = True

    size = 0
    for nxt in edge[now]:
        if not flag[nxt]:
            size += dfs(nxt)

    return size + 1

res = 0

for i in range(n):
    if flag[i]:
        continue
    res = max(res,dfs(i))

print(res)

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

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
    else:
        root[x] += root[y]
        root[y] = x


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


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



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

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

    def unite(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 find(self, x):
        if self.parents[x] < 0:
            return x
        else:
            self.parents[x] = self.find(self.parents[x])
            return self.parents[x]

    def size(self, x):
        return -self.parents[self.find(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.size(i))
  
print(ans)

Solution (Python):



class UnionFind(object):
    '''Represents a data structure that tracks a set of elements partitioned
       into a number of disjoint (non-overlapping) subsets.
    Landau notation: O(α(n)), where α(n) is the inverse Ackermann function.
    See:
    https://www.youtube.com/watch?v=zV3Ul2pA2Fw
    https://en.wikipedia.org/wiki/Disjoint-set_data_structure
    https://atcoder.jp/contests/abc120/submissions/4444942
    '''

    def __init__(self, number_count: int):
        '''
        Args:
            number_count: The size of elements (greater than 2).
        '''
        self.parent_numbers = [-1 for _ in range(number_count)]

    def find_root(self, number: int) -> int:
        '''Follows the chain of parent pointers from number up the tree until
           it reaches a root element, whose parent is itself.
        Args:
            number: The trees id (0-index).
        Returns:
            The index of a root element.
        '''
        if self.parent_numbers[number] < 0:
            return number

        self.parent_numbers[number] = self.find_root(self.parent_numbers[number])
        return self.parent_numbers[number]

    def get_group_size(self, number: int) -> int:
        '''
        Args:
            number: The trees id (0-index).
        Returns:
            The size of group.
        '''
        return -self.parent_numbers[self.find_root(number)]

    def is_same_group(self, number_x: int, number_y: int) -> bool:
        '''Represents the roots of tree number_x and number_y are in the same
           group.
        Args:
            number_x: The trees x (0-index).
            number_y: The trees y (0-index).
        '''
        return self.find_root(number_x) == self.find_root(number_y)

    def merge_if_needs(self, number_x: int, number_y: int) -> bool:
        '''Uses find_root to determine the roots of the tree number_x and
           number_y belong to. If the roots are distinct, the trees are combined
           by attaching the roots of one to the root of the other.
        Args:
            number_x: The trees x (0-index).
            number_y: The trees y (0-index).
        '''
        x = self.find_root(number_x)
        y = self.find_root(number_y)

        if x == y:
            return False

        if self.get_group_size(x) >= self.get_group_size(y):
            self.parent_numbers[x] += self.parent_numbers[y]
            self.parent_numbers[y] = x
        else:
            self.parent_numbers[y] += self.parent_numbers[x]
            self.parent_numbers[x] = y
        return True


def main():
    import sys
    input = sys.stdin.readline

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

    for i in range(m):
        ai, bi = map(int, input().split())
        ai -= 1
        bi -= 1

        uf.merge_if_needs(ai, bi)

    ans = 0

    for j in range(n):
        ans = max(ans, uf.get_group_size(j))

    print(ans)


if __name__ == '__main__':
    main()

Solution (Python):
n, m = map(int, input().split())
fr = [[] for _ in range(n)]
for _ in range(m):
    a, b = list(map(int, input().split()))
    fr[a-1].append(b-1)
    fr[b-1].append(a-1)
max_gr = 0
check = [False for _ in range(n)]
ans = 0

for per in range(n):
    if check[per]:
        continue

    else:
        tank = [per]
        count = 0
        while tank:
            now = tank.pop()
            if check[now]:
                continue
            else:
                check[now] = True
                count += 1
                for j in fr[now]:
                    if not check[j]:
                        tank.append(j)

        ans = max(ans, count)

print(ans)

Solution (Python):
n,m = map(int, input().split())
par = [0]*(n+1)
group = [1]*(n+1)
for i in range(1,n+1): par[i]=i
def root(x):
  if par[x]==x: return x
  return root(par[x])

def union(x,y):
  rx = root(x)
  ry = root(y)
  if rx==ry: return
  par[max(rx,ry)] = min(rx,ry)
  group[min(rx,ry)] += group[max(rx,ry)]

for _ in range(m):
  f1,f2 = map(int, input().split())
  union(f1,f2)
print(max(group))

Solution (Python):

import sys
sys.setrecursionlimit(1000000)

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


def dfs(i):
    ans[-1] += 1
    flg[i] = 1
    for j in friends[i]:
        if not flg[j]:
            dfs(j)


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

flg = [0]*n
ans = []

for i in range(n):
    ans.append(0)
    if not flg[i]:
        dfs(i)

print(max(ans))

Solution (Python):

import sys
sys.setrecursionlimit(1000000)

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


def dfs(i):
    ans[-1] += 1
    flg[i] = 1
    for j in friends[i]:
        if not flg[j]:
            dfs(j)
    return


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

flg = [0]*n
ans = []

for i in range(n):
    ans.append(0)
    if not flg[i]:
        dfs(i)

print(max(ans))

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

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


def dfs(i):
    ans[-1] += 1
    flg[i] = 1
    for j in friends[i]:
        if not flg[j]:
            dfs(j)
    return


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

flg = [0]*n
ans = []

for i in range(n):
    ans.append(0)
    if not flg[i]:
        dfs(i)

print(max(ans))

Solution (Python):
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        self.num = [1] * (n+1)
 
    
    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 self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.num[y]+=self.num[x]
        else:
            self.par[y] = x
            self.num[x]+=self.num[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1
 
    
    def same_check(self, x, y):
        return self.find(x) == self.find(y)

n, m = map(int, input().split())
f = [list(map(int, input().split())) for i in range(m)]

uf = UnionFind(n)
  
for i in range(m):
  a, b = f[i]
  if not uf.same_check(a, b):
    uf.union(a, b)
    
print(max(uf.num))

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 main():
    n, m = map(int,input().split())
    uf = UnionFind(n)
    for i in range(m):
        a,b = map(int,input().split())
        uf.union(a-1,b-1)
    print(-min(list(uf.parents)))
    
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

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

uf = UnionFind(n)

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

for a,b in ab:
    uf.union(a-1,b-1)

ans = -1
for i in uf.parents:
    ans = min(i,ans)
    
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())
u = UnionFind(n)

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

result = 0
for i in range(n): 
	result = max(result, u.size(i))

print(result)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
input = sys.stdin.readline
n,m=map(int,input().split())
root=[-1]*(n+1)
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
    if x>y:
        x,y=y,x

    root[x]+=root[y]
    root[y]=x
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())

    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i+1))
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
n,m=map(int,input().split())
root=[-1]*(n+1)
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
    if x>y:
        x,y=y,x

    root[x]+=root[y]
    root[y]=x
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())

    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i+1))
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())
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):
    ans = max(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())

ARR = []

for i in range(M):
    ARR.append(list(map(int,input().split())))

def calculate(n,m,arr):
    unionFind = UnionFind(n)

    for i in range(m):
        startNode = arr[i][0] - 1
        endNode = arr[i][1] - 1
        unionFind.union(startNode, endNode)

    result = 0
    for i in range(n):
        result = max(result,unionFind.size(i))
    print(result)



calculate(N,M,ARR)

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

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
    
n,m = map(int, input().split())

uf = UnionFind(n)

for i in range(m):
    a,b = map(int, input().split())
    uf.union(a-1, b-1)
ans = 0
roots = uf.roots()
cnt = []
for r in roots:
    cnt.append(uf.size(r))
cnt.sort(reverse=True)
ans = cnt[0]
print(ans)

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

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

from queue import Queue
ans = 1
for i in range(1, n+1):
  if g[i] != -1:
    continue
  if not i in edges:
    continue
  q = Queue()
  q.put(i)
  g[i] = 0
  tmp = 1
  while not q.empty():
    p = q.get()
    for edge in edges[p]:
      if g[edge] == -1:
        g[edge] = 0
        q.put(edge)
        tmp += 1
  ans = max(tmp, ans)
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(1<<30)
input = sys.stdin.readline
N, M = map(int, input().split())

e = [-1] * N

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

def join(a, b):
	a, b = find(a), find(b)
	if a == b: return
	if e[a] > e[b]: a, b = b, a
	e[a] += e[b]
	e[b] = a

for _ in range(M):
	x, y = map(int, input().split())
	join(x-1, y-1)

print(-min(e))

Solution (Python):
N, M = map(int, input().split())
A = [0] * M
B = [0] * M
for i in range(M):
    A[i], B[i] = map(int, input().split())

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

    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)]
    
u = UnionFind(N)
for i in range(M):
    u.union(A[i], B[i])
    
ans = 1
for i in range(1, N+1):
    ans = max(ans, u.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)]

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.union(a, b)

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

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

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

  def union(self, u,v):
    p1,p2 = self.find(u),self.find(v)
    if p1==p2: return
    if p1 > p2:
      p1,p2 = p2,p1
    self.parents[p1] += self.parents[p2]
    self.parents[p2] = p1

  def same(self, u,v):
    return self.find(u) == self.find(v)

  def weight(self, u):
    p = self.find(u)
    return -self.parents[p]

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

print(max([ abs(u) for u in uf.parents if u<0 ]))

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
n,m=map(int,input().split())
root=[-1]*(n+1)
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
    if root[x]>root[y]:
        x,y=y,x

    root[x]+=root[y]
    root[y]=x
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())

    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i+1))
print(ans)

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


done=[0]*n


def dfs(j):
  que=[j]
  cnt=1
  done[j]=1
  while(que):
    now=que.pop(0)

    for i in l[now]:
      if done[i]!=1:
        que.append(i)
        done[i]=1
        cnt+=1

  return cnt

ma=0
for j in range(n):
  if done[j]!=1:
    now=dfs(j)
  else:
    now=0
  ma=max(now,ma)
  
print(ma)

Solution (Python):
p = [i for i in range(200001)]
r = [1 for i in range(200001)]
ans = [1 for i in range(200001)]

def fs(a):
    if p[a] == a: return a
    p[a] = fs(p[a])
    return p[a]

def js(a, b):
    a = fs(a)
    b = fs(b)
    if a == b: return
    if r[a] > r[b]:
        p[b] = a
        ans[a] += ans[b]
    elif r[b] > r[a]:
        p[a] = b
        ans[b] += ans[a]
    else:
        p[b] = a
        ans[a] += ans[b]
        r[a] += 1

n, k = map(int,input().split())
for i in range(k):
    a, b = map(int,input().split())
    js(a, b)

ans1 = 0
for i in range(1, n+1):
    ans1 = max(ans1, ans[fs(i)])

print (ans1)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
n,m=map(int,input().split())
root=[-1]*(n+1)
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=map(int,input().split())

    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i+1))
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
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
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())
    x-=1
    y-=1
    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i))
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
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
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())
    x-=1
    y-=1
    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i))
print(ans)

Solution (Python):
import sys
sys.setrecursionlimit(10**9)
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
def size(x):
    x=r(x)
    return -root[x]
for i in range(m):
    x,y=map(int,input().split())
    x-=1
    y-=1
    unite(x,y)
ans=0
for i in range(n):
    ans=max(ans,size(i))
print(ans)

Solution (Python):
def main():
    n,m=map(int,input().split())
    uf=UnionFind(n)
    for a,b in (map(lambda x: int(x)-1, input().split()) for _ in range(m)):
        uf.union(a,b)
    print(max((uf.size(x) for x in uf.roots())))

class UnionFind():
    '''Union-Find'''
    
    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 is_same(self, x, y) -> bool:
        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())
if __name__ == "__main__":
    main()

Solution (Python):
def get_root(num):
    if num == root[num]:
        return num
    else:
        root[num] = get_root(root[num])
        return root[num]


def is_same_group(a,b):
    return get_root(a) == get_root(b)


def unite(x,y):
    root_x = get_root(x)
    root_y = get_root(y)

    if root_x == root_y:
        return

    if height[x] > height[y]:

        size[root_x] += size[root_y]
        root[root_y] = root_x 

    elif height[x] < height[y]:

        size[root_y] += size[root_x]
        root[root_x] = root_y

    else:
        size[root_x] += size[root_y]
        root[root_y] = root_x
        height[x] += 1



V,E = map(int,input().split())

root = list(range(V+1))
height = [0]*(V+1)
size = [1]*(V+1)

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

print(max(size))

Solution (Python):
n,m=map(int,input().split())
ab=[]
data=[[] for i in range(n+1)]
for i in range(m):
  a,b=map(int,input().split())
  ab.append([a,b])
  data[a].append(b)
  data[b].append(a)
flag=[0]*(n+1)
cnt=[0]*(n+1)
for i in range(1, n+1):
  if flag[i]==0:
    cnt[i]+=1
    flag[i]=1
    que=[i]
    while que:
      h=que.pop()
      for u in data[h]:
        if flag[u]==0:
          cnt[i]+=1
          flag[u]=1
          que.append(u)   
print(max(cnt))

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

if M==0:
  print(1)
  exit()
else:
  A = [list(map(int,input().split())) for m in range(M)]
  G = Graph()
  G.add_edges_from(A)
  print(len(max(connected_components(G),key=len)))

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

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())
N, M = map(int, input().split())
uf = UnionFind(N)
for i in range(M):
    a, b = map(int, input().split())
    uf.union(a-1, b-1)
ans = 0
for i in range(N):
    ans = max(ans, uf.size(i))
print(ans)

Solution (Python):
from networkx import*
_, *t = map(str.split, open(0))
print(max(1, 1, *map(len,connected_components(Graph(t)))))

Solution (Python):
def main():
    n,m=map(int,input().split())
    ab=[map(lambda x: int(x)-1,input().split()) for _ in range(m)]
    uf=UnionFind(n)
    for a,b in ab:
        uf.union(a,b)
    ans = 0
    for s in uf.roots():
        ans = max(uf.size(s),ans)
    print(ans)

class UnionFind():
    '''Union-Find'''
    
    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 is_same(self, x, y) -> bool:
        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())
    
if __name__ == "__main__":
    main()

Solution (Python):






from collections import Counter

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


def parent(par, i):
    depth = 1
    while par[i-1]!=i:  
        i = par[i-1]
        depth += 1
    return i, depth


def union(par, a, b):
    pa, da = parent(par, a)
    pb, db = parent(par, b)
    if da < db:
        par[pa-1] = par[pb-1]
    else:
        par[pb-1] = par[pa-1]


par = [i for i in range(1,n+1)]


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

c = Counter()
for i in range(n):
    c.update([parent(par,i)[0]])





print(c.most_common(1)[0][1])