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 resolve():
    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)
    maxnum = 0
    for _, v in list(uf.all_group_members().items()):
        maxnum = max(maxnum, len(v))
    print(maxnum)

if '__main__' == __name__:
    resolve()

# 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 resolve():
    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)
    maxnum = 0
    for v in uf.parents:
        if v < 0:
            maxnum = max(maxnum, -v)
    print(maxnum)

if '__main__' == __name__:
    resolve()
# Original solution
class UnionFind():
    #https://note.nkmk.me/python-union-find/ 
    #note.nkmk.me  2019-08-18 
    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())


# 初期入力
import sys
input = sys.stdin.readline  #文字列では使わない
N,M = list(map(int, input().split()))
G =UnionFind(N)
for i in range(M):
    a,b = list(map(int, input().split()))
    #a,b =min(a,b),max(a,b)
    G.union(a-1,b-1)
members =G.all_group_members()

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

# Optimized solution
class UnionFind():
    #https://note.nkmk.me/python-union-find/ 
    #note.nkmk.me  2019-08-18 
    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())


# 初期入力
import sys
input = sys.stdin.readline  #文字列では使わない
N,M = list(map(int, input().split()))
G =UnionFind(N)
ans =0
for i in range(M):
    a,b = list(map(int, input().split()))
    #a,b =min(a,b),max(a,b)
    G.union(a-1,b-1)
    ans =max(ans,G.size(a-1))
if M ==0:
    print((1))
else:
    print(ans)
# Original solution
f=lambda:list(map(int,input().split()))
n,m=f()
# Union Find
p=[-1]*n
def root(x):
  while p[x]>=0: x=p[x]
  return x
def unite(x,y):
  x,y=root(x),root(y)
  if x==y: return
  if x>y: x,y=y,x
  p[x]+=p[y]
  p[y]=x
def same(x,y):
  return root(x)==root(y)
def size(x):
  return -p[root(x)]

for i in range(m):
  a,b=f()
  unite(a-1,b-1)
print((max(size(i) for i in range(n))))

# Optimized solution
f=lambda:list(map(int,input().split()))
n,m=f()
# Union Find
p=[-1]*n
def root(x):
  while p[x]>=0: x=p[x]
  return x
def unite(x,y):
  x,y=root(x),root(y)
  if x==y: return
  if x>y: x,y=y,x
  p[x]+=p[y]
  p[y]=x
def same(x,y):
  return root(x)==root(y)
def size(x):
  return -p[root(x)]

for i in range(m):
  a,b=f()
  unite(a-1,b-1)
print((-min(p)))
# Original solution
import sys
input = sys.stdin.readline
def main():
    N, M = list(map(int, input().split()))
    C = [list(map(int, input().split())) for i in range(M)]
    F = [[0]*(N+1) for i in range(N+1)]
    for a,b in C:
        if F[a][b] == 0:
            F[a][b] += 1
        if F[b][a] == 0:
            F[b][a] += 1
    G = [1]*(N+1)
    for i in range(N+1):
        G[i] = sum(F[i])
    ans = max(G) + 1
    print(ans)

if __name__ == '__main__':
    main()

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

def get_unique_list(seq):
    seen = []
    return [x for x in seq if x not in seen and not seen.append(x)]

def main():
    N, M = list(map(int, input().split()))
    C = []
    for i in range(M):
        a, b = list(map(int, input().split()))
        p = min(a, b)
        q = max(a, b)
        C.append([p,q])
    D = get_unique_list(C)
    # print(D)

    # C = [list(map(int, input().split())) for i in range(M)]

    # F = [[0]*(N+1) for i in range(N+1)]
    F = [1]*(N+1)
    for a, b in D:
        F[a] += 1
        F[b] += 1
    # for a,b in D:
    #     if F[a][b] == 0:
    #         F[a][b] += 1
    #     if F[b][a] == 0:
    #         F[b][a] += 1
    # G = [1]*(N+1)
    # for i in range(N+1):
    #     G[i] = sum(F[i])
    ans = max(F)
    print(ans)

if __name__ == '__main__':
    main()
# Original solution
def find(e):
  if parent[e] == e:
    return e
  return find(parent[e])
n, m = list(map(int,input().split()))
l = []
for _ in range(m):
  p, q = list(map(int,input().split()))
  p -= 1
  q -= 1
  if (p,q) not in l:
    l.append((p,q))
parent = [i for i in range(n)]
for i,j in l:
  x = find(i)
  y = find(j)
  if x > y:
      x, y = y, x
  parent[y] = x
mx = 0
for i in set(parent):
    mx = max(mx,parent.count(i))
print(mx)


# Optimized solution
class UnionFind(object):
    def __init__(self, n=1):
        self.par = [i for i in range(n)]
        self.rank = [0 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

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

n,m = list(map(int,input().split()))
uf1=UnionFind(n)
for i in range(m):
    a,b=list(map(int, input().split()))
    uf1.union(a-1,b-1)

for i in range(n):uf1.find(i)
X = uf1.par

ans = [0]*n
for i in range(n):
    ans[X[i]] += 1

print((max(ans)))
# Original solution
import sys
sys.setrecursionlimit(10**9)

def dfs(G, v, p):
    seen[v] = True
    for nv in G[v]:
        if nv == p: continue
        if seen[nv]: continue
        dfs(G, nv, v)
    
    for c in G[v]:
        if c != p: continue
        sz[p] += (sz[v]+1)

n, m = list(map(int, input().split()))
ab = []
for _ in range(m):
    a, b = list(map(int, input().split()))
    a, b = a-1, b-1
    if a > b:
        a, b = b, a
    ab.append((a, b))
ab = set(ab)

G = [[] for _ in range(n)]
for a, b in ab:
    G[a].append(b)
    G[b].append(a)

seen = [False]*n
sz = [0]*n
for i in range(n):
    if not seen[i]:
        dfs(G, i, -1)

print((max(sz)+1))

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

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

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

def is_same(x, y):
    return root(x) == root(y)


n, m = list(map(int, input().split()))
par = [i for i in range(n)]
for _ in range(m):
    a, b = list(map(int, input().split()))
    a, b = a-1, b-1
    unite(a, b)

cnt = [0]*n
for p in par:
    cnt[root(p)] += 1
print((max(cnt)))
# Original solution
n, m = list(map(int, input().split()))
fri_dic = {}
for _ in range(m):
  a, b = list(map(int, input().split()))
  if a not in fri_dic:
    fri_dic[a] = set()
  if b not in fri_dic[a]:
    fri_dic[a].add(b)
  if b not in fri_dic:
    fri_dic[b] = set()
  if a not in fri_dic[b]:
    fri_dic[b].add(a)
visited = set()
max_count = 0
count = 0
for i in range(1, n + 1):
  #print(visited)
  if i in visited:
    continue
  queue = [i]
  con_visited = set()
  while queue:
    p = queue.pop(0)
    if p in visited:
      continue
    visited.add(p)
    con_visited.add(p)
    if p not in fri_dic:
      continue
    for j in fri_dic[p]:
      queue.append(j)
  if len(con_visited) > max_count:
    max_count = len(con_visited)
  count += len(con_visited)
  if max_count >= n - count:
    break
print(max_count)


# Optimized solution
n, m = list(map(int, input().split()))
fri_dic = {}
for _ in range(m):
  a, b = list(map(int, input().split()))
  if a not in fri_dic:
    fri_dic[a] = set()
  if b not in fri_dic[a]:
    fri_dic[a].add(b)
  if b not in fri_dic:
    fri_dic[b] = set()
  if a not in fri_dic[b]:
    fri_dic[b].add(a)
visited = set()
max_count = 0
for i in range(1, n + 1):
  #print(visited)
  if i in visited:
    continue
  stack = [i]
  con_visited = set()
  while stack:
    p = stack.pop()
    if p in visited:
      continue
    visited.add(p)
    con_visited.add(p)
    if p not in fri_dic:
      continue
    for j in fri_dic[p]:
      stack.append(j)
  if len(con_visited) > max_count:
    max_count = len(con_visited)
print(max_count)
# Original solution
N,M=list(map(int,input().split()))
l=[[] for i in range(N)]
l_c=[0 for i in range(N)]
for i in range(M):
   a,b=list(map(int,input().split()))
   a-=1;b-=1
   l[a].append(b)
   l[b].append(a)
from collections import deque
def search(start):
   que=deque([start])
   after=deque([])
   while que:
      A=que.popleft()
      after.append(A)
      l_c[A]=1
      for i in l[A]:
         if i not in que and i not in after:
            que.append(i)
   return len(after)
ans=0
for i in range(N):
   if l_c[i] ==0:
      ans=max(ans,search(i))
   if ans>M//2+1:
      break
print(ans)

# Optimized solution
N,M=list(map(int,input().split()))
l=[[] for i in range(N)]
l_c=[0 for i in range(N)]
for i in range(M):
   a,b=list(map(int,input().split()))
   a-=1;b-=1
   l[a].append(b)
   l[b].append(a)
from collections import deque
def search(start):
   cnt=1
   que=deque([start])
   l_c[start]=1
   while que:
      A=que.popleft()
      for i in l[A]:
         if l_c[i]==0:
            cnt+=1
            l_c[i]=1
            que.append(i)
   return cnt
ans=0
for i in range(N):
   if l_c[i] ==0:
      ans=max(ans,search(i))
print(ans)
# Original solution
N, M = list(map(int, input().split()))

f = [{} for i in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    a -= 1
    b -= 1
    f[a][b] = True
    f[b][a] = True

for i in range(N):
    koho = set()
    for k in list(f[i].keys()):
        for ff in list(f[k].keys()):
            if not(ff in f[i]):
                koho.add(ff)
    for k in koho:
        f[i][k] = True

ans = 0
zumi = set()
for i in range(N):
    if i in zumi:
        continue

    koho = set()
    ans += 1
    for j in range(N):
        if j in koho or j in zumi:
            continue
        for k in koho:
            if j in f[k]:
                break
        else:
            koho.add(j)
            zumi.add(j)
print(ans)


# Optimized solution
import sys


def input():
    return sys.stdin.readline()[:-1]


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

ans = 0
for i in range(N):
    ans = max(ans, uf.size(i))
print(ans)
# Original solution
import sys

read = sys.stdin.read
readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 8)
INF = float('inf')
MOD = 10 ** 9 + 7


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 main():
    N, M = list(map(int, readline().split()))
    uf = UnionFind(N)
    for _ in range(M):
        a, b = list(map(int, readline().split()))
        uf.union(a-1,b-1)
    L = list(uf.all_group_members().values())
    ans = 1
    for l in L:
        ans = max(ans, len(l))
    print(ans)


if __name__ == '__main__':
    main()


# Optimized solution
import sys

read = sys.stdin.read
readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 8)
INF = float('inf')
MOD = 10 ** 9 + 7


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 roots(self):
        return [i for i, x in enumerate(self.parents) if x < 0]


def main():
    N, M = list(map(int, readline().split()))
    uf = UnionFind(N)
    for _ in range(M):
        a, b = list(map(int, readline().split()))
        uf.union(a - 1, b - 1)
    print((-min(uf.parents)))


if __name__ == '__main__':
    main()
# 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)
ans = 0
for i in uf.roots():
    ans = max(uf.size(i),ans)
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())

import sys
input = sys.stdin.buffer.readline
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)
ans = 0
for i in uf.roots():
    ans = max(uf.size(i),ans)
print(ans)
# 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()))
Network = UnionFind(N)

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

out = 0
for L in list(Network.all_group_members().values()):
    out = max(out,len(L))
print(out)

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