# 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):
# 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)        return self.find_parent(n1) == self.find_parent(n2)

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