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



Sample input:
5 3
1 2
3 4
5 1


Sample output:
3

Submission status: Runtime Error

Solution code:
def main():
    n, m = map(int, input().split())
    g = [[] for i in [0]*(n+1)]
    for _ in range(m):
        a, b = map(int, input().split())
        g[a].append(b)
        g[b].append(a)

    def bfs(n, m, adj):
        visited = [0 for i in [0]*(n+1)]
        ans = 1
        for i in range(n+1):
            if visited[i]:
                continue
            Q = deque([i])
            temp = 1
            while Q:
                q = Q.popleft()
                visited[q] = 1
                link = adj[q]
                for j in link:
                    if visited[j]:
                        continue
                    visited[j] = 1
                    temp += 1
                    Q.append(j)
            ans = max(ans, temp)
        print(ans)  
    bfs(n, m, g)
 
if __name__=="__main__":
    main()

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(10**7)
def input(): return sys.stdin.readline().rstrip()

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

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

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

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

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

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

def main():
    n, m = map(int, input().split())

    uf = UnionFind(n)
    for _ in range(m):
        a, b = map(int, input().split())
        uf.unite(a-1, b-1)
    roots = uf.roots()
    cnt = []
    for r in roots:
        cnt.append(uf.size(r))
    print(max(cnt))

if __name__ == '__main__':
    main()

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(10**7)
def input(): return sys.stdin.readline().rstrip()

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

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

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

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

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

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

def main():
    n, m = map(int, input().split())

    uf = UnionFind(n)
    for _ in range(m):
        a, b = map(int, input().split())
        uf.unite(a-1, b-1)
    roots = uf.roots()
    cnt = []
    for r in roots:
        cnt.append(uf.size(r))
    print(max(cnt))

if __name__ == '__main__':
    main()

Submission status: Runtime Error

Solution code:
from collections import deque
from copy import deepcopy

def main():
 
    n, m = map(int, input().split())
    adj = [[] for _ in range(n)]
    for i in range(m):
        a, b = map(lambda x: int(x) - 1, input().split())
        adj[a].append(b)
        adj[b].append(a)
    dist = [-1] * n
    q = deque([0])
    dist[0] = 0
    dl = 0
    while q:
        v = q.popleft()
        d = dist[v]
        for w in adj[v]:
            if dist[w] > -1:
                continue
            dist[w] = d + 1
            q.append(w)
    dl = sum([1 for i in dist if i >= 0])
    def search_index(l, x, default=False):
        return l.index(x) if x in l else default

    dist_0 = deepcopy(dist)
    next = 1
    while next:
        next = search_index(dist_0, -1)
        if next == False:
            print(dl)
            exit()
        q = deque([next])
        dist = [-1] * n
        dist[next] = 0
        while q:
            v = q.popleft()
            d = dist[v]
            for w in adj[v]:
                if dist[w] > -1:
                    continue
                dist[w] = d + 1
                q.append(w)
                sum_d = sum([1 for i in dist if i >= 0])
        if dl < sum_d:
            dl = sum_d
        dist_0[next] = 0
    print(dl)
    
if __name__ == '__main__':
    main()

Submission status: Runtime Error

Solution code:
from collections import deque
from copy import deepcopy

def main():
 
    n, m = map(int, input().split())
    adj = [[] for _ in range(n)]
    for i in range(m):
        a, b = map(lambda x: int(x) - 1, input().split())
        print(a, b)
        adj[a].append(b)
        adj[b].append(a)
    print(adj)

    dist = [-1] * n
    q = deque([0])
    dist[0] = 0
    dl = 0
    while q:
        v = q.popleft()
        d = dist[v]
        for w in adj[v]:
            if dist[w] > -1:
                continue
            dist[w] = d + 1
            q.append(w)
    dl = sum([1 for i in dist if i >= 0])
    print(dl)
    def search_index(l, x, default=False):
        return l.index(x) if x in l else default
    print(search_index(dist, -1))

    dist_0 = deepcopy(dist)
    next = 1
    while next:
        next = search_index(dist_0, -1)
        print('next', next)
        if next == False:
            break
        q = deque([next])
        dist = [-1] * n
        dist[next] = 0
        while q:
            v = q.popleft()
            d = dist[v]
            for w in adj[v]:
                if dist[w] > -1:
                    continue
                dist[w] = d + 1
                q.append(w)
                sum_d = sum([1 for i in dist if i >= 0])
        if dl[0] < sum_d:
            dl = sum_d
        dist_0[next] = 0
    print('dl', dl)

if __name__ == '__main__':
    main()

Submission status: Runtime Error

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

par = list(range(N))
rank = [1]*N
size = [1]*N

def find(x):
  if par[x] == x:
    return x
  else:
    return find(par[x])
  
def unite(x,y):
  x = find(x)
  y = find(y)
  
  if x == y:
    return
  if rank[x]<rank[y]:
    x,y = y,x
  else:
  par[y] = x
  size[x] += size[y]
  if rank[x]==rank[y]:
    rank[x]+=1
    
for i in range(M):
  a,b = [int(i)-1 for i in input().split()]
  unite(a,b)
  
print(max(size))

Submission status: Runtime Error

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

par = list(range(N))
rank = [1]*N
size = [1]*N

def find(x):
  if par[x] == x:
    return x
  else:
    return find(par[x])
  
def unite(x,y):
  x = find(x)
  y = find(y)
  
  if x == y:
    return
  if rank[x]<rank[y]:
    x,y = y,x
  par[y] = x
  size[x] += size[y]
  if rank[x]==rank[y]:
    rank[x]
    
for i in range(M):
  a,b = [int(i)-1 for i in input().split()]
  unite(a,b)
  
print(max(size))

Submission status: Runtime Error

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

def uf_find(x):
  if x == p[x]:
    return x
  else:
    p[x] = uf_find(p[x])
    return p[x]

def uf_unite(x,y):
  x = uf_find(x)
  y = uf_find(y)
  if x != y:
    if r[y]>r[x]:
      x,y = y,x
    if r[x]==r[y]:
      r[x]+= 1
    p[y] = x
    #print(r)


N, M = map(int, input().split())
p = list(range(N))
r = [0]*N

for i in range(M):
  A, B = [int(j)-1 for j in input().split()]
  uf_unite(A,B)
  print(p)
  
for i in range(N):
  p[i] = uf_find(i)

q = [0]*N
for i in range(N):
  q[i] = p.count(i)
  
print(max(q))

Submission status: Runtime Error

Solution code:
def uf_find(x):
  z = x
  while z != p[z]:
    z = p[z]
  p[x] = z
  return z

def uf_unite(x,y):
  global rand
  x = uf_find(x)
  y = uf_find(y)
  if x != y:
    rand += 1
    if rand % 2 ==0:
      p[y] = x
    else:
      p[x] = y

N, M = map(int, input().split())
p = list(range(N))
rand = 0

for i in range(M):
  A, B = [int(j)-1 for j in input().split()]
  uf_unite(A,B)
  print(p)
  
for i in range(N):
  p[i] = uf_find(i)
print(p)

q = [0]*N
for i in range(N):
  q[i] = p.count(i)
  
print(max(q))

Submission status: Runtime Error

Solution code:
n, m = map(int, input().split())
friends = set()
for i in range(m):
  friends.add(tuple(map(int,input().split())))
  
#print(friends)

group = [set(friends.pop())]
for i,j in friends:
  #print(group)
  for g in group:
    if (i in g) or (j in g):
      g.add(i)
      g.add(j)
      break
  else:
    group.append({i,j})

#print(group)

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

Submission status: Runtime Error

Solution code:
n, m = map(int, input().split())
friends = set()
for i in range(m):
  friends.add(tuple(map(int,input().split())))
  
print(friends)

group = [set(friends.pop())]
for i,j in friends:
  for g in group:
    if (i in g) or (j in g):
      g.add(i)
      g.add(j)
    else:
      group.append({i,j})
#print(group)

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

Submission status: Runtime Error

Solution code:
N, M = map(int, input().split())
friends = {i: set() for i in range(N)}
for _ in range(M):
  A, B = sorted(list(map(int, input().split())))
  friends[A-1].add(B-1)

#print(friends)
ignore = set()
max = 0
def getAllFriends(i):
  res = friends[i]
  for f in friends[i]:
    res = res|getAllFriends(f)
  return res
for i, ff in friends.items():
  if i in ignore: continue
  fs = getAllFriends(i)
  ignore = ignore|fs
  if max<len(fs): max = len(fs)
print(max+1)

Submission status: Runtime Error

Solution code:
N, M = map(int, input().split())
friends = {i: set() for i in range(N)}
for _ in range(M):
  A, B = sorted(list(map(int, input().split())))
  friends[A-1].add(B-1)

#print(friends)
ignore = set()
max = 0
def getAllFriends(i):
  res = friends[i]
  for f in friends[i]:
    res |= getAllFriends(f)
  return res
for i, ff in friends.items():
  if i in ignore: continue
  fs = getAllFriends(i)
  ignore |= fs
  if max<len(fs): max = len(fs)
print(max+1)

Submission status: Runtime Error

Solution code:
N, M = map(int, input().split())
friends = {i: [] for i in range(N)}
for _ in range(N):
  A, B = sorted(map(int, input().split()))
  friends[A].append(B)


ignore = []
max = 0
def getAllFriends(i):
  res = []
  for f in friends[i]:
    res += getAllFriends(f)
  return res
for i, ff in friends.items():
  if i in ignore: continue
  fs = getAllFriends(i)
  ignore += fs
  if max<len(fs): max = len(fs)
print(fs)

Submission status: Runtime Error

Solution code:
from numba import njit


class UnionFind:
    __slots__ = ["data"]
    
    def __init__(self, n=0):
        self.data = [-1]*(n+1)
    
    def root(self, x):
        if self.data[x] < 0:
            return x
        self.data[x] = self.root(self.data[x])
        return self.data[x]
    
    def unite(self, x, y):
        x = self.root(x)
        y = self.root(y)
        if x != y:
            if self.data[x] < self.data[y]:
                self.data[x] += self.data[y]
                self.data[y] = x
            else:
                self.data[y] += self.data[x]
                self.data[x] = y
    
    def same(self, x, y):
        return self.root(x) == self.root(y)
    
    def size(self, x):
        return -self.data[self.root(x)]

@njit
def main():
    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(1, n+1):
        ans = max(ans, uf.size(i))
        
    print(ans)
        


main()

Submission status: Runtime Error

Solution code:
#_______________________________________________________________#
def fact(x):
	if x == 0:
		return 1
	else:
		return x * fact(x-1)
def lower_bound(li, num): 
	answer = -1
	start = 0
	end = len(li)-1

	while(start <= end):
		middle = (end+start)//2
		if li[middle] >= num:
			answer = middle
			end = middle - 1
		else:
			start = middle + 1
	return answer #index where x is not less than num
def upper_bound(li, num): 
	answer = -1
	start = 0
	end = len(li)-1

	while(start <= end):
		middle = (end+start)//2

		if li[middle] <= num:
			answer = middle
			start = middle + 1
		
		else:
			end = middle - 1
	return answer #index where x is not greater than num

def abs(x):
	return x if x >=0 else -x
def binary_search(li, val, lb, ub): 
	ans = 0
	while(lb <= ub):
		mid = (lb+ub)//2
		#print(mid, li[mid])
		if li[mid] > val:
			ub = mid-1
		elif val > li[mid]:
			lb = mid + 1
		else:
			ans = 1
			break
	return ans
def kadane(x): #maximum sum contiguous subarray
	sum_so_far = 0
	current_sum = 0
	for i in x:
		current_sum += i
		if current_sum < 0:
			current_sum = 0
		else:
			sum_so_far = mpos(sum_so_far,current_sum)
	return sum_so_far
def pref(li):
	pref_sum = [0]
	for i in li:
		pref_sum.append(pref_sum[-1] + i)
	return pref_sum

#_______________________________________________________________#
'''
      ▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄
   ▄███████▀▀▀▀▀▀███████▄
░▐████▀▒▒Aestroix▒▒▀██████
░███▀▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▀████
░▐██▒▒▒▒▒KARMANYA▒▒▒▒▒▒████▌         ________________
░▐█▌▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▌  ? ?   |▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
░░█▒▒▄▀▀▀▀▀▄▒▒▄▀▀▀▀▀▄▒▒▐███▌   ?    |___CM ONE DAY___|
░░░▐░░░▄▄░░▌▐░░░▄▄░░▌▒▐███▌     ? ? |▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒|
░▄▀▌░░░▀▀░░▌▐░░░▀▀░░▌▒▀▒█▌    ? ?    
░▌▒▀▄░░░░▄▀▒▒▀▄░░░▄▀▒▒▄▀▒▌      ? 
░▀▄▐▒▀▀▀▀▒▒▒▒▒▒▀▀▀▒▒▒▒▒▒█     ? ? 
░░░▀▌▒▄██▄▄▄▄████▄▒▒▒▒█▀       ? 
░░░░▄█████████ ████=========█▒▒▐▌
░░░▀███▀▀████▀█████▀▒▌
░░░░░▌▒▒▒▄▒▒▒▄▒▒▒▒▒▒▐
░░░░░▌▒▒▒▒▀▀▀▒▒▒▒▒▒▒▐
░░░░░████████████████
'''
from math import *
#for _ in range(int(input())):
mod = 1000000007
for _ in range(1):
	#n = int(input())
	n,m = map(int,input().split())
	#d,t,s = map(int,input().split())
	#ws,wa = map(int,input().split())
	#b = list(input())
	#x = int(input())
	#n = len(b)
	#s2 = input()
	#r, g, b, w = map(int,input().split())
	#a = list(map(int,input().split()))
	#b = list(map(int,input().split()))
	#s1 = list(st)
	di = {}
	for i in range(1,n+1):
		di.setdefault(i,[])
	for i in range(m):
		a,b = map(int,input().split())
		di[a] += [b]
		di[b] += [a]
	ans = 0
	for i in range(n):
		vis = [0]*n
		def dfs(n):
			vis[n-1] = 1
			for i in di[n]:
				if vis[i-1] == 0:
					dfs(i)
		dfs(i+1)
		ans = max(ans, vis.count(1))
	
	print(ans)

Submission status: Runtime Error

Solution code:
import networkx as nx
n,m=map(int,input().split())
a=[[i for i in input().split()] for _ in range(m)]
g=nx.Graph()
for x in a:
     g.add_edge(x[0],x[1])
print(len(sorted(nx.connected_components(g),key=len,reverse=True)[0]))

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(4100000)
import math
import itertools
INF = float('inf')
from heapq import heapify, heappop, heappush
import collections


n,m = map(int, input().split())
par = [i for i in range(n)]
rank = [0]*n

def find(x):
    if par[x] == x:
        return x
    else:
        par[x] = find(par[x])
        return par[x]


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

def main():
    for _ in range(m):
        a,b = map(int, input().split())
        unite(a-1,b-1)
    count = [0]*n
    for p in par:
        count[find(p)] += 1
    print(max(count))


if __name__ == '__main__':
    main()

Submission status: Runtime Error

Solution code:
import sys
sys.setrecursionlimit(4100000)
import math
import itertools
INF = float('inf')
from heapq import heapify, heappop, heappush
import collections


n,m = map(int, input().split())
par = [i for i in range(n)]
rank = [0]*n

def find(x):
    if par[x] == x:
        return x
    else:
        par[x] = find(par[x])
        return par[x]

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

def main():
    for _ in range(m):
        a,b = map(int, input().split())
        unite(a-1,b-1)

    count = [0]*n
    for p in par:
        count[par(p)] += 1
    print(max(count))


if __name__ == '__main__':
    main()

Submission status: Runtime Error

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

Submission status: Runtime Error

Solution code:
from networkx import*
n, m = map(int, input().split())
edges = [tuple(map(int, input().split())) for _ in range(m)]
G = Graph()
#G.add_nodes_from(range(1, n+1))
G.add_edges_from(edges)
ccs = connected_components(G)
ans = max(map(len, ccs))
print(ans)

Submission status: Runtime Error

Solution code:
from networkx import*
#print(max(map(len,connected_components(Graph(map(str.split,[*open(0)][1:]))))))
#(n,m),*t=map(str.split,open(0));print(max(map(len,connected_components(Graph(t[:int(m)])))))
n, m = map(int, input().split())
edges = [tuple(map(int, input().split())) for _ in range(m)]
G = Graph(range(1, n+1))
G.add_edges_from(edges)
ccs = connected_components(G)
ans = max(map(len, ccs))
print(ans)

Submission status: Runtime Error

Solution code:
from networkx import*
#print(max(map(len,connected_components(Graph(map(str.split,[*open(0)][1:]))))))
#(n,m),*t=map(str.split,open(0));print(max(map(len,connected_components(Graph(t[:int(m)])))))
n, m = map(int, input().split())
edges = [tuple(map(int, input().split())) for _ in range(m)]
G = Graph(edges)
ccs = connected_components(G)
ans = max(map(len, ccs))
print(ans)

Submission status: Runtime Error

Solution code:
from networkx import*
f=lambda:tuple(map(int,input().split()))
n,m=f()
print(max(map(len,connected_components(DiGraph(f()for _ in range(m))))))

Submission status: Runtime Error

Solution code:
from networkx import*
f=lambda:tuple(map(int,input().split()))
n,m=f()
print(max(map(len,connected_components(Graph(f()for _ in range(m))))))

Submission status: Runtime Error

Solution code:
from networkx import*
f=lambda:map(int,input().split())
n,m=f()
print(max(map(len,connected_components(f()for _ in range(m)))))

Submission status: Runtime Error

Solution code:
line = input()

N, M = [int(x) for x in line.split(" ")]

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

def find(arr, num):
  if arr[num] != num:
    return find(arr, arr[num])
  else:
    return num
  

for i in range(M):
  line = input()
  people1, people2 = [int(x) for x in line.split(" ")]
  parent1 = find(arr,people1)
  parent2 = find(arr,people2)
  if parent1 != parent2:
    arr[min(parent1, parent2)] = max(parent1, parent2)
            

dic1 = {}
max_group = 0
for i in range(1, N+1):
  people = find(arr,i)
  
  if people in dic1:
    dic1[people] += 1
  else:
    dic1[people] = 1
  max_group = max(max_group,dic1[people])


print(max_group)

Submission status: Runtime Error

Solution code:
from networkx import*
(n,m),*t=map(str.split,open(0))
print(max(map(len,connected_components(Graph(t[:int(m)])))))

Submission status: Runtime Error

Solution code:
from networkx import*
print(max(map(len,connected_components(Graph(map(str.split,[*open(0)][1:]))))))

Submission status: Runtime Error

Solution code:
import sys
input = sys.stdin.readline
ins = lambda: input().rstrip()
ini = lambda: int(input().rstrip())
inm = lambda: map(int, input().split())
inl = lambda: list(map(int, input().split()))
out = lambda x: print('\n'.join(map(str, x)))

def dfs(x):
    stack = [x]
    visited = []
    if checked[x] == 1:
        return 0
    while stack:
        node = stack.pop()
        if node not in visited:
            visited.append(node)
            checked[node] = 1
            for i in graph[node]:
                stack.append(i)
                checked[i] = 1
    return len(visited)

n, m = inm()
checked = [0] * (n+1)
graph = {}
for i in range(m):
    a, b = inm()
    if a not in graph:
        graph[a] = []
    if b not in graph:
        graph[b] = []
    graph[a].append(b)
    graph[b].append(a)
ans = 0
for i in range(1, n+1):
    if checked[i] == 0:
        ans = max(ans, dfs(i))
print(ans)

Submission status: Runtime Error

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

par = [i + 1 for i in range(n)]
rank = [0] * n
size = [1] * n

def find(x):
    if par[x - 1] == x:
        return x
    else:
        return find(par[x - 1])

def union(x, y):
    x = find(x)
    y = find(y)
    if rank[x] < rank[y]:
        par[x] = y
        size[x] += size[y]
    else:
        par[y] = x
        size[y] += size[x]
        if rank[x] == rank[y]:
            rank[x] += 1

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

print(max(size))

Submission status: Runtime Error

Solution code:
def mian():
	N, M = map(int, input().strip().split())

	groups = []

	for _ in range(M):
		Ai, Bj = map(int, input().strip().split())

		g_ai = -1
		g_bj = -1

		for i, group in enumerate(groups):
			if Ai in group:
				g_ai = i
			if Bj in group:
				g_bj = i
			if g_ai > -1 and g_bj > -1:
				break

		if g_ai < 0 and g_bj < 0:
			new_g = set([Ai, Bj])
			groups.append(new_g)

		elif g_ai < 0 and g_bj > -1:
			groups[g_bj].add(Ai)

		elif g_ai > -1 and g_bj < 0:
			groups[g_ai].add(Bj)

		elif g_ai != g_bj:
			new_g = groups[g_ai] | groups[g_bj]
			groups.append(new_g)
			del groups[g_ai]
			del groups[g_bj]

	if not groups:
		print(1)
	else:
		print(max([len(g) for g in groups]))

main()

Submission status: Runtime Error

Solution code:
import sys, re, os
from collections import deque, defaultdict, Counter
from math import ceil, sqrt, hypot, factorial, pi, sin, cos, radians, gcd
from itertools import permutations, combinations, product, accumulate
from operator import itemgetter, mul
from copy import deepcopy
from string import ascii_lowercase, ascii_uppercase, digits
from functools import reduce
from bisect import bisect_left, insort_left
from heapq import heapify, heappush, heappop

INPUT = lambda: sys.stdin.readline().rstrip()
INT = lambda: int(INPUT())
MAP = lambda: map(int, INPUT().split())
S_MAP = lambda: map(str, INPUT().split())
LIST = lambda: list(map(int, INPUT().split()))
S_LIST = lambda: list(map(str, INPUT().split()))

sys.setrecursionlimit(10 ** 9)
INF = float('inf')
mod = 10 ** 9 + 7


class UnionFind():
    def __init__(self, n):
        self.n = n
        # parents[i]: 要素iの親要素の番号
        # 要素iが根の場合、parents[i] = -(そのグループの要素数)
        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

    # 要素xが属するグループの要素数を返す
    def size(self, x):
        return -self.parents[self.find(x)]

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

    # 要素xが属するグループに属する要素をリストで返す
    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()}

    # print()での表示用
    # all_group_members()をprintする
    def __str__(self):
        return '\n'.join('{}: {}'.format(r, self.members(r)) for r in self.roots())


def main():
    N, M = MAP()

    tree = UnionFind(N)
    for _ in range(M):
      	a, b = MAP()
        tree.union(a - 1, b - 1)

    ans = 0
    for l in tree.all_group_members().values():
        ans = max(ans, len(l))

    print(ans)


if __name__ == '__main__':
    main()

Submission status: Runtime Error

Solution code:
import math
import collections
import fractions
import itertools
import functools
import operator
import bisect

def solve():
    n, m = map(int, input().split())
    group = []
    done = [-1]*n
    num = 0
    for i in range(m):
        a, b = map(lambda x:int(x)-1, input().split())
        if done[a] != -1:
            if done[b] == -1:
                group[done[a]].append(b)
                done[b] = done[a]
            else:
                if done[a] != done[b]:
                    group[done[a]] += group[done[b]]
                    group[done[b]] = 0
        else:
            if done[b] == -1:
                group.append([a,b])
                done[a], done[b] = num, num
                num += 1
            else:
                group[done[b]].append(a)
                done[a] = done[b]
    people = [1]+[len(i) for i in group]
    print(max(people))
    return 0

if __name__ == "__main__":
    solve()

Submission status: Runtime Error

Solution code:
import math
import collections
import fractions
import itertools
import functools
import operator
import bisect

def solve():
    n, m = map(int, input().split())
    group = []
    done = [-1]*n
    num = 0
    for i in range(m):
        a, b = map(lambda x:int(x)-1, input().split())
        if done[a] != -1:
            if done[b] == -1:
                group[done[a]].append(b)
                done[b] = done[a]
            else:
                if done[a] != done[b]:
                    group[done[a]] += group[done[b]]
                    group[done[b]] = 0
        else:
            if done[b] == -1:
                group.append([a,b])
                done[a], done[b] = num, num
                num += 1
            else:
                group[done[b]].append(a)
                done[a] = done[b]
    people = [done.count(-1)]+[len(i) for i in group]
    print(max(people))
    return 0

if __name__ == "__main__":
    solve()

Submission status: Runtime Error

Solution code:
# UnionFind

# 配列で、子のID番目:(親のID), 親のID番目:(その塊の-サイズ)
# Union Findを使う
class UnionFind:
    def __init__(self, size):
        self.parent_indexes = [-1] * size
        
    def find_parent(self, n):
#         print(self.parent_indexes[n])
        if self.parent_indexes[n] < 0:
            return n
#         print('hewe')
        # 探しているnodeが指し示しているのが現在の親ではない場合、
        # 現在の親に書き換え(memo化)た上で返す
        self.parent_indexes[n] = self.find_parent(self.parent_indexes[n])
        return self.parent_indexes[n] 
    
    def union(self, n1, n2):
        if self.same_group(n1, n2):
            return False
        
        # サイズの大きい方の親が親であり続ける
        if self.size(n1) >= self.size(n2):
            tmp = self.size(n2)
            self.parent_indexes[self.find_parent(n2)] = self.find_parent(n1)
            self.parent_indexes[self.find_parent(n1)] -= tmp
            return True
        
        tmp = self.size(n1)
        self.parent_indexes[self.find_parent(n1)] = self.find_parent(n2)
        self.parent_indexes[self.find_parent(n2)] -= tmp
        return True
        
    
    def size(self, n):
        return -self.parent_indexes[self.find_parent(n)]
    
    def same_group(self, n1, n2):
        return self.find_parent(n1) == self.find_parent(n2)


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

n, m = map(lambda x: int(x), input().split())

uf = UnionFind(n)

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

Submission status: Runtime Error

Solution code:
# UnionFind

# 配列で、子のID番目:(親のID), 親のID番目:(その塊の-サイズ)
# Union Findを使う
class UnionFind:
    def __init__(self, size):
        self.parent_indexes = [-1] * size
        
    def find_parent(self, n):
#         print(self.parent_indexes[n])
        if self.parent_indexes[n] < 0:
            return n
#         print('hewe')
        # 探しているnodeが指し示しているのが現在の親ではない場合、
        # 現在の親に書き換え(memo化)た上で返す
        self.parent_indexes[n] = self.find_parent(self.parent_indexes[n])
        return self.parent_indexes[n] 
    
    def union(self, n1, n2):
        if self.same_group(n1, n2):
            return False
        
        # サイズの大きい方の親が親であり続ける
        if self.size(n1) >= self.size(n2):
            tmp = self.size(n2)
            self.parent_indexes[self.find_parent(n2)] = self.find_parent(n1)
            self.parent_indexes[self.find_parent(n1)] -= tmp
            return True
        
        tmp = self.size(n1)
        self.parent_indexes[self.find_parent(n1)] = self.find_parent(n2)
        self.parent_indexes[self.find_parent(n2)] -= tmp
        return True
        
    
    def size(self, n):
        return -self.parent_indexes[self.find_parent(n)]
    
    def same_group(self, n1, n2):
        return self.find_parent(n1) == self.find_parent(n2)


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

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


n, m = map(lambda x: int(x), input().split())

uf = UnionFind(n)

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