Problem:


Score : 400 points

Problem Statement

There are N persons called Person 1 through Person N.

You are given M facts that "Person A_i and Person B_i are friends." The same fact may be given multiple times.

If X and Y are friends, and Y and Z are friends, then X and Z are also friends. There is no friendship that cannot be derived from the M given facts.

Takahashi the evil wants to divide the N persons into some number of groups so that every person has no friend in his/her group.

At least how many groups does he need to make?

Constraints

2 \leq N \leq 2\times 10^5

0 \leq M \leq 2\times 10^5

1\leq A_i,B_i\leq N

A_i \neq B_i

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
\vdots
A_M B_M

Output

Print the answer.

Sample Input 1

5 3
1 2
3 4
5 1

Sample Output 1

3

Dividing them into three groups such as \{1,3\}, \{2,4\}, and \{5\} achieves the goal.

Sample Input 2

4 10
1 2
2 1
1 2
2 1
1 2
1 3
1 4
2 3
2 4
3 4

Sample Output 2

4

Sample Input 3

10 4
3 1
4 1
5 9
2 6

Sample Output 3

3



Sample input:
5 3
1 2
3 4
5 1


Sample output:
3

Submission status: Accepted

Solution code:
# This code is generated by [Atcoder_base64](https://github.com/kyomukyomupurin/AtCoder_base64)
import base64
import subprocess
import zlib


exe_bin = "c$~dk4Rlo1wLW)dk_;i48#N#xNVH>36vm7MOlr_fn1nlaf(XP?3%!QPgiOufOKuR5r;tf_T*pzKcD1ZlEA{6srCO2KMS<tzB?ber=tEnn6@RD|oH2^=hY$oZZ|`%@nYnW_)1SBAdY3iX_k3sXefHVsoPB=o;l3(wwMh^Nf6U}2f~kT_v~&f-^Bi#&z)Hyk_<K2-K{6q2(eWASsE|yp@p3e|Qj?Z8(&;3b3ObrW(my+<CsU|NTn=q5o}r<|GYXPugq6GHach#CiOES!PGbC=<}o==xwM7-mNDE&-6WY>7+riqsmJ#NQ?;~_){|t)<!%GHO!D_Xd5kV$<)!n>5oRx^ydAD<3apw}a$QsX?503V=i1q8OXtm=SK{bsbzDzv%456>7u8aJY;Tj!=6r@>{#_HNy=8wQr~95qPX4>H{k5OnAz!h?#CUkSVS8*8@+dY5enm4Ln7+EUj#p#c(+t0hQ{W|_@X8eUL?Jc*)HL{58vUEo;7_E%KTd-?(v<s58vX@o_`_-VXA<7Slb_eq@P9Xr{=77LZcKw;okmY>nsP4&{)@;|Qc$32<Kt_TXn3&!C(tiDlzQK_*J59sM`U?*b8Cy-q13f2vP@*pvKqPG-|k->=urIa%W4)hwYK<|)vapsYk8@2?pU-`DGjuC$gAo){3V{2fZ}#mtpR+g;=DnYmB#kgyCJV$u4`&)^<hSR)8aK)_}aB{o4>uIwWY2ppsbVE6hmIi-OZ^~E<lxF{%W63?m+9EM6PYQJJ3=uFY$MDHv2Kt$EyW3^4%r-8t;-D>H<v!>KteR*tfP$u2cML0}5&OH+T3I%xUdZAPdsXt!w-!LmKXG4=8@p(C)9RXHpFTv~j(kFg}2>Jm$LQI#9oG!2)@XqnIpMzT8#mk)4h?WTDqn2}yuUw0HS>-J2f0-Z7Wpm^Z;c3;fLRFN0DO9pPClKA0Gf_6YE=SJ%%Le|z0T<XtK7d=rfkm|qOP-@kBI21X3OpkYeU!&WS{EzWNy?~z3O%MS!{aYos|`KJaZV1(Mt(w);VZ6Xgdc^((zvqZi|OAUB2>&z7f{5YFet%iQf(?@1%G?OIaB|dNK@LU~!T!)J~Jfg$(L2_7!U!=oFb@(MZJdfFh)z8u4d_3Y@oUg-+b@(J5-p2H2k;EK=&srUB*5Mm<xJ8F=(c$`az*Zfup9i<;@GKp^U58tB_%k|uf)3xQ!?Shx9vwbWhxh7mn+`vu!}ak_3Vv#pLK(G_3y9RytC(U(q~HN-KZ(uVH>rTcu6haniZd(V4bzP%5<MP+=c-+pMwdp9(DV*WW7moH()1IUM%PAn()7<TjV_IDr|E|=jjoJtrRn=IjV_FCr0Fh9qq)&GnqH4-bXoLHnr_E5x+=PurhkNKbWyZ|rdMGaT@x*)={q3Zu$9-_^*z_^Qh5HPU3TKCbuFu13XW)$!iv4HUJ6;RDn!?)Zu@d)Z$tp4m@^CbPrPU+kzpuR@~yBJN(bHcQtCx`so*aXed#%-uCN!2J>SYe=^4*~pcHNbWadW9cZcfjvs_`fJyzB85fn5_?0y!U<qgfg|HVQgh34J^#9MYs?0yq`D(=oK&sHqu1)Wz*;c7vg3C3l7A2`I_R!JR@g1y4Vvjxg08_#AdCqPQs4{Z6KvRA~-PeK!cx>=MtvwXJL9RQ^KI`P5j&=}4)tDGNU`z{FQJQX}HO2Gj^Qs<8CEF|u*T|$ZL?)yvkn~K?W=3P(OX|elPN#@Mb%&9<o26v{lN9=yojBa2ywNjfVZKDDvwCQ=G*|Z7RoFh{3Wx+Wp&V)s3I7daZ)Jb;%GveVKu&Oc!W_?uAJ))S-{K*ykRFFc;?4`k|P~-d5(|5vjOSt5kP-aiBs47sD*B4C&7Xs)m`?J`+W-J!-_zp<nk}k>DCx!F7LN|p>We4xgcd5PVs7pQURu6jABa-^1R~-;W)l9c~WwZjMr0^}^sNA<+z$#P<X!~}oqWbE7Iws1X%Td3CZwJ0f&r`l?cs+`&8-R5m<@@I`jn7kbdT$;?97+AatA4U5Y`-@0?0G0Alxw=Afb7FyL=}6BKJls_N8W=xj{t_xUHXEZc-5<xK>@A-3v@E|=g15l$pui<%JkQ$r?`Gk(TG?5a#48JoJh4+#N!ty7Xg+1JhGk^@rtCr<5g#${xzzvB3ymc&GdSG!<C_&T|I-M`UenJGu6K6FCowCJ6;(of1)QQs%8`7F7-gPg9_39PmOWD=~YjGMUnmIs2!Ik*?}3SF++G;Qs0LT)&@olVDB?0D!Br%@&d8@1Xx?1Eq0@0qTig4mjhb+E;4F;oM{cuo%Cz;SjOZOnoUgev<sT%i-AUqFQ8`Vmm#;ku&4Ll<+S5DKXV@QLWC$Dx?G&uP2<a%w_Rli+@kk*@D)J{_FKxD?1lGUBZYIOg@m5owa2}_2=vDtp_|Y{dq6-HLYYH@4O|{#%~Y`4t)7frlto9&lIJmk%rFBgg@b4$?So}~VsI{0Y`~N)g*MnrrC`R@z$r*QF(o6?^Gz(~?8S`b_0pVj8rQ_0c_s|}2O58{(zU|1()B}^+z%mQ!t>Byrhx05gVASzKxBwcIFC(vwlZYdhXdzJ5U*5ocHvM`4@GS_5PSziIbGgxc@LV6{opJ$zoe^DE#H9^R!5^VW2oi~sM&>T`ly=nC#agy=m+3bX-`ahZkEdW#eb>B2oaw37<C17#@Ehbi@oA}ll$kOh0Yon5u~!;cMfZHSDWk=7`Ew~1TGM}H-ZNu_kwtI%{R1azdNT@?OLtRJtBfXi{6R%jeaaio$=AHuw%RveVX>=Ug+apJ%j6RtW+)gpofoAbhI*5vae@k-7SFbQV&LpXf68y?E>^lh$!Hz??{mI8RZ{@`rqHvyKXkXUFxBsU6Sv04RKbgC0*(lLx;V-0buF^s05&W>hRE$lJ8Kc<o=!!QQb`4X1QPO8~RVL?@%R!af^rOz|h_}y6$RV>_R9~Ig0h9-s#smMH?be)kBni?p3|^DPHhe9=up1yRdU$ul9xzhmM{HFIFsgXh&oj$PDcSDM^#^+VfD<8o7syNtzgDfUFh7q6^V6>KR&)ln{}UN|NFtSXA^HklEVc;O)H>2E^JOg*XBPTLFoDdIoDX|M^@T4U=|LGWUDH5b464aPEye?AoY@=|uhSh!;?ZxLWc981k2)GBsm5id;uU{sXi3RXmC_P-Hql-tZ$98Zu`beb!E@oP(}CuN^*on2vu>c>Q^=dep5Bs)wZDDZzE-c;6@Hu;pQ)x2P{TSiEHs^vf~zjn3n)V4vU#zHD)AI-7SjEbL$T0T`U289a}Y`7@#OMPD6>#S-;(e&$i%_@ShJC<Q+nUcAg3&RCy`Ln7Bq$^3G#FE;5XIR)fvY7antkf@cy8GC_BWuuaMLYWFnyC3CfOS{~avEvE-EBi5eC(<ClDTms$o~kJt19_=$3<Bb?)EBu~5(cC<#uR9!3@1~Vg9_8>+c^I=U?ZK^Nx}IaOoX>uv?m9eEF17hGgLMrK@|oviXbhZIE~j|^*7M^Ap6Q_18`_*DfCn6Q45Ci4?&wYT8qAkP8wnHSPI>0rOP<q`%>RuOfZ#C4VhpVW&J=MhA7uh=cAHe!pNAU4yYz|7-L_*uKwzU2!<djREz!Z2}yWo=x8E)D_bP0rzQ2Awr2jRmCh4SVjuIA{Xy);BO8~v+hXTyBM&U^1U?U`G-Sj2$fF)eULS$5@>}H1m&#riH+NxltI~`LJ)#N08cC^fzUdr<Wsh}e4y^w|wIrPXFf5J2mc?onaIzU;F)T5dPz9_??)zi+pkh9=62rY!3-|r3zf=lwn{fSd?>nG!FZy-p-$1{&=tHl15?2fATXZ!N`kIDIC7VsAunK{-2yKYStzXmCh*y0QeWG86M6c)TpipjEwqYLjsP9Jdzh)DB5Ji*bV5mJ}I0x?<)8^nEK%<A@4{Z-`_yy#vUFuQKt6yoY@&fH8;VNyRIRYj1922`Q2P$sa1AjN2dmOgdp72X{9PQ$Re;|m(j-SpDA1b8z_x)rW5g$5F-zzFbQXxJz;1+kkULo!t@dW!ag9Dkk{`S4@+VlNOfBS|Mj9P{!Z1semvt!Zf+rd*78Vqs+FXMPG>c{TrI~KCcRDZ9!a|sG;`bLDT`(E9H`ynn0DvO4tZ5q2I^h?4AQt+%*4DJM`kv@yq^RGB7_6#bbxI1g4&$Oiq=JMTu)d&x08WN4X=^QPganrevVXY}XG#%K2=X~OWbKnIXLH5$U8J<6C>(nZNy6k2FE$XKF21v0dsJ#kF9jJo1_TtuSKiz)~LxZ^X;#O`y-OnAzWkD!Q3fEet;D->1uz$KSBDr%%rJ}baAu1JpE(QNQO6%7(pHAd|9>s-9NtUFRm|%cdrLsfqpGU8VucMiLZ$SyL5S`6!JabG6HwqqA^I>%QSiHaO&4M_ke!^n~j_{LT#9}q-QyS}EF3{k@;%)C<+7{|y^d8#3_TpA^KizNUjo~6HcrIIfwAVQZwwdt#u|5eR`_OBlET~_|EuM$kosa$#t$Xf#UD<RfeH{6bzU-f&nZI?5V+|lR7QIoE${Hu-RZm2mdO?Bt1NW~U^^e*xxaxf~4gIrE0$u7-FL=}uZ_x=lBKj_vBbN??`kv2}0_QPaU$6R&R~>PypSxoD@4^BVW~=u)KS?w)T@>o(->>@FSphvAVCP?#nQy$4Xy*^_ejbZG2lP283dht-KqF9(CRi_&!#uwNmQ@=7Z-PZw4&V;}g&{~j1-b(023TlrLkjg<0sNl=eae(L;}O;`A;Q``;j)}8>sBEv4{`j|@;2zdmL#6k{DjyUe<9d;1Q~33)wU_Oh!gL&ZX`EPyYZSi_A9wOej7OgeERd5`1hdoi@j8H*3WA)3dm(#KgwYl%b}i^0ku4?oi>%g@5k`F6L9)PqS}`CfXQW>vf1pi6$C9yvTaiq*zziER@X#)chUFnPQ+t{!|>Yzau1=ZN?TsoRB4;?0LpE)xNL>Nj9YBQrr%`S3IPF)l~lBPBJl#d6=dE8-<~%m$x3lqkFD5j77W6!iKbcuR5g(-rWFT!PQ_wR!)C;CP}BJk>U_}bu@!_ZmA1kMGF-Oe&6zG+X)w!e+b)=gE!nnGz@WTJTR~-_5a!S4KxZLL;3rW(R6J-h{m#amj%{!l@~6Nc^^>IXs^aBISe}IC)z~W9Q<X)}AoIZo6`)6dt{IC7_`C9&$r!c1Fu!CYzn++JDwk}_$$<B0F1`nCf9;ds|Leogd-?e;KhM>FpVZS{L;5{N`B~}~cF4%jbbrIX^Dz=XZ@!GB`C0BXM)~<N9~XSAoF0p{BHhNE%^i4z9j5X#(q5L&&oqC*4CQB;QyA5s<>JH7YL~O~Ox~siOrDQ_e&%{9qm9;Nyf`b_?ouYt&t7@?my={Z*fi4m2@D!z>FumyF_z|b4zqL%%RkG~`m^Q#%ZGm-Ha@#q#ReEX%IHZ(M;Ogy4KkV0Z!<cN(P~C-XS6|oDE+^9`1c3?EL^bQI|YTct2$eh&Vm~pa~;LA=XBDP^Im7Eqqw9<L;oJ#W@x2SQ!3mP{~n%<n~9PVx5WE%GM*9d$H{nRyuT;oS@C|5j9cUVCmEj*@2AOlcDz3);}hfKIvLL)+f(AXq%B4JnTd^TOo@x}IFXF!k=~T}Me+Ls$@s;ja9S$-60&i6Dm*_PkCO38@i>%>Pfj@w%n%KD+(^c!;D@CYc;fqSGCtmT3?CNqMa+ofw=om=lgI6o48M}fOeH&CDvZnH<4mKcoatG7Niu#D!?zmn+ZcY_fUjodmg>H*;j@OmkN4+eOiw|65=@?@{Nvjto&AR>|HWiOiuO&#f0X_m-+!W1&-nKJlK#yfXTMp{aHE}*1=KUXKg>$=-M@l<mz_eU82ST#oheAse-=_biE+Wh!R=}8A#6x<KV%!_PmIT>Sv+_wjh+{=T+@_sadkh{5B-p}BcIpb0{jZ#&ok8bX*22{Ki<C(Qr~~Dn9|($NQ0N9!H=4>`to~Vd~IKohX2kq__fsj@$qnjN%N1f9k-Y?|LkP`d58^+=NMiwSxcYS-Al?#(e8LZClCCyhmC9gyqCt#VUxyhwC8*p{wvIye=1nJ_!;grr{=FtgReHHz9$n*!~b(u?oL)NpZ0#0hX2(x`u}9s`cDO`@8U<bk@3D+^Ydcn|60cXRT@3HmNfpcr0(aqj>B@dzhtNBJT@Xr)94{?xw<{zZ>jHa_}bctywH1VrOPYJ9i6LW58hd!mvFqLvK(j)v;-95Ygamy&V~kuk0kE-$V#*9!}~lPM3(DY<<(8CtLmEMdZo3!L$2#wOMI=(ZB2f~U+=hKURh~sCM+!=*R{9Tt&{yNO8Yv}&|cT<m+L#5o7aJeE+wNWNvyJ5y~I^hC08wS<259C;i6i(N@AeoUP5H|_ZPWpJPRN%Nw_{4pto`2Zn(9&dTG@%d6}!yTP3rbJ{1-E8#l7QzD}tlvgcNrUJ;TzJN)%&FD@}zcAqEtUQn`LdLKx;VPq&!uJ34-8|zx?wTn~ps_Qxw&#gBsZV$9TOSrGET0`95bF}*#94W6yQ7erqbyt@XSqT%h3r_|idIif+A-sBJtYh*;s)Q2ETUN7xw^*VkOMP`ME&lcrygTIycmu^%RaI-2ER$2zb}qeU6=y;o8QX(3BfWlQtm~?d4&KVC?}!;IKyPXJIyz}L;kUPpTE~03qC$6#>#yF6OS*&xirFnNUCB5y#@`nkXM_GGUIV?9cE_T!+Ll0TOEnZw(%#ytR0aOZJv{B!nz5b7busN~Udk(b$-X0wj&;pS-726;yG9%N8&%at94)Pi-vMr#t<<e%snso=j#Zt3rux}|dO}l;bsdewQNOMQ^l4OS*K*c?&!K)v2^sR*{Y`bq$lltT6f6?j4__UtTj2#dHT<Qnb+otAVeIfXvM|$F-=0W;cAro7ul4!c6j`CJawKAgrh~sjnRU$pAG}b7(A$UuqF*zFsZ`<jAAK;+<CM+krF8eY`6C$8-y+)C0GBu3n=UZ$8@G2(gFN3ya%%q@@_61g5{tERdA{G|l&>cEd5UrSw}@zGCtRNIOF8BD#BrM`=;Zl1$L%Eft~B4ja{3E{!;Jp>A<@o0xIEwIayrXkzsW%FBHCFBPxJjSr~KkpCbQF6|Mf)kDVOK_W={F}j?sU-{@qNzlBN0nn$rTE{G}=6A0+xa<B9V%PWd?$e~j&~8szzYozo)*{yYQyu|b~i>p3<0%W9yH8RYqXgVXEvmpn=G-A;U-G|2OP1E<F02V?!8W%7J2#`jIe{gY9i(-%qd_)qu$7t)pgUj})8KEdg7!#R)9pMwT@evZNEH3oj;_&G+j`<ndRF!BE(w6xLR#`eSe{Gv{t?}IC5q_)>6{}oA$EqoIH--MN~iywM9Zr3(eC*%3-@|jxtnZHr~d4qg>U&RO?XGVGcnAm|Vm*@NUDNKIbqsbBl2Kg*OE8lpq$mNR+c&c;v6i0zXV)Dyb@z@<4WPJRXptD{7Y-fRgrJ=(b`_Dyb<S($moA)>3_x}KD$#Q!"

open("./kyomu", 'wb').write(zlib.decompress(base64.b85decode(exe_bin)))
subprocess.run(["chmod +x ./kyomu"], shell=True)
subprocess.run(["./kyomu"], shell=True)

Submission status: Accepted

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

    def find(self, x):
        """
        要素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が属するグループと要素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):
        """
        要素xが属するグループのサイズ（要素数）を返す
        """
        return -self.parents[self.find(x)]

    def same(self, x, y):
        """
        要素x, yが同じグループに属するかどうかを返す
        """
        return self.find(x) == self.find(y)

    def members(self, x):
        """
        要素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 = map(int, input().split())
    A_B = [list(map(int, input().split())) for i in range(M)]

    uf = UnionFind(N)
    for i in range(M):
        x = A_B[i][0] - 1
        y = A_B[i][1] - 1
        uf.union(x, y)

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

    print(ans)
    return


if __name__ == '__main__':
    main()

Submission status: Accepted

Solution code:
N, M = map(int, input().split())
F = [list(map(int, input().split())) for i in range(M)]

d = [-1]*N


def find(x):
    if d[x] < 0:
        return x
    d[x] = find(d[x])
    return d[x]


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


for f in F:
    union(f[0]-1, f[1]-1)
print(-min(d))

Submission status: Accepted

Solution code:
# -*- coding: utf-8 -*-
import numpy
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 = map(int, input().split())
uf = UnionFind(n)
for i in range(m):
    a, b = map(int, input().split())
    uf.union(a-1, b-1)
answer = []
for i in range(n):
    answer.append(uf.size(i))
print(max(answer))

Submission status: Accepted

Solution code:
import sys
#import time
from collections import deque, Counter, defaultdict
#from fractions import gcd
import bisect
import heapq
#import math
import itertools
import numpy as np
input = sys.stdin.readline
sys.setrecursionlimit(10**8)
inf = 10**18
MOD = 1000000007
ri = lambda : int(input())
rs = lambda : input().strip()
rl = lambda : list(map(int, input().split()))

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

    # ノードxのrootノードを見つける
    def find(self, x):
        if(self.root[x] < 0):
            return x
        else:
            self.root[x] = self.find(self.root[x])
            return self.root[x]
    # 木の併合、入力は併合したい各ノード
    def unite(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if(x == y):
            return 
        elif(self.rnk[x] > self.rnk[y]):
            self.root[x] += self.root[y]
            self.root[y] = x

        else:
            self.root[y] += self.root[x]
            self.root[x] = y
            if(self.rnk[x] == self.rnk[y]):
                self.rnk[y] += 1
    # xとyが同じグループに属するか判断
    def same(self, x, y):
        return self.find(x) == self.find(y)
    # ノードxが属する木のサイズを返す
    def size(self, x):
        return -self.root[self.find(x)]
n,m = rl()    
uf = UnionFind(n)
for i in range(m):
    a,b = rl()
    uf.unite(a,b)
print(-min(uf.root))

Submission status: Accepted

Solution code:
code = r"""
# distutils: language=c++
from libcpp cimport bool
from libcpp.vector cimport vector
cdef extern from "atcoder.hpp" namespace "atcoder":
    cdef cppclass dsu:
        dsu(int n)
        int merge(int a, int b)
        bool same(int a, int b)
        int leader(int a)
        int size(int a)
        vector[vector[int]] groups()
from libc.stdio cimport getchar, printf
cdef inline int read():
    cdef int b, c = 0
    while 1:
        b = getchar() - 48
        if b < 0: return c
        c = c * 10 + b
cdef int n = read(), m = read(), i, a, t
cdef dsu *d = new dsu(n)
for i in range(m): d.merge(read() - 1, read() - 1)
cdef vector[vector[int]] g = d.groups()
for i in range(g.size()):
    t = g[i].size()
    if t > a: a = t
printf('%d\n', a)
"""
import sys
if sys.argv[-1] == 'ONLINE_JUDGE':
    import os, zlib, base64
    open("atcoder.hpp","wb").write(zlib.decompress(base64.b85decode("c%1D$Yjfj9j^F(&dTJ|klq_jvd6L}vb(fiBvbjrkH*4pv>ReidmMEEHiqw*nEPKZH+YdlL*e^<y?b+l~Q6*!EjYgx<02+-(H~0P!r{iQfiP%Y)%(6T#ujglb+QU2#@6Pt%$#fD;+31J!x1<01=5HEAoR)c<_O78;luqL5-d-Bcqhb+`BNmq9Y!c<{gZ>aIM0pw}`1I8)_V0@@59cgpKlj<mDNBE*hj~;k^OViwG@dV^G)uc_Gz-gk6|tY!KeM7&_SnxU))=(g>!0@kD;q~~GFoJ}g8+Y}Eogzk2Y;;DDeE88&)e%biC7RE{KQU9*t*3|Sg=fsc$P*Jglz?BtHsv)`y5<QvOeB>u;@M5ncg5}FIjNF+ikHIKoh6@s+bxyaN=#IBRL8x$<i5sPNFrZbMz)I&&Of<F3WGjd=k8*vJPM}`XOrkAxer!e?A&rE#st&)6uxR53rILPU!UmW6(!;1l<xb;Cp*}nuILNIEhP?qDM)_TyT1BaC*(=*@Vsa##vgF(Rz_{hR{DnIE_Y798`~h5!H{ml#Dg|4DfRP#8VcmK^FQj_H180wuk>+Sd`fGG6CwZ?${M*NK}>pH(8F$I7<=eZ_zZ$qjVe{vFoy26i2UKMQQIgzKIvnBo2F7K6{0~UcKS9M@H>G|K;MFBS45<i;+p;6!^lv0}g#3-b8yvnFFwD`GYAJC_N)VyeTYPVxWl1ybQ(yf!CBrVA&C%4d$&5pa=pNb1Uc`wAd@aw$I?phli>esT?k$OB|&Zqd{aJlq}AV*@I1GC=5ghV<af83a>=rm02k8{T#A36n!R(%$_Y1v#Vjp1h`W4QDuSq@?Z#EJ!J>_!;m2fr@$dJHyu`FEV~Ks_Kb=Htat`?OMgl=(0&Djzkl%>+1S#HyJrZ|rWOfcpXDr|F6Y=~12~CFb`OAI8)+H0aYQBpdfb7pb_E1%a}ojp-jWZ-?I51FVff);TRagIjN7?*sw1nOVmn0hKK(Tw2o!TN;PQK$1wwjG_`|lzq#y`6p)GcH#=dynVy8e3%X0W<UmFRJ*b_gF6~sMj!$=)_Eo=>jbya(`1fe+?{A+NJ%Ftmi*Dc+m)*)c0su(|B9nv&wGy>^^R$9S*t6lY38D^&`6xJ1vp*fq~vo5sV2CZsUT|jF$BJQtRPzmgvv>Esjdb8qB9`+uNH%!%=tn|-dQrm5u%}Dut#v0~pwACY3R%f--j<iG{l);{(1c1DV=K9AzTj;Vxa>6r8IqGz6=^d1+*#)SRh=fm}Tn<Se&i6<jl90m~+#w@$P9wtL&R3Gccq>vK^tmXPb5S+T;IAKg4Cem0h;CSzPS}6+*nfoSI8MWknz#O%$MX>9Vs;S~FxSu66qM&Xn09ATUa*Vnuw?Jz5}A~NG5aALU&m?0{yWPj{_(E{^eW2|78j!hG!bcoX?kMBk`sN%rXi@!u~rHLI$$3^GWzzV`u0Ut1*Siv#%E9gAo@O>)zD3V(<!LJfiYqet@ebyg0^`v@<kKG5N5v*gAV($1B5*2qg=t1(7@!_Q-EXaN;yn3W#ye|B$enF5~b|rOQ;OLs&DjMZ(j-#$q;lVJvNF;@HLebRgxr`cW1O!YRoWOa2Z?SGGvpF&BI<9%@;{n^7R2r&sdG5;AH6v4RU4AnBB>?Tp6}y5yp8i>!1fu-t`P{&BhaC>=k$^Yn+T{U?RXx#NQ;c=-^$wnrU)dl#`<)M0KJDOfxz#?WU^{V%20pH%eEMQ=x7dh=fW+LsL9ITmdx?l^gapgC$frE{h}i1f7clMrGcIQANys*$)K)UPOry2elA~h@;Iu&JRAq>{!y*{zu}Yr5XjgEgcfz&{i8Dfm|7Ah~!9Dp3<)fOJoJOFl8kv(3w*rVOc!`%<zypuskM`Kk^?$Baz*PibSvBKphT`46gt=MYvl|cO{3GAN3k1rxj;JRkLP5oZ6Q}EDdkzw4SXBEL?&CE$0ga*12%1GX?n#FxmsEFz*{YLKbNc4)jV7a<E|`f^4Zs0U57~W~k*?vQ!n)1ls3I9{9VDzUwPVuawmSh8~5L&p2<h`2vT&MAb#DjcJ9OXIW|Z0`n!zHdh=ZGL+V+1F8Wtm0UE(DXg1sTbgpB?NBvFSi_oGTxVdQ)a>BcEIIh%%P+qi9B32Cp#|~!i$8w(#i0NCkF^kAe*XH8U%mz`RV#KgfBfUW4qm@L{QS^C0`yMeRdG4!4`C2LJn+Z#h@K28xN%xmeu#`;0Ddz5uOy^U!?k9%*Y+HSm1C%Uc&yE5tsn-Mk__T8l<pJTOwR?8#@@Mr2nGW8_mSw>oNqLe{I&5zL|PTAc}bsDI3;K1lxGsK)>T1uc}Dy^X0!c$y(-N;*$wKDav~g7^^qqhI0o>=tS@PDr*oJ!s_`KT<01No!a;SJKvY;0sv<Lw!kf+fk(6XNO3r4=UALy+xjy~6I)&~@osyx0`>6O&75*8AMG@tt9#u@2^C*wU`lIr05shFPjLTxTKoKnAQezEQ^?jT`)9m7GZ&{$P3yubN=*7ZHtjDlrM9p0R==vnaNKBZV&;zUmr6(61wIUmpXGce?Fj+?6o;ri)e(LZ@ES)Vls6Gnp2x)BuO@c+>&<Os4Vcf(Rxz>3+YnIQ$8)y0ZYhltnyosKHO*WUd5vnnE8>q{=ErX6~G|NGaP8)PV0-s#$Ho*4B*1~7NXN^jQaT~|%&u%j0t-Y(_Rg`ZWg}^@oFJJD?F(s4Ka)qq*IR0-M(Oo(C)Dd_F<F{3%A3YM1@3OU>IsX(%|J2s8%oJ@K<#<nYWMemcrWRm2O^vO^-bTGO+Ek5gsWi^!^DHGEK^4KKid#G+>|q+)Zh}oI+rfxzVN#v+)|!Q1TC#T4&nFnldJX-hnb1_d3|V;MJh-byc#(KDgj9p)3N(}I5l)VT5BhzTM5A~*D(gDCO<8nlszs~=Z9~nRF&Y_@xmG}^1PdOqs(RX@>J#N~i0x=t4kJUa!Xl#BhIm|*VHuA{dg+k^yU|2)U^!0k0IQ9%>4}D=!_Y=<$5K1qyx1J+`T??**BuvSz&FEMXKmbeSSHD$%+I_$0d`2lM@JrRiS2#929b==peQ7}SY9RZn1@AqskP$g`|N6moi^AtU_zXSw-f_e>EQ}0(e^&qy%Fv)uAI$66^GIA3K9cK9#{o^N(;bZXQVnB6D-w-K{1%<qQ5XnHnv=isMm^pX8h*q2Q6z~RL=t85ZczSXM=U!(nC<&x@MZ6ojd0v0J|l+qElkxq0kqi5-4mOEe(krMRRL8OgyO?D+P>_@{(nXC=bgl-`@{RvSmJ%<T6qr`P<?&^&O#Vm)CKj_sMLe+YRivB}dyA7~SFPcAGV#cLW(^t3)0Z%LJ8CtBs%ied~eTv?ci3R-h-lw9@T1X~j1zrvV>9{y4ubEa3u~hlil#&S;$(qt$hp+i=XbQP6Ejfk!)=QPAE<K~3_AP7Y;{*fjbS^WIj>=0v{o5oy$wQo-6pOPsEPmZ6N*pu2j@TlY$$3q0pGyj#_(sx7ixZErMnbEUYW!n2R`-R`;E)*z%EJ@EoRzKjYf3M#9jeX37Q_*r|N8JQFnzqPT*9la!OI(?zgKW=H+REbWGRxPt>x$6Z?5~*%oHqc-m7%mZQWVm@4;SPp2afof`(W**1u^NwNy=j~Sy|m-tr2{|;Oe>t&ybvQg&Etq~$mznP%VBa2L$yJBbcso@h}#omkH*tT_i2rE8#U5?S|ja7jl6nVBd_Wj;X7BNk<-)1w33j;Lh;aTSA8olp3=$-yA||O^LPcG(UI$0NHE8D^<|6Jda+iHiApfh-7k80G6(<OTz8PtPtKTd(I<D{_xpYHEzY@Fv(7vB_~hgO1XpEG^TM<mt1O<dA}T4tB-Z!7H5(vS9hG`tl?DT3ZtvXVC_eupz+}bquL3Omk6s3BT?PCCi-662t6K%QivSBxlU2a)ivT6_zb^tTw*Ipg0aEF}U;4C^Y+ekI{D4WuLjve}aaw+N=6?&${8l&HTDNU+v;8ji?~e8Fj`gp|v35K`Fm49GMt@uRrpNqDi0eJO_)Y)g1c0CnCo`2N2`;j5pb11hw*%cLssx;Oy~aUbe7<z5R7F-D$5B7&9$?Jhzs0d}m&yp{ySo(ehTuNmwrGyNejm)}^``wQwZef~&LW2|RP6mp+M;pBdan-8i96(H7H+juTDSXC_1{ER%K)p*hWj{=+h{X()vCv<Xbif&Tk@jabJTx(5o8L$34)l*1zH(iEla30P3{6>4=08Lzht2_C*Hjwa|$$5K?wt`d4tv&w-i_<<yC^PSH$;`nkKR6+Q3#F$)+<M8VzI-#Z0PY<LYbCVmTj0mxui!KOVq;#*}p&QO<Om^?E%#5ePqHOuofO_<hL90r!Gh(5<O#(n`Ih2B9jn)**bVS;F`CU;zK^$1R@FTREdVS$lwPVlfRgZc#3<jUTi5k#DnB4}C2M9?$q8Iy_~Iz>)9-E9&(`WrW0BWjss@f4g1Vze4Jf^4OvpKZ0cgWT%ya9P4GVRT$xX?Nq>rv2!#?bv(^(O^>i9;d+3rdb6&z!KVR%fd-_OZwRflxp2foH^gbQySOHT@GtnX*Z9S36oH6nJgpx97>-YeEz~1?vbeT~xW1<a?`Z)&y@fxX#B%g@rqd!KBd4`NXJXB+`uMl-G7dlF>SB&j2;;gh8W|q@;c^QOzAU`#rW!gzsF>i%<jr6lAA)vm&<Ede@{vdF`d=$rQM6i~VSe}|W_5&$_}enAv1ME1O20JQs+-pMciXByzcJeyYcuOc>sn)6J=T?sDmxQq*5u$Lt!w-nHLuTUSREMrcrP2!HDsS9Js#WztIWT_%G`?!2Z2Luvfi;~zT+M3cazMkCs=mJjHA_FWyun=C|x6uCw|?B>g2E2Xm{wU4t#WF*>SL&FH$_#{$gI82!5yvdG2ML1}PmM1Lx$6z8&9A=?V{9i?L#H8!mXw<C;S4Y_d6Mo_?nVG=(>FnD*AE9jRA46y$pj`5p;}KQ(%k79`H^hZx-oxgEN?d_Sy{Gbi>381&!^wtO#5ig)I;dKdQch=%LFns#MCLoKjEQFhe?Sn}G(vwMeUyw5P-DI5DxhnXCb(5Bn&5VxB5a&EkD>64y!93=ulo1`ed=XE5bk4-<zyizBd=m8!*aaeALX^-6Hyspi$lgnMN%NM31^N^Ye@Di2TU+~-t&4Y2Zd7GHNdL|t+NAu9B14SLEo!VwP7Y_I=PJ@j@XY2*~aLgSXS2~U>8wbr{WAw>%R?o9l6olwn(YLFC<c>W&j(|3i!HTvqCvA)*>Qj($2gR6VQ*T+j&q1Sllq4P*sbEo7yc3}N*^K6sNLGESM74wS!(YC}`vTOdb?$Tz{yuoU3kn=;b$DK(_<R=>7|d0t>lKPGnxh!}fGCKVHX%H2UiU!OJ$Ovrfl+s`TV1Q=iulG@;sed2i=B-s4QYoOY8l&4janFNYvDj|Vep6+4jZ;GpcW3R7BrJ{V49p0taYY)GhWMtU;_`>p$m4Xz#Pk^+m9z&F#pA1de#GFoCM<o?*7CFn35q`1Onv%4g}yp0Fpc$cmNLt;GqCK<bZ<;5Y+MwqYK$!th;aMf`|^wgFFfoCXOneus1q9-h#D;p8ml94B#*D1HT^r04rm>rVibK!5iZa6<h@I9#Sa@u3kRP#>;|bDV5k2WsCnJn-pITfA|*`!2h6ecq7K&@q)Oz#@8MF31<?bgmDY{*aN8J1sMpK4nQE>>l(O24Xy)F2>ZnwAm}zOud^jNNiPhtf*dbuL!LpUpx?5w@{dC#3l8c)2L`C5mIZ^l3WuHwitxi$&0yU|Y<wM!Z$PNa>##I&2S6TE)#%&j%)0y#p$0yvLmTSQ2lZM(X}5jF)2X!-=JM9nPus}*n)GC_HF8M%O>J4ZVT7I1!|2;SxA7HB6Qju2?3bU@T`&frF#PZzpFTi*gqGs>L-qYZ*Y57A#75+N#y;0pOu}U{GxH2jsmUcC-pheKdt;k7!JwJ%V8sy4BQTf2G6l<v_Y<MlgAs^e5ti4$wfO>8GX)g3+*|JcXBD$=!z51VlDlu?Wf3hF5qsBT-<9w<Of$Of?(47&#ZKoEkP)!zLqRrs5*P0?iX25H<FqXD3|1lYLhfx&iY1MWp1=vucqU`2WisN!nBR0qCFr~_LZG@FW%-D&%)p{*_oC7|DavON)eAfFs!`3C*K%z_JfVv>pN{mb8y(^bA+BtQSfu47Q3yi-%f${|7AJmQSz^7$NakJ3O6HWMU9&@%>mjseKfD{Zv{(aJ>N~9s7XfIFgP<1vPLpFzh)v0+*f(Cc@k#kAQ!*r5k#QDNwQ&|DM9^-O(18P!3*nGko@ya(5#_=w+MFVnR+806P%0X?<w0?1Xtbm|SNeBc{GPE{o-G%Jk=1Dfi5`uvmeXK_+D3J_rWthkyt9!%SXH6qCQ}ZZ6-ujGx-@DG_2gE6Sk3J!&((Z1$-Fu)hT&V3!_r%$POaQcf_6u5cC)uw7T2SzaC~F1Mvui|tzMLeMHCqLsQ-C{F@jM%4Fup-G>g*!#!yyFCqZlD%KP%=(6e&q8*(cxVQJNi=8N)<5|%8CdRwj-J1MkAh7~ezBre)Se-iJ|N@0#W0t*i_G)`by8VO~RP+55$<+pJGP+UhGMIgC0^@pEQc;qcxTj%1&*Ob4D(%X1^Gb-~a@}064)8$kHGmb|5WNcg-2j%(Y7UmSI<8kL&qtu>sCou0*o~bZ2w22!|_=$-{hh3nD?YC<Sv}+67t}S$}7I~}-1Rpustl0MDg71~W#P*Xq6QFR>e8*mbm8{u7yTI)dqBY?&S6)YLg48Db0&w`23z8g3MtnJL>fo28)kLIqnf&RDx+T`cKPmDIx_%OyZ#JKDcII9HSRfOKRXMTBWKm8jr^uq*Z(4Y#WH*{>M^pDT&Onr-aPCthuNK+LaIRaKa~8C-MJqV(u=AE(5VcGr$Lqhd!RFy&5#u`KosHxjl#;0_==KkSc;`UG6KF>z>m}j+-KdCWN<($E(+f%Mj0cqh8jqC%8c%f*IzL0-7sHx<46Y$R=VqLg8snlX85cE=_n65Q)uxW223S+>06~?iU?MXKD>8AZh47r(3N*R5VBehu94<CzkBw97<dSIFXXIS0j9ql2B7yPPk=Q-=q#rC7phJ;o2G$K9tZby=JKx#xp`P+N$V(+M(<Bi60<ewX)#y}BE*F;HZlIxFo=9}aC($zlk?7Ppo5>#iGMy3j2m53Z2201u^B8XQ`4dVeS5AHu$fzWVquZIhdepRorZ{1v0W?efrQK3`JxwAQk=Tr=>g0BvT-3?!Iu8|X=d74x!bF5_Uop@5S7!nNHkpj9_(O+AIFf7;z!#YNFO&WKp@+y^LgyTMa@p<XLu%N9PVCbqoVm`C6I&o82^B^q7-0ftDK``8Czmkq8JY@KKDm>+`i@P1QC$^tPB87zlR5*}RCPU_luEL(uaD4_|9@ISQD2^%R--Ex3CKO%<Ny}t_}5Ab+N3!Z&qyCoGWn2z-gICbj=j*i4GqfUhxTd@XS}E2!O}eF(!f?c=-$A~lr4hTbl8Nz?l^FwR_)Mfv{wEh1*U>Fcyi~hGamj6*P}e1UGo_&@f}}M5HQ-8!+=lX>b_@OV8Fsw*E8E6{np!5hkeUt+ttn&6q^N+dsdp15En%9K(O`}3XdK(u}#j9;FMuc6O+suX(j#Djp$yXq^<Q?KxUgJj-lyXI`~dRklF>o52x6p5u5?1j9kk)03@aXE%HNb(4qZUscC)js(&7wr|uIO<HWV2F?=rg7Lp7y9@Go?&<u4Gp^A==C1t3IBE{(_iKeByGOdmQa)A7aYGgFDQHyG(tW8>!o39Dc55hlAhiVK|BTdTnGxGS+*7WqU82AQC)@u2Ud!=BLOYUlIRIt2>g4xbm#T}twxhIoXC#V5E@*^c$LDwsp!zuaMLCJ{n9Td$&R;5=wd?F?*N3Z&uLqHv|0#<8fbB)X<?$dW?utGl8oLRXx1%x-KXp_sEp`;tf>1K##g1%wDhw7>m?j<TmgAh0_qQGW2sW(GQmu{3mCHEX&3zc9UdhEKWBxsWGN^2EKM6_Ak1Ax79fg~mIq)J<R?f_P~TqIHRAh7cqwx%y%GcE!^b70&&Q~zqV*mD5czJz2h4Wp4%N>>W-?Mn;Zv!PF~W)oN%yqitj@Q|C^m3LLiomsN&-E3OwQ@U#OCQ{%1J(Q_*&wTe2Xs@0VHSgV92?R;^Dw~SG!zak2Io)p1+S~T>t1%$noZ6T-%aGiR#O6XS;(geexqA#sW>Ds4k?|%i{<^Om-)=PTQ?d4nKlw_lesz?jVS24TO6LBWhW@}9G9{Bae<KW56R*>n8!<rjI;OevzL;u9JqNmTdycD$=k%s7@2;Fc{~0yyc`*-pAfg;+j!Jbu^!fYBtN|_Kbm={ngl`lrisd{yLKdF^LJ+F)ToOk|s_-?S;aWa2-tR?yocA#eCqLjdx@Yix0N-ihTcOfAiu-T_q#g$~@4L^D;kl7ZMp*k`tJiI4t`=t9UiRBFyfSKe0A45BpB(4v9O?vAgzxO?Ff7Hd2lks=*G83BY=%jA=?dzKjH;!@ftV)*n-Jm!uJjhwrPf9zc(V?@-Pe$cGL8az-tyWJB`+RyOXNlXJOPSLMt>BY!Iz1lOzqPkoft!7$X(U@&(LGG<Vr`qq_?$k1;ekrdHNq8^{Yqz)~rjv46c91u>%M3o7wKiT)glNTUeWKi(|ZtSOOwIF122Ms+9}cy3*(<5Ff2My>ks;&1${!t$m90N%5&;YA#;g#?j3Cp4sRFSEUDQQko_i?l0qppgzHC(~|zf|Gq=5Jk@sp`0EbOPOaPNQrh(k#M>*|V8Yu7hp#!VUS~#-+8ep6SAbpBVI(|Pgr~xBW#F)=y&HkuLD2|_jD76UE9~%E7I26*<?rfmaTGQ6C7L>Jq<1jjnD(JB;&oslcA2Uh(A6+dSqC`{galZR<M<4#;y=cOPOa{qxA)9fRaD#lMT|Lpqkk-;rQG(nj(se`yCe%I)f5h%cqKFBc+311v7h)s)=`NqsahqdG$rS5EA$FvJ>eVR3C~PjjzzHpkrQH9CYnxtIF6ka0<U`Ul9f8CRbou3>Hy3%&*;jnswED82`vr{+~Xt)b0hCbq824u$Y1B6P9ChXh^DOA-#@NdVZ=|o0VTn6?8fCMH2BTe9kwvN4HrtB=F`zE4;R<Y{<JJ`Q$kdUoenb7b3rJpZ88}}6OnZZ12gCAnlkGk4Qw3NZY&}&E_CSchJ-=z+3{7n*(MllMsxgdVI_Q87&g<Z6=SW*)(1s)FuTO>Ls{cNt0Rl5derX^*i&A$%!btwB%sKwjiq+o+J@24;au)U8%#4SMi`M<XTdq@GOG}X;pm{56erQ8uR!%@QCW>-Y@aRP$WMJJVjL|x2&V(!%4>vq12a@o%&()>)lmN8E2^PgBj;5{Q4iRMfAVNGba+C%)X{br)u2DnWtchuQ;#|?zC7r9t{Ydxbw(J?e95gmaFOUaZ}@3;T9EgPa_K5@sm7+|U5nIShsmwrb(qc~ZE(46rqS()cp`tGU_A4<>roBS0>Y{9;<>56IQB1h7nhe?<wb~tY7^8<QlbInI+Ug?Tvw1;_>kX`AgrAyL{2aTy_1|oL%dC9#7+GP8fbha(Av6Q){DNQ9`ovTCbgjVPHi-%{I%o)!YjNY8+a8ZJP|mCsV%UR;N@Ce^Hg}ne=POQVAA5NDbB2zV(MLnPvayBsJ$w2mH*^<tC;0)ZGT|tWid2!<nRNnyED5iAV;IH3PdpL1p){^#=FZ4!+=+pBA9SL+!!@Ag6@J_M7qx}$b`vscDWkX1<TPh76OPbA^-SMbeBXL-S&RV6D)Aq!{JZGuhkGksP&P2gvJKTYUAGrs@RC|o^G1Kb?sgO%dk(BNYKwBN~T=YS6tMW3tu#aZiFn<Vqv*33BZbYG{un$eq;dHK)26IhL|wYIKL$8j53cPWYGBhyc$;CYt6MKWMN-2Zi7}sBN(OkL(+0`YK#>O^^AYL<c3R0!KM+%UQcQ+DM7vloVk2HRCi%4(e?qeI-Vw5o`I!9T1fClT12n;oO{Y9J_x6ST`wRGq#p$>)gxM3pqOlYwKK;g=f-1Q9u2>U<|1FlEuW-nOfP=GxY_!yhWHXMnmMIYN**dJ<A>5#**^LuOkdw`t+rC7`URZ=T?^oUnu)3!F#I&#`}zA~>LnRJ)HW`*>v-;XCC(J8&o;P#JfnT!@se)?8&|cupsTn54o!BPktCpZ9%wKJ&>DM_{jah8f?A#iX1*ewm}yN53-7d0O$ji0zmO<Nk?Lj<1IXL7!;xK0x;@OINo}MzB*fFQW#n16pp^pC;4E9zf`!+&jsVe?ODt|KIy<8Xg&$IUr>5~_RPzHNO?M1G#ag~2vf1BeMOm%u$F&Rlaka9SEBf&>F6lc&2uuV;tt<M})%~wz4d0<oK7Az*UaXDiQ!MD|u^gJ;-WuO9MY}Edc@c1>+F$+W#Q*}GPrHTz_}NJ<0?;@BP<4##<6Eh?XP<Hb+pN7!D_VIbDajU5VEZkt9%-H1q%$2<&7TQeTRN;axO0zpZ2nWN=q-o>cb-dgvvC#XahR3`3*J)J&zj8mkq*)gQgB+|BKpZPq@}j}8dqQG8bxzsIGQZS(S)oI3-Crz`nJ#E$#a_HjS=D}`7gMlC7lS9gmliUO<atyUVtf8xS2hP3+tS(d-ik1Ll}#w9#DCeCJ0}qLVI98rdz`oNK56x)31$(ZoT4#T{Pv(ZD_Hont|_i5fZIJq*aI-Q~*v?HSmY1LRZi_wP?2b(YN}*fxn6FJnIYcCEVx68y!x9A2IRN+ED_03~Xu-@!F25r$69-qQ`b8Rs%m;YXSV=P}N3~$SwX6ch!pr|3Yk+uu+MtgPyPF8{$S3_J|9L7uB!3IYh0SuVN=<?Wzuxmsmkqit8*dBhW6eR;!j&-$H5bYPhLBDRh9^Y?y-(=6RkkxQbev>Yw1YFPa~B>FJp{8wY3bBUV})!ZSM0RaE8$c@W#eZkY7Ytt^{l+iLi6LzhHF;t)W+1r|%=yU#H5CiT}*P99TMRyV6v<Mmx6eskz<HF%CwZ-2CEr>fe%=5YExi<PRf+5i<PsJI?V)69w%9^kUIRDQN44qF%PVgLjMp!6=UrF&#v$<5KYi+gDSKwMYi@aoDhpsLx;x{jK{hnAhHZ(;yT8hAb?zKZgrR}6G*FFo3hT-Z0k{6@j6)m4*S=5L9JHnDF;WKrVaB?Hv0(>T@hQ^hkS{td#2riImJ9e)^6*Hf5B7O=J%iJx8LeyeRRq`jHwY!QCI#@*#=(}*ESpY(TdGV@FnwBTf?ZWPfUN+-E5QSQMBEsp6Y7y|#+$5@^S$LRDJ!_ou_i^mB6^voSXcX%GvDBm>{OIE!(SM4Ghs~*>cy|sw;z5`{_N<x9h<-0<MEdGfItA&HR((stI?XWn1jj|FgkZix<;v$nRM*14cPh(U0!jCT1<~*={f$EJB>Y<R`gM^C3ZV=>`4jgU^Coao40f)75tgu;T**7X=I4*KeLK&@<iZaYgx9?ClN@B@JsL$hvzB`{ShJJH)_L2utDtms!o1rT|@%03RIv^kwFsp{zjE-|u&JqmJ;mVS7_3`YB|I#S$@mBvGO&n!RSI&s<*1akfT7LIwwnXN$Q=Nwm=_dwU3JkIz&<A?aMeV!AQSzLN{QlNs7h(QBO!<9%(W1QWz9Y7rM`1p`rYrltk5l-;zNN77SL*&gd7Viy9@m7FRf!cpHX_Hcq8+WGyo|>@a;6<UWY+yb{s=SH;nLuQc0Yi7_fWmU6T0~CD*G?aSq3KX5BM(-+QENVJZV`0DH2Qf$}sF&JTXIkG-{X=4HC~oc@%fxV`xUHQ<x01e8MMqep?vu!E^&0Z4;X%m<fE#V-$dbn&_flAUQ@jLcpu!O;4<%c1xYo{fY0U>_OAqi-e~67ts~_kgIIG8k3bZ0~qQx>v6S_`{(L6>F4H`eqa^?RN!h6553D}ob8ZgS}E}DRsV8D+y3@$Z5d2Z&If-&BZE!&w!}bfi>Rj2dW3@J9roB{ZzWDSR2vR{qJLVOS^@*K#3h&*PoEbcKWfZtyao9|f|l6bQBBGSh%yIIs!_irU1AqkwLuDZ8K-dCBI`{(+2Nu-DPyq`F}02E55Oy1|B|io?e-JL)US0O;EaM<=^I?74+@y<f!eLu=$<Hx=2|nrfl?`rooU2$y9LF39@=2PXvQi6Rn6YtpcVxq#5C3tl`hxD9Np;VN=4F^eUwVZe1po7>6beSik^P4qeQKG+wfvXeqf#|Z*z({v+A}7rJ>xuLoOUxn#%l6>{GMZH*at6;A)_kA&Jql(>=b3g7REdSnFz-)3|n?t7keg{*4!Fhr7WBw=ZL*rwEiAysh08T|2J9k<#;Hzc9%}8O4A3?D<n6cFS|XTm6g+{?xU8)ybHeoA&fe_T2mRoU8R3-m3Ti=R&>T_&s^QiYxD`tLiXb3G{us8|${+=GO2ku3!75Zx&~ta_5_Ko6Yq3u7#R5xX<QY&9zXCZe#Q9+)tn3TBzs0;c5D8H#{}E#Hm4Z^7H#8PL9|==@O@1gx<QuX@ksfzQoBZ^E+MQ^iR8qY5Ht8F*UwysX>$S^ZR8>^_MMGPRgThReEk0StJ4JkHFWB(^+#r+P?|l2Kd8K8pbQ1I~&tQ|0-gkEr$Xt%h7{1NcFNfE5o1&s}v&mZXIUex2t5Bp5}$a7-pRt<+;n(+KAWYpHx^I=G-h#?}Y`EOq+xtjS3k(JfUYBtThRwf1^Ro52v`lz=hSkZJ-F9*D1>JnPj-8NoSv6h&n7!Z_vkwCFXpw^Oz}r`-c15H~c!E8@yU$;DnmS^M!~-W0f@@$2;!@Iq40)wg#0QzTH&=Aqq~!bISyySYSL2Z-pRI*uU`__<P8XjLmgb1Mi=@vufPc)sS?okp?Y|O^YXP6J%h6X2F2%mqmElA6nUFo~2C9&Xm9q69)N%_NFj}B7o)s^#tj_xE6Ht0D7k%B(h$mLiZd2Hj)ryzBdIHOy2od-S1#&p3o*zw~XfzE0)t~yk=pZhj)BW5Etrkmbx2M-}cy_=|ZgY9{V3WlH8#!ssHY=KlRw#Yq4>4ahtJk0OvTy7k+$YzG6yjUtM6!=e*^wsO7hM%axykY`yr?-@ZBj(_g;-di3Y7zWc9lkjZ^6kyXjpfBEUn_uu{bTPS?pKlAElT-0kNN4H!oqP&5E^1IRuuSS1gb!y)8_MvZ=4Qzv0fKZXqI&gLdw3~qrG|BbuU`W^l^LDBSO(NvGvMrwalBwlvQy3!UB9N^2<4_i{Fqec|=OH7zHz`!1p>24(%s@mt`cAYXDR}CAP>5{+{xa<YQmRD$0OjHUCsn!LW0%t9e3S$vEMgZNpA^~?52dv?sF62Hlsfy^i1o5?UZmt3dZLM7YxdA<-*<e<#onQdw=Q<k3A=qY8}>)2i~!*L6cq~XjotKzZ(^jFQYt2wI(<y$?ioVLZT6dKBN^HmE_@-DJv0h%oGtDGqE<spKLu{6Ela#xBolnm$K2T~;>T^#g{Vsf1nZ8kk18%FLy<1v<O#S`CMK21W-3(^DW79_GxTF~<gsQ;O(bX0yyPyaRupoi6OJIxD{9iW#!*zQbgEV+RVEXjhaHaPIH<K8J9T$kZ@XQ+zoa7#d+f`4BAEt>8_i+XPx-y7N&(~nr@qGm)p{n%0&)6yk6d#k+7z!sud^^dQaL1iQQLOjcep<Tfg3mMRGtf3pa7Ltu$L}^tUI*KO+MzQPDZLP1f-rh-7>ni!u^WSXCNd;SL8qA9<_$kpR3`2iyqOKM`M_TbP~vChNs;689plkUrGY1X3@KC;NJSTXKBrc8dIT@zHDwi_N)g$cSjUdlvE|8D|AQ^=j(YzFE7EFJN4tqbv$`3p1cl^dS|BhNCq9}CThFTUl=;xWY_<G34z9!ZeEv$qAh``olRGbn5*FWkWx)b2GQYtS{r4}eFZKKwbD=V2!=`K2A(*aeu2QPN|2p(e4QxAT$EKsU5m`+E};mmJ2+^`aAG;i9gpLC7Et|8)slWQPxI5F2I&BdUpQsh6`u_drmU*CVf9y^Bj9mxabY&1CE-qMCOuLt8Da1My(Pm}(rZl6vQO-~50&qTLuA||jB7feLkBlI?Y*LLx87bnHfj@3)@sp00UCIqT@nI6?64XJBI<xVF*RSvOU0_(ZVoDHc+z8ypRjSILI=k&O=hhE7o^nmU<jHGc#Y(sfh^+Li5~fM26WIt$W~2|t!A`%%=NJWwt;_nS<4FS7NrPkYn&}z8hrkFONL?0u*yY`{byK&aR&n|-$zjg!zo|o@qC$w6l;O+H{or_qb>j0V}A|v8w$1XXiAr&Dc@)5EGo+G+iX71((YgL2!ku|Yq7+4uV+Y=5pv<L0ROHm5YtzSMG}t*uJCA$I}XWsu~}s{UV~n1RKf<sCu~Ma4tU*==IPCjV~W8<6`YGVMgXAm;^y8;p{^gJPS^Z>px62yj*P1EkcIcUCdB=oFHHobncq$X90SNckR`(CvHWq&uKnqf#U)jc8cpAwRL*Mh0Ve3J13A|oRRAczB6|f$X|eBk!VV(x$u+#99(B72YgGH|9{YA#Oyek-kiu%wP*BKo>Miv3B9HJUFVx5L=pRe0UK|PC1<(B)L#eoBluq{OPJgA-VZz?TS(44}8clWgBekpbgqdzb_|t7svHc!noHZ-c4oP#prr@n^xNmW9EFADjfFgT;`JPT4$LQbp>5PiV+*YMsyfgEj=B)SnKECj@W3{P3)7y;}ExZ98xY4IH?0(fM>D4{0M&H|ZLv%ScJd=CBI@Ao!uWDM;X)Fe<##e4X?M>YH>kUkT#bOmE;Qsso6Cg@B*BA59%vZ*gsI-l`e*v>2zIwa7jzHm-<ux8Qc?)!fFfsnP48h2PqE6TwSo=jGZGXJW^7#_lk}0p{Z3f<W>0~d8=hZdLbbv)mV3YtVfl*xDGz!z=Hp=Nc*1)}LUji(s^s-QQztZYd91eLee%8KrOI`I-djZLNgm`a506A4^E7FC69!!OXVbmKRq9Oz{wMVt7z5><jE2Kt!?P_x1S_}p>yh<WpMm$f5@2RAC=fu^HM+Rb^FTm$s`9tg()Snv{!^oAVLUCeZ@J*u5p=8(N;5#5fQ1mld{83Gku=m~N9F?pnL7jYJ__igL`2PT#v*N@")))
    open('solve.pyx', 'w').write(code)
    os.system('cythonize -i -3 -b solve.pyx')
import solve

Submission status: Accepted

Solution code:
import sys
sys.setrecursionlimit(10000000)
N, M = map(int, input().split())
ki = [[] for _ in range(N)]
for _ in range(M):
    a, b = map(int, input().split())
    ki[a-1].append(b-1)
    ki[b-1].append(a-1)
tf = [False for _ in range(N)]

# DFS
def dfs(v):
    global eda
    tf[v] = True
    eda += 1
    for nv in set(ki[v]):
        if not tf[nv]:
            dfs(nv)

ans = 0
for i in range(N):
    if not tf[i]:
        eda = 0
        dfs(i)
        ans = max(ans, eda)
print(ans)

Submission status: Accepted

Solution code:
class UnionFind:
    def __init__(self, n):
        self.par = [i for i in range(n+1)]
        self.rank = [0] * (n+1)
        self.size = [1] * (n+1)
    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 same_check(self, x, y):
        return self.find(x) == self.find(y)
    def union(self, x, y):
        x = self.find(x)
        y = self.find(y)
        if x == y:
            return
        if self.rank[x] < self.rank[y]:
            self.par[x] = y
            self.size[y] += self.size[x]
        else:
            self.par[y] = x
            self.size[x] += self.size[y]
            if self.rank[x] == self.rank[y]:
                self.rank[x] += 1

n, m = map(int, input().split())
uf = UnionFind(n)

for i in range(m):
    a, b = map(int, input().split())
    uf.union(a, b)

max = 1
for size in uf.size:
    if size > max:
        max = size

print(max)