import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)


def Z_algo(S):
    n = len(S)
    LCP = [0] * n
    c = 0  # 最も末尾側までLCPを求めたインデックス
    for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
    LCP[0] = n
    return LCP


n = int(readline())
s = read().rstrip().decode()
ans = 0
for i in range(n):
    for j, m in enumerate(Z_algo(s[i:])):
        ans = max(ans, min(j, m))
print(ans) import sys sys read = sys.stdin.buffer.read read sys.stdin.buffer.read sys.stdin.buffer sys.stdin sys stdin buffer read readline = sys.stdin.buffer.readline readline sys.stdin.buffer.readline sys.stdin.buffer sys.stdin sys stdin buffer readline readlines = sys.stdin.buffer.readlines readlines sys.stdin.buffer.readlines sys.stdin.buffer sys.stdin sys stdin buffer readlines sys.setrecursionlimit(10 ** 7) sys.setrecursionlimit sys setrecursionlimit 10 ** 7 10 7 def Z_algo(S):
    n = len(S)
    LCP = [0] * n
    c = 0  # 最も末尾側までLCPを求めたインデックス
    for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
    LCP[0] = n
    return LCP Z_algo n = len(S) n len(S) len S LCP = [0] * n LCP [0] * n [0] 0 n c = 0 c 0 for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
     i range(1, n) range 1 n if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
     i + LCP[i - c] < c + LCP[c] i + LCP[i - c] i LCP[i - c] LCP i - c i c c + LCP[c] c LCP[c] LCP c LCP[i] = LCP[i - c] LCP[i] LCP i LCP[i - c] LCP i - c i c j = max(0, c + LCP[c] - i) j max(0, c + LCP[c] - i) max 0 c + LCP[c] - i c + LCP[c] c LCP[c] LCP c i while i + j < n and S[j] == S[i + j]:
                j += 1
             i + j < n and S[j] == S[i + j] i + j < n i + j i j n S[j] == S[i + j] S[j] S j S[i + j] S i + j i j j += 1 j 1 LCP[i] = j LCP[i] LCP i j c = i c i LCP[0] = n LCP[0] LCP 0 n return LCP LCP S S n = int(readline()) n int(readline()) int readline() readline s = read().rstrip().decode() s read().rstrip().decode() ().rstrip().decode ().rstrip() ().rstrip () read rstrip decode ans = 0 ans 0 for i in range(n):
    for j, m in enumerate(Z_algo(s[i:])):
        ans = max(ans, min(j, m)) i range(n) range n for j, m in enumerate(Z_algo(s[i:])):
        ans = max(ans, min(j, m)) j m enumerate(Z_algo(s[i:])) enumerate Z_algo(s[i:]) Z_algo s[i:] s i: i ans = max(ans, min(j, m)) ans max(ans, min(j, m)) max ans min(j, m) min j m print(ans) print ans n = int(readline()) int(readline()) n ans = 0 0 ans read = sys.stdin.buffer.read sys.stdin.buffer.read read readlines = sys.stdin.buffer.readlines sys.stdin.buffer.readlines readlines s = read().rstrip().decode() read().rstrip().decode() s ans = max(ans, min(j, m)) max(ans, min(j, m)) ans def Z_algo(S):
    n = len(S)
    LCP = [0] * n
    c = 0  # 最も末尾側までLCPを求めたインデックス
    for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
    LCP[0] = n
    return LCP def Z_algo(S):
    n = len(S)
    LCP = [0] * n
    c = 0  # 最も末尾側までLCPを求めたインデックス
    for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
    LCP[0] = n
    return LCP Z_algo readline = sys.stdin.buffer.readline sys.stdin.buffer.readline readline
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
sys.setrecursionlimit(10 ** 7)


def Z_algo(S):
    n = len(S)
    LCP = [0] * n
    c = 0  # 最も末尾側までLCPを求めたインデックス
    for i in range(1, n):
        # i番目からのLCPが以前計算したcからのLCPに含まれている場合
        if i + LCP[i - c] < c + LCP[c]:
            LCP[i] = LCP[i - c]
        else:
            j = max(0, c + LCP[c] - i)
            while i + j < n and S[j] == S[i + j]:
                j += 1
            LCP[i] = j
            c = i
    LCP[0] = n
    return LCP


n = int(readline())
s = read().rstrip().decode()
ans = 0
for i in range(n):
    for j, m in enumerate(Z_algo(s[i:])):
        ans = max(ans, min(j, m))
print(ans)
