def z_algo(s):
    """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """
    n = len(s)
    ret = [0] * n

    ref_frm, ref_tail = -1, -1  # 一番末尾まで探索したケースの起点と終点
    for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
    ret[0] = n
    return ret


def main():
    N = int(input())
    S = input()

    ret = 0
    t = ''
    for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
    print(ret)


if __name__ == '__main__':
    main() def z_algo(s):
    """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """
    n = len(s)
    ret = [0] * n

    ref_frm, ref_tail = -1, -1  # 一番末尾まで探索したケースの起点と終点
    for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
    ret[0] = n
    return ret z_algo """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """ n = len(s) n len(s) len s ret = [0] * n ret [0] * n [0] 0 n ref_frm, ref_tail = -1, -1 ref_frm -1 ref_tail -1 for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
     frm range(1, n) range 1 n cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0 cont max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0 ~ref_frm ref_frm max(0, min(ret[frm - ref_frm], ref_tail - frm)) max 0 min(ret[frm - ref_frm], ref_tail - frm) min ret[frm - ref_frm] ret frm - ref_frm frm ref_frm ref_tail - frm ref_tail frm 0 while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
         (frm + cont < n) and (s[cont] == s[frm + cont]) frm + cont < n frm + cont frm cont n s[cont] == s[frm + cont] s[cont] s cont s[frm + cont] s frm + cont frm cont ret[frm] = cont ret[frm] ret frm cont if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
     ref_tail < frm + cont ref_tail frm + cont frm cont ref_tail = frm + cont ref_tail frm + cont frm cont ref_frm = frm ref_frm frm ret[0] = n ret[0] ret 0 n return ret ret s s def main():
    N = int(input())
    S = input()

    ret = 0
    t = ''
    for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
    print(ret) main N = int(input()) N int(input()) int input() input S = input() S input() input ret = 0 ret 0 t = '' t '' for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
     c reversed(S) reversed S t = c + t t c + t c t lcp = z_algo(t) lcp z_algo(t) z_algo t for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
     diff len_ enumerate(lcp) enumerate lcp ret = max(ret, min(diff, len_)) ret max(ret, min(diff, len_)) max ret min(diff, len_) min diff len_ print(ret) print ret if __name__ == '__main__':
    main() __name__ == '__main__' __name__ '__main__' main() main def z_algo(s):
    """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """
    n = len(s)
    ret = [0] * n

    ref_frm, ref_tail = -1, -1  # 一番末尾まで探索したケースの起点と終点
    for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
    ret[0] = n
    return ret def z_algo(s):
    """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """
    n = len(s)
    ret = [0] * n

    ref_frm, ref_tail = -1, -1  # 一番末尾まで探索したケースの起点と終点
    for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
    ret[0] = n
    return ret z_algo def main():
    N = int(input())
    S = input()

    ret = 0
    t = ''
    for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
    print(ret) def main():
    N = int(input())
    S = input()

    ret = 0
    t = ''
    for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
    print(ret) main
def z_algo(s):
    """https://www.youtube.com/watch?v=f6ct5PQHqM0
    """
    n = len(s)
    ret = [0] * n

    ref_frm, ref_tail = -1, -1  # 一番末尾まで探索したケースの起点と終点
    for frm in range(1, n):
        cont = max(0, min(ret[frm - ref_frm], ref_tail - frm)) if ~ref_frm else 0

        while (frm + cont < n) and (s[cont] == s[frm + cont]): cont += 1
        ret[frm] = cont
        if ref_tail < frm + cont:
            ref_tail = frm + cont
            ref_frm = frm
    ret[0] = n
    return ret


def main():
    N = int(input())
    S = input()

    ret = 0
    t = ''
    for c in reversed(S):
        # zalgoは[0,i]の比較で
        # 先頭が固定されているので
        # 末尾から文字を増やしていくことで
        # 先頭をSの各文字にしている
        t = c + t
        lcp = z_algo(t)
        for diff, len_ in enumerate(lcp):
            ret = max(ret, min(diff, len_))
    print(ret)


if __name__ == '__main__':
    main()
