from collections import deque

 

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

g = {i:set() for i in range(N)}

v = [-1 for i in range(N)]

for _ in range(M):

  a, b = list(map(int, input().split()))

  a, b = a-1, b-1

  g[a].add(b)

  g[b].add(a)

  

Q = deque()

ans = 0

for a in g:

  if v[a]==-1:

    v[a] = 1

    ans_tmp = 1

    Q.append(a)

    while len(Q)>0:

      na = Q.popleft()

      for nb in g[na]:

        if v[nb] == -1:

          v[nb] = 1

          ans_tmp += 1

          Q.append(nb)

    ans = max(ans, ans_tmp)

print(ans)
N, M = list(map(int, input().split()))

r = [i for i in range(N+1)]

n = [0 for i in range(N+1)]

buf = []



def root(x):

  if x==r[x]:

    return x

  else:

    r[x] = root(r[x])

    return r[x]



def unite(x, y):

  rx = root(x)

  ry = root(y)

  if rx < ry:

    r[ry] = rx

  elif rx > ry:

    r[rx] = ry

    



for _ in range(M):

  a, b = list(map(int, input().split()))

  unite(a, b)



for x in range(1, N+1):

  if r[x] != x and r[r[x]] != r[x]:

    _ = root(x)

  

  

for x in r[1:]:

  n[x] += 1

    

ans = max(n[1:])



print(ans)
from collections import deque

N, M = list(map(int, input().split()))
g = {i: set() for i in range(N)}
v = [-1 for i in range(N)]
for _ in range(M):
    a, b = list(map(int, input().split()))
    a, b = a - 1, b - 1
    g[a].add(b)
    g[b].add(a)
Q = deque()
ans = 0
for a in g:
    if v[a] == -1:
        v[a] = 1
        ans_tmp = 1
        Q.append(a)
        while len(Q) > 0:
            na = Q.popleft()
            for nb in g[na]:
                if v[nb] == -1:
                    v[nb] = 1
                    ans_tmp += 1
                    Q.append(nb)
        ans = max(ans, ans_tmp)
print(ans)

N, M = list(map(int, input().split()))
r = [i for i in range(N + 1)]
n = [0 for i in range(N + 1)]
buf = []


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


def unite(x, y):
    rx = root(x)
    ry = root(y)
    if rx < ry:
        r[ry] = rx
    elif rx > ry:
        r[rx] = ry


for _ in range(M):
    a, b = list(map(int, input().split()))
    unite(a, b)
for x in range(1, N + 1):
    if r[x] != x and r[r[x]] != r[x]:
        _ = root(x)
for x in r[1:]:
    n[x] += 1
ans = max(n[1:])
print(ans)

-from collections import deque +N, M = list(map(int, input().split())) +r = [i for i in range(N + 1)] +n = [0 for i in range(N + 1)] +buf = [] -N, M = list(map(int, input().split())) -g = {i: set() for i in range(N)} -v = [-1 for i in range(N)] + +def root(x): +    if x == r[x]: +        return x +    else: +        r[x] = root(r[x]) +        return r[x] + + +def unite(x, y): +    rx = root(x) +    ry = root(y) +    if rx < ry: +        r[ry] = rx +    elif rx > ry: +        r[rx] = ry + + -    a, b = a - 1, b - 1 -    g[a].add(b) -    g[b].add(a) -Q = deque() -ans = 0 -for a in g: -    if v[a] == -1: -        v[a] = 1 -        ans_tmp = 1 -        Q.append(a) -        while len(Q) > 0: -            na = Q.popleft() -            for nb in g[na]: -                if v[nb] == -1: -                    v[nb] = 1 -                    ans_tmp += 1 -                    Q.append(nb) -        ans = max(ans, ans_tmp) +    unite(a, b) +for x in range(1, N + 1): +    if r[x] != x and r[r[x]] != r[x]: +        _ = root(x) +for x in r[1:]: +    n[x] += 1 +ans = max(n[1:])