import sys

input = sys.stdin.readline

sys.setrecursionlimit(10 ** 7)



import numpy as np



N = int(eval(input()))

S = np.array([ord(x) for x in input().rstrip()],dtype=np.int64)



MOD = 10**9 + 7

base = 1234



def cumprod(arr):

    L = len(arr); Lsq = int(L**.5+1)

    arr = np.resize(arr,Lsq**2).reshape(Lsq,Lsq)

    for n in range(1,Lsq):

        arr[:,n] *= arr[:,n-1]; arr[:,n] %= MOD

    for n in range(1,Lsq):

        arr[n] *= arr[n-1,-1]; arr[n] %= MOD

    return arr.ravel()[:L]



x = np.full(N,base,np.int64); x[0] = 1

power = cumprod(x)

x = np.full(N,pow(base,MOD-2,MOD),np.int64); x[0] = 1

power_inv = cumprod(x)



# rolling hash

H = S * power % MOD

Hcum = H.cumsum() % MOD



def test(n):

    # 長さnの文字列で2回現れるものが存在する

    x = (Hcum[n-1:N] - Hcum[:N-n+1] + H[:N-n+1]) % MOD

    x *= power_inv[:N-n+1]

    x %= MOD

    for i,a in np.ndenumerate(x):

        if (x[i[0]+n:] == a).any():

            return True

    return False



left = 0 # 存在

right = N+1 # 非存在

while left + 1 < right:

    mid = (left + right)//2

    if test(mid):

        left = mid

    else:

        right = mid



answer = left

print(answer)
import sys

input = sys.stdin.readline

sys.setrecursionlimit(10 ** 7)



import numpy as np



N = int(eval(input()))

S = np.array([ord(x) for x in input().rstrip()],dtype=np.int64)



MOD = 10**9 + 7

base = 1234



def cumprod(arr):

    L = len(arr); Lsq = int(L**.5+1)

    arr = np.resize(arr,Lsq**2).reshape(Lsq,Lsq)

    for n in range(1,Lsq):

        arr[:,n] *= arr[:,n-1]; arr[:,n] %= MOD

    for n in range(1,Lsq):

        arr[n] *= arr[n-1,-1]; arr[n] %= MOD

    return arr.ravel()[:L]



x = np.full(N,base,np.int64); x[0] = 1

power = cumprod(x)

x = np.full(N,pow(base,MOD-2,MOD),np.int64); x[0] = 1

power_inv = cumprod(x)



# rolling hash

H = S * power % MOD

Hcum = H.cumsum() % MOD



def test(n):

    # 長さnの文字列で2回現れるものが存在する

    x = (Hcum[n-1:N] - Hcum[:N-n+1] + H[:N-n+1]) % MOD

    x *= power_inv[:N-n+1]

    x %= MOD

    # 距離n以上離れたところで連番が存在しないといけない

    ind = np.lexsort((np.arange(N-n+1),x))

    x = x[ind]

    is_left_end = np.zeros(N-n+1,np.bool)

    is_left_end[1:] = (x[1:] != x[:-1])

    is_left_end[0] = 1

    is_right_end = np.zeros(N-n+1,np.bool)

    is_right_end[:-1] = (x[:-1] != x[1:])

    is_right_end[-1] = 1

    gap = ind[is_right_end] - ind[is_left_end]

    return gap.max() >= n



left = 0 # 存在

right = N+1 # 非存在

while left + 1 < right:

    mid = (left + right)//2

    if test(mid):

        left = mid

    else:

        right = mid



answer = left

print(answer)

import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)
import numpy as np

N = int(eval(input()))
S = np.array([ord(x) for x in input().rstrip()], dtype=np.int64)
MOD = 10**9 + 7
base = 1234


def cumprod(arr):
    L = len(arr)
    Lsq = int(L**0.5 + 1)
    arr = np.resize(arr, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        arr[:, n] *= arr[:, n - 1]
        arr[:, n] %= MOD
    for n in range(1, Lsq):
        arr[n] *= arr[n - 1, -1]
        arr[n] %= MOD
    return arr.ravel()[:L]


x = np.full(N, base, np.int64)
x[0] = 1
power = cumprod(x)
x = np.full(N, pow(base, MOD - 2, MOD), np.int64)
x[0] = 1
power_inv = cumprod(x)
# rolling hash
H = S * power % MOD
Hcum = H.cumsum() % MOD


def test(n):
    # 長さnの文字列で2回現れるものが存在する
    x = (Hcum[n - 1 : N] - Hcum[: N - n + 1] + H[: N - n + 1]) % MOD
    x *= power_inv[: N - n + 1]
    x %= MOD
    for i, a in np.ndenumerate(x):
        if (x[i[0] + n :] == a).any():
            return True
    return False


left = 0  # 存在
right = N + 1  # 非存在
while left + 1 < right:
    mid = (left + right) // 2
    if test(mid):
        left = mid
    else:
        right = mid
answer = left
print(answer)

import sys

input = sys.stdin.readline
sys.setrecursionlimit(10**7)
import numpy as np

N = int(eval(input()))
S = np.array([ord(x) for x in input().rstrip()], dtype=np.int64)
MOD = 10**9 + 7
base = 1234


def cumprod(arr):
    L = len(arr)
    Lsq = int(L**0.5 + 1)
    arr = np.resize(arr, Lsq**2).reshape(Lsq, Lsq)
    for n in range(1, Lsq):
        arr[:, n] *= arr[:, n - 1]
        arr[:, n] %= MOD
    for n in range(1, Lsq):
        arr[n] *= arr[n - 1, -1]
        arr[n] %= MOD
    return arr.ravel()[:L]


x = np.full(N, base, np.int64)
x[0] = 1
power = cumprod(x)
x = np.full(N, pow(base, MOD - 2, MOD), np.int64)
x[0] = 1
power_inv = cumprod(x)
# rolling hash
H = S * power % MOD
Hcum = H.cumsum() % MOD


def test(n):
    # 長さnの文字列で2回現れるものが存在する
    x = (Hcum[n - 1 : N] - Hcum[: N - n + 1] + H[: N - n + 1]) % MOD
    x *= power_inv[: N - n + 1]
    x %= MOD
    # 距離n以上離れたところで連番が存在しないといけない
    ind = np.lexsort((np.arange(N - n + 1), x))
    x = x[ind]
    is_left_end = np.zeros(N - n + 1, np.bool)
    is_left_end[1:] = x[1:] != x[:-1]
    is_left_end[0] = 1
    is_right_end = np.zeros(N - n + 1, np.bool)
    is_right_end[:-1] = x[:-1] != x[1:]
    is_right_end[-1] = 1
    gap = ind[is_right_end] - ind[is_left_end]
    return gap.max() >= n


left = 0  # 存在
right = N + 1  # 非存在
while left + 1 < right:
    mid = (left + right) // 2
    if test(mid):
        left = mid
    else:
        right = mid
answer = left
print(answer)

-    for i, a in np.ndenumerate(x): -        if (x[i[0] + n :] == a).any(): -            return True -    return False +    # 距離n以上離れたところで連番が存在しないといけない +    ind = np.lexsort((np.arange(N - n + 1), x)) +    x = x[ind] +    is_left_end = np.zeros(N - n + 1, np.bool) +    is_left_end[1:] = x[1:] != x[:-1] +    is_left_end[0] = 1 +    is_right_end = np.zeros(N - n + 1, np.bool) +    is_right_end[:-1] = x[:-1] != x[1:] +    is_right_end[-1] = 1 +    gap = ind[is_right_end] - ind[is_left_end] +    return gap.max() >= n