CodeEff/ECCO huggingface dataset:
# Original solution
class UnionFind():
    def __init__(self, n):
        self.n = n
        self.parents = [-1] * n

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

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


def main():
    N, M = list(map(int, input().split()))
    AB = [list(map(int, input().split())) for _ in range(M)]

    uf = UnionFind(N)

    for ab in AB:
        uf.union(ab[0]-1, ab[1]-1)

    g = uf.all_group_members()

    ans = 0
    for gg in g:
        if len(g[gg]) > ans:
            ans = len(g[gg])

    print(ans)


if __name__ == "__main__":
    main()


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

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

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

        if x == y:
            return

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

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

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

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

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

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

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

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

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


def main():
    N, M = list(map(int, input().split()))
    AB = [list(map(int, input().split())) for _ in range(M)]

    uf = UnionFind(N)

    for ab in AB:
        uf.union(ab[0]-1, ab[1]-1)

    ans = 0
    for i in range(N):
        if uf.size(i) > ans:
            ans = uf.size(i)

    print(ans)


if __name__ == "__main__":
    main()
# Original solution
N,M = tuple(map(int,input().split()))
matchlist = [tuple([int(x)-1 for x in input().split()]) for i in range(M)]
#最大のグループの大きさを出す
friendlist = [[i] for i in range(N)]

def match(ab):
    a,b=ab
    lsa = friendlist[a].copy()
    lsb = friendlist[b].copy()
    if a in lsb:
        return
    else:
        for ip in lsa:
            friendlist[ip].extend(lsb)
        for ip in lsb:
            friendlist[ip].extend(lsa)

for i in range(M):
    match(matchlist[i])
print((max([len(item) for item in friendlist])))

# Optimized solution
N,M = tuple(map(int,input().split()))
# matchlist = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(M)]
#最大のグループの大きさを出す
# friendlist = [0 for i in range(N)]
gplist = [[-1]]
def match(ab):
    a,b=ab
    igpa = 0
    igpb = 0
    for i,gp in enumerate(gplist):
        if a in gp:
            igpa = i
            if b in gp:
                return
        elif b in gp:
            igpb = i
        if bool(igpa) and bool(igpb):
            break
    if not bool(igpa) and not bool(igpb):
        gplist.append([a,b])
    elif bool(igpa) and not bool(igpb):
        gplist[igpa].append(b)
    elif not bool(igpa) and bool(igpb):
        gplist[igpb].append(a)
    else:
        gplist[igpa].extend(gplist[igpb])
        gplist.remove(gplist[igpb])


# print(gplist)
for i in range(M):
    # match(matchlist[i])
    match(tuple([int(x)-1 for x in input().split()]))
    # print(gplist)
print((max([len(item) for item in gplist])))
# Original solution
N,M = tuple(map(int,input().split()))
# matchlist = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(M)]
#最大のグループの大きさを出す
friendlist = list(range(N))
# [所属先,[所属メンバー]]
gplist = [[i] for i in range(N)]
def match(ab):
    a,b=ab
    gpa=friendlist[a]
    gpb=friendlist[b]
    mema=gplist[gpa].copy()
    memb=gplist[gpb].copy()
    if gpa==gpb:
        return
    else:
        gplist[gpa].extend(memb)
        for i in memb:
            friendlist[i]=gpa
        gplist[gpb] = [-1]

# print(gplist)
for i in range(M):
    match(tuple([int(x)-1 for x in input().split()]))
    # print(friendlist)
    # print(gplist)
print((max([len(item) for item in gplist])))

# Optimized solution
N,M = tuple(map(int,input().split()))
# matchlist = [tuple(map(lambda x:int(x)-1,input().split())) for i in range(M)]
#最大のグループの大きさを出す
friendlist = list(range(N))
# [所属先,[所属メンバー]]
gplist = [[i] for i in range(N)]

def getgroup(a):
    A = friendlist[a]
    if A == a:
        return a
    else:
        return getgroup(A)

def match(ab):
    A = getgroup(ab[0])
    B = getgroup(ab[1])
    if A==B:
        return
    elif len(gplist[A])<len(gplist[B]):
        gplist[B].extend(gplist[A])
        friendlist[A] = B
    else:
        gplist[A].extend(gplist[B])
        friendlist[B] = A

for i in range(M):
    # print(friendlist)
    # print(gplist)
    match(tuple([int(x)-1 for x in input().split()]))

# print(friendlist)
# print(gplist)

print((max([len(item) for item in gplist])))
# Original solution
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 i in range(m):
    a, b = list(map(int, input().split()))
    uf.union(a-1, b-1)
gf = uf.all_group_members()
ans = 0
for i in list(gf.values()):
    #print(i)
    ans = max(ans, len(i))
print(ans)

# Optimized solution
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()))
if m == 0:
    print((1))
    exit()
uf = UnionFind(n)
ans = 0
for i in range(m):
    a, b = list(map(int, input().split()))
    uf.union(a-1, b-1)
    ans = max(ans, uf.size(a-1))
print(ans)
# Original solution
import sys
sys.setrecursionlimit(10**6)
N,M = list(map(int,input().split()))

class Union_Find():

    def __init__(self,n):
        self.n = n
        self.root = [-1]*(n+1)
        self.rank = [0]*(n+1)

    #xの木の根を返す関数
    def find_root(self,x):
        if self.root[x]<0:
            return x
        else:
            self.root[x] = self.find_root(self.root[x])
            return self.root[x]

    #xの木とyの木を統合する関数
    def unite(self,x,y):
        x = self.find_root(x)
        y = self.find_root(y)

        if x==y:
            return
        else:
            if self.root[x]<self.root[y]:
                x,y=y,x
            self.root[x]+=self.root[y]
            self.root[y]=x 
        """
        elif self.rank[x]>self.rank[y]:
            self.root[x]+=self.root[y]
            self.root[y]=x
        else:
            self.root[y]+=self.root[x]
            self.root[x]=y

            if self.rank[x]==self.rank[y]:
                self.rank[y]+=1
        """



    #xとyの木の根が同じならTrueを返す関数
    def same(self,x,y):
        return self.find_root(x)==self.find_root(y)

    #xの木の要素数を返す関数
    def cnt(self,x):
        return -self.root[self.find_root(x)]

G=Union_Find(N)
ans=0
for i in range(M):
    a,b=list(map(int,input().split()))
    G.unite(a,b)

for i in range(1,N+1):
    ans = max(ans,G.cnt(i))
print(ans)

# Optimized solution
import sys
sys.setrecursionlimit(10**6)
N,M=list(map(int,input().split()))

class union_find():

    def __init__(self,n):
        self.n = n
        self.root = [-1]*n
        self.rank = [0]*n

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

    def unite(self,x,y):
        x = self.find_root(x)
        y = self.find_root(y)
        if x==y:
            return
        elif self.rank[x]>self.rank[y]:
            self.root[x]+=self.root[y]
            self.root[y]=x
        else:
            self.root[y]+=self.root[x]
            self.root[x]=y
            if self.rank[x]==self.rank[y]:
                self.rank[y]+=1

    def same(self,x,y):
        x = self.find_root(x)
        y = self.find_root(y)
        if x==y:
            return True
        else:
            return False

    def count(self,x):
        return -self.root[self.find_root(x)]

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

ans = 0
for i in range(N):
    tmp = G.count(i)
    ans = max(ans,tmp)

print(ans)
# Original solution
n,m=list(map(int,input().split()))
par=[i for i in range(n)] #親
rank=[1]*n #深さ
size=[1]*n #iを根とするグループのサイズ
#親を見つける
def find(x):
  if par[x]==x:
    return x
  else:
    return find(par[x])
  
#xの属するグループとyの属するグループを併合
def unite(x,y):
  x=find(x)
  y=find(y)
  if x==y:
    return
  if rank[x]<rank[y]:
    par[x]=y
    size[y]=size[y]+size[x]
  else:
    par[y]=x
    size[x]=size[x]+size[y]
    if rank[x]==rank[y]:
      rank[x]+=1
      
#xとyが同じグループに属するかどうか
def same(x,y):
  return find(x)==find(y)

#check=set()
for i in range(m):
  a,b=list(map(int,input().split()))
  unite(a-1,b-1)
  
ans=0

for i in range(n):
  ans=max(ans,size[find(i)])
print(ans)



# Optimized solution
n,m=list(map(int,input().split()))

#Union-Find木
#par[i]:iの親　deep[i]:iの深さ　size[i]:iの大きさ
par=[i for i in range(n)]
deep=[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 deep[x]<deep[y]:
    par[x]=y
    size[y]+=size[x]
  else:
    par[y]=x
    size[x]+=size[y]
    if deep[x]==deep[y]:
      deep[x]+=1

#xとyが同じグループに属するかどうか
def same(x,y):
  return find(x)==find(y)


for i in range(m):
  a,b=list(map(int,input().split()))
  unite(a-1,b-1)
print((max(size)))
# Original solution
N, M = list(map(int, input().split()))

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

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

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

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

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

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

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

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

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

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

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

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



# Optimized solution
import sys
sys.setrecursionlimit(10 ** 9)

N, M = list(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):
    return -r(x)


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

max_size = -min(root)
print(max_size)
# Original solution
N=list(map(int,input().split()))
n=N[0]
m=N[1]
A = []
for i in range(m):
  array = list(map(int,input().split()))
  array.sort()
  A.append(array)
def get_unique_list(seq):
    seen = []
    return [x for x in seq if x not in seen and not seen.append(x)]

X=get_unique_list(A)
#print(X)
R=[]

for j in range(1,n+1):
  c=1
  for h in range(len(X)):
    if j in X[h]:
      c+=1
  R.append(c)
    
  
print((max(R)))

# Optimized solution
class UnionFind(): # 0インデックス
    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)]


if __name__ == "__main__":
    N, M = list(map(int, input().split())) # N人、M個の関係
    union_find = UnionFind(N)
    for _ in range(M):
        A, B = list(map(int, input().split()))
        A -= 1
        B -= 1
        union_find.union(A, B)

    answer = 0
    for i in range(N):
        answer = max(answer, union_find.size(i))

    print(answer)
# Original solution
from collections import deque

N, M = list(map(int, input().split()))
rinsetu = [set() for _ in range(N + 1)]
for i in range(M):
    a, b = list(map(int, (input().split())))
    rinsetu[a].add(b)
    rinsetu[b].add(a)

grp = 0
color = ["white"] * (N + 1)
color[0] = "black"
for i in range(1, N + 1):
    if color[i] == "white":
        d = deque()
        d.append(i)
        a = set()
        a.add(i)
        while (d):
            k = d.popleft()
            color[k] = "black"
            for j in rinsetu[k]:
                if color[j] == "white":
                    d.append(j)
                    a.add(j)
        grp=max(grp,len(a))
print(grp)

# Optimized solution
from collections import deque

N, M = list(map(int, input().split()))
rinsetu = [set() for _ in range(N + 1)]
for i in range(M):
    a, b = list(map(int, (input().split())))
    rinsetu[a].add(b)
    rinsetu[b].add(a)

grp = 0
color = ["white"] * (N + 1)
color_2 = ["white"] * (N + 1)
color[0] = "black"
for i in range(1, N + 1):
    count=1
    if color[i] == "white":
        d = deque()
        d.append(i)
        a = set()
        a.add(i)
        while (d):
            k = d.popleft()
            color[k] = "black"
            color_2[k]="black"
            for j in rinsetu[k]:
                if color[j] == "white" and color_2[j]=="white":
                    color_2[j]="black"
                    d.append(j)
                    count+=1
        grp=max(grp,count)
print(grp)
# Original solution
#template
def inputlist(): return [int(j) for j in input().split()]
#template

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 all_group_members(self):
        return {r: self.members(r) for r in self.roots()}


N,M = inputlist()
uf = UnionFind(N+1)
for i in range(M):
    A,B = inputlist()
    uf.union(A,B)

ans = 0
lis = list(uf.all_group_members().values())
for i in lis:
    ans = max(ans,len(i))
print(ans)

# Optimized solution
#template
def inputlist(): return [int(j) for j in input().split()]
#template

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 all_group_members(self):
        return {r: self.members(r) for r in self.roots()}


N,M = inputlist()
uf = UnionFind(N+1)
for i in range(M):
    A,B = inputlist()
    uf.union(A,B)

ans = 0
for i in range(N+1):
    ans = max(ans,uf.size(i))
print(ans)
# Original solution
n,m=list(map(int,input().split()))
d={i:set() for i in range(1,n+1)}
for i in range(m):
    a,b=list(map(int,input().split()))
    d[a].add(b)
    d[b].add(a)

vis = set()
res = 0
for i in range(1,n+1):
    if i not in vis:
        stack=[i]
        ans=1
        vis.add(i)
        while stack:
            cur=stack.pop()
            for j in d[cur]:
                if j not in vis:
                    vis.add(j)
                    ans+=1
                    stack.append(j)
        res=max(res,ans)
print(res)
        


# Optimized solution
import sys
input = sys.stdin.readline

n,m=list(map(int,input().split()))
M=set(tuple(map(int,input().split())) for _ in range(m))
d={i:set() for i in range(1,n+1)}
for i,j in M:
    d[i].add(j)
    d[j].add(i)

vis=set()
res = 0
for i in range(1,n+1):
    if i not in vis:
        stack = [i]
        ans = 1
        vis.add(i)
        while stack:
            curr = stack.pop()
            for j in d[curr]:
                if j not in vis:
                    stack.append(j)
                    ans+=1
                    vis.add(j)
        res = max(ans,res)
print(res)
# Original solution
from collections import defaultdict
from collections import deque
from collections import Counter
import math

def readInt():
	return int(eval(input()))
def readInts():
	return list(map(int, input().split()))
def readChar():
	return eval(input())
def readChars():
	return 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())

    def depth(self):
    	ans = 0
    	for r in self.roots():
    		ans = max(ans, len(self.members(r)))
    	return ans

n,m = readInts()
ab = []
for i in range(m):
	ab.append(readInts())

uf = UnionFind(n+1)
for a,b in ab:
	uf.union(a,b)

print((uf.depth()))


# Optimized solution
from collections import defaultdict
from collections import deque
from collections import Counter
import math

def readInt():
	return int(eval(input()))
def readInts():
	return list(map(int, input().split()))
def readChar():
	return eval(input())
def readChars():
	return 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 depth(self):
    	ans = 0
    	for r in self.roots():
    		ans = max(ans,self.size(r))
    	return ans

n,m = readInts()
ab = []
for i in range(m):
	ab.append(readInts())

uf = UnionFind(n+1)
for a,b in ab:
	uf.union(a,b)

print((uf.depth()))