#!/usr/bin/env python3

def main():

    from collections import deque



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

    friends_input = [set() for _ in range(N)]

    for _ in range(M):

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

        friends_input[a - 1].add(b - 1)

        friends_input[b - 1].add(a - 1)



    seen = [False] * N

    friends_group = []

    for i in range(N):

        if seen[i]:

            continue

        q = deque([i])

        tmp_group = set([i])

        while q:

            now = q.popleft()

            if seen[now]:

                continue

            seen[now] = True

            for j in friends_input[now]:

                if not seen[j]:

                    q.append(j)

                    tmp_group.add(j)

        friends_group.append(tmp_group)

    ans = 0

    for i in friends_group:

        ans = max(ans, len(i))

    print(ans)





if __name__ == '__main__':

    main()

#!/usr/bin/env python3

class unionfind:

    """Union-Find"""

    def __init__(self, n: int):

        """

        Constructer(Initialize parameter in this class)



        Parameters

        ----------

        n : int

            Number of node

        

        Yields

        -----

        root : list

            When value is postive, express root of the node.

            When it is negative, express this node is root and size of set.

        """



        self.root = [-1] * n



    def find(self, x: int):

        """

        Search root of node x



        Parameters

        ----------

        x : int

            node x



        Returns

        -------

        x : int

            Root of node x

        """



        if self.root[x] < 0:

            return x

        self.root[x] = self.find(self.root[x])

        return self.root[x]

    

    def unite(self, x: int, y: int):

        """

        Unite two set including node x and node y into one set.



        Parameters

        ----------

        x, y : int

            Node number



        Returns

        -------

        unite_result : bool

            False : Already two node include same set.

            True  : United

        """



        x = self.find(x)

        y = self.find(y)

        if x == y:

            return False

        if self.root[x] > self.root[y]:

            x, y = y, x

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

        self.root[y] = x

        return True



    def same(self, x: int, y: int):

        """

        Determine if x and y are in same set.



        Parameters

        ----------

        x, y : int

            Node number



        Returns

        -------

        result : bool

            Determining result

        """



        return self.find(x) == self.find(y)

    

    def size(self, x: int) -> bool:

        """

        Return size of set including node x.



        Parameters

        ----------

        x : int

            Node number



        Returns

        -------

        Size of set : int

        """



        return self.root[self.find(x)] * -1





def main():

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



    ans = 0

    for i in range(N):

        ans = max(ans, uf.size(i))

    print(ans)





if __name__ == '__main__':

    main()

#!/usr/bin/env python3
def main():
    from collections import deque

    N, M = list(map(int, input().split()))
    friends_input = [set() for _ in range(N)]
    for _ in range(M):
        a, b = list(map(int, input().split()))
        friends_input[a - 1].add(b - 1)
        friends_input[b - 1].add(a - 1)
    seen = [False] * N
    friends_group = []
    for i in range(N):
        if seen[i]:
            continue
        q = deque([i])
        tmp_group = set([i])
        while q:
            now = q.popleft()
            if seen[now]:
                continue
            seen[now] = True
            for j in friends_input[now]:
                if not seen[j]:
                    q.append(j)
                    tmp_group.add(j)
        friends_group.append(tmp_group)
    ans = 0
    for i in friends_group:
        ans = max(ans, len(i))
    print(ans)


if __name__ == "__main__":
    main()

#!/usr/bin/env python3
class unionfind:
    """Union-Find"""

    def __init__(self, n: int):
        """
        Constructer(Initialize parameter in this class)
        Parameters
        ----------
        n : int
            Number of node
        Yields
        -----
        root : list
            When value is postive, express root of the node.
            When it is negative, express this node is root and size of set.
        """
        self.root = [-1] * n

    def find(self, x: int):
        """
        Search root of node x
        Parameters
        ----------
        x : int
            node x
        Returns
        -------
        x : int
            Root of node x
        """
        if self.root[x] < 0:
            return x
        self.root[x] = self.find(self.root[x])
        return self.root[x]

    def unite(self, x: int, y: int):
        """
        Unite two set including node x and node y into one set.
        Parameters
        ----------
        x, y : int
            Node number
        Returns
        -------
        unite_result : bool
            False : Already two node include same set.
            True  : United
        """
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return False
        if self.root[x] > self.root[y]:
            x, y = y, x
        self.root[x] += self.root[y]
        self.root[y] = x
        return True

    def same(self, x: int, y: int):
        """
        Determine if x and y are in same set.
        Parameters
        ----------
        x, y : int
            Node number
        Returns
        -------
        result : bool
            Determining result
        """
        return self.find(x) == self.find(y)

    def size(self, x: int) -> bool:
        """
        Return size of set including node x.
        Parameters
        ----------
        x : int
            Node number
        Returns
        -------
        Size of set : int
        """
        return self.root[self.find(x)] * -1


def main():
    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.unite(a, b)
    ans = 0
    for i in range(N):
        ans = max(ans, uf.size(i))
    print(ans)


if __name__ == "__main__":
    main()

+class unionfind: +    """Union-Find""" + +    def __init__(self, n: int): +        """ +        Constructer(Initialize parameter in this class) +        Parameters +        n : int +            Number of node +        Yields +        root : list +            When value is postive, express root of the node. +            When it is negative, express this node is root and size of set. +        """ +        self.root = [-1] * n + +    def find(self, x: int): +        """ +        Search root of node x +        Parameters +        x : int +            node x +        Returns +        x : int +            Root of node x +        """ +        if self.root[x] < 0: +            return x +        self.root[x] = self.find(self.root[x]) +        return self.root[x] + +    def unite(self, x: int, y: int): +        """ +        Unite two set including node x and node y into one set. +        Parameters +        x, y : int +            Node number +        Returns +        unite_result : bool +            False : Already two node include same set. +            True  : United +        """ +        x = self.find(x) +        y = self.find(y) +        if x == y: +            return False +        if self.root[x] > self.root[y]: +            x, y = y, x +        self.root[x] += self.root[y] +        self.root[y] = x +        return True + +    def same(self, x: int, y: int): +        """ +        Determine if x and y are in same set. +        Parameters +        x, y : int +            Node number +        Returns +        result : bool +            Determining result +        """ +        return self.find(x) == self.find(y) + +    def size(self, x: int) -> bool: +        """ +        Return size of set including node x. +        Parameters +        x : int +            Node number +        Returns +        Size of set : int +        """ +        return self.root[self.find(x)] * -1 + + -    from collections import deque - -    friends_input = [set() for _ in range(N)] +    uf = unionfind(N) -        friends_input[a - 1].add(b - 1) -        friends_input[b - 1].add(a - 1) -    seen = [False] * N -    friends_group = [] +        a -= 1 +        b -= 1 +        uf.unite(a, b) +    ans = 0 -        if seen[i]: -            continue -        q = deque([i]) -        tmp_group = set([i]) -        while q: -            now = q.popleft() -            if seen[now]: -                continue -            seen[now] = True -            for j in friends_input[now]: -                if not seen[j]: -                    q.append(j) -                    tmp_group.add(j) -        friends_group.append(tmp_group) -    ans = 0 -    for i in friends_group: -        ans = max(ans, len(i)) +        ans = max(ans, uf.size(i))