import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():
    
    # https://qiita.com/drken/items/dc53c683d6de8aeacf5a#dp-%E5%AE%9F%E8%A3%85%E3%81%AE%E9%A0%86%E5%BA%8F
    
    
    INF = 10**10  # INF+INFを計算してもオーバーフローしない範囲で大きく
    
    N = int(input())
    S=input()
    # dpテーブル dp[i][j]:= ...
    dp = [[0]*N for _ in range(N)]
    
    # 初期条件
    dp[0][0] = 0
    for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
    for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
    ans=0
    for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
    print(ans)

    
    
resolve() import sys sys sys.setrecursionlimit(10 ** 5 + 10) sys.setrecursionlimit sys setrecursionlimit 10 ** 5 + 10 10 ** 5 10 5 10 def input(): return sys.stdin.readline().strip() input def resolve():
    
    # https://qiita.com/drken/items/dc53c683d6de8aeacf5a#dp-%E5%AE%9F%E8%A3%85%E3%81%AE%E9%A0%86%E5%BA%8F
    
    
    INF = 10**10  # INF+INFを計算してもオーバーフローしない範囲で大きく
    
    N = int(input())
    S=input()
    # dpテーブル dp[i][j]:= ...
    dp = [[0]*N for _ in range(N)]
    
    # 初期条件
    dp[0][0] = 0
    for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
    for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
    ans=0
    for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
    print(ans)

    
     resolve INF = 10**10 INF 10**10 10 10 N = int(input()) N int(input()) int input() input S=input() S input() input [0]*N for _ in range(N) for _ in range(N) _ range(N) range N for _ in range(N) [0]*N [0] 0 N dp = [[0]*N for _ in range(N)] dp [[0]*N for _ in range(N)] dp[0][0] = 0 dp[0][0] [0] dp 0 0 0 for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
     i range(N-1) range N-1 N 1 if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
     S[i]==S[N-1] S[i] S i S[N-1] S N-1 N 1 dp[N-1][i]=1 dp[N-1][i] [N-1] dp N-1 N 1 i 1 for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
     i reversed(range(N-1)) reversed range(N-1) range N-1 N 1 for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
     j reversed(range(N-1)) reversed range(N-1) range N-1 N 1 if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
     i>j i j if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
     S[i]!=S[j] S[i] S i S[j] S j dp[i][j]=0 dp[i][j] [i] dp i j 0 dp[i][j]=min(i-j,dp[i+1][j+1]+1) dp[i][j] [i] dp i j min(i-j,dp[i+1][j+1]+1) min i-j i j dp[i+1][j+1]+1 dp[i+1][j+1] [i+1] dp i+1 i 1 j+1 j 1 1 ans=0 ans 0 for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
     i reversed(range(N)) reversed range(N) range N for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
     j reversed(range(N)) reversed range(N) range N if i>j:
                ans=max(ans,dp[i][j])
     i>j i j ans=max(ans,dp[i][j]) ans max(ans,dp[i][j]) max ans dp[i][j] [i] dp i j print(ans) print ans resolve() resolve def resolve():
    
    # https://qiita.com/drken/items/dc53c683d6de8aeacf5a#dp-%E5%AE%9F%E8%A3%85%E3%81%AE%E9%A0%86%E5%BA%8F
    
    
    INF = 10**10  # INF+INFを計算してもオーバーフローしない範囲で大きく
    
    N = int(input())
    S=input()
    # dpテーブル dp[i][j]:= ...
    dp = [[0]*N for _ in range(N)]
    
    # 初期条件
    dp[0][0] = 0
    for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
    for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
    ans=0
    for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
    print(ans)

    
     def resolve():
    
    # https://qiita.com/drken/items/dc53c683d6de8aeacf5a#dp-%E5%AE%9F%E8%A3%85%E3%81%AE%E9%A0%86%E5%BA%8F
    
    
    INF = 10**10  # INF+INFを計算してもオーバーフローしない範囲で大きく
    
    N = int(input())
    S=input()
    # dpテーブル dp[i][j]:= ...
    dp = [[0]*N for _ in range(N)]
    
    # 初期条件
    dp[0][0] = 0
    for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
    for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
    ans=0
    for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
    print(ans)

    
     resolve def input(): return sys.stdin.readline().strip() def input(): return sys.stdin.readline().strip() input
import sys
sys.setrecursionlimit(10 ** 5 + 10)
def input(): return sys.stdin.readline().strip()

def resolve():
    
    # https://qiita.com/drken/items/dc53c683d6de8aeacf5a#dp-%E5%AE%9F%E8%A3%85%E3%81%AE%E9%A0%86%E5%BA%8F
    
    
    INF = 10**10  # INF+INFを計算してもオーバーフローしない範囲で大きく
    
    N = int(input())
    S=input()
    # dpテーブル dp[i][j]:= ...
    dp = [[0]*N for _ in range(N)]
    
    # 初期条件
    dp[0][0] = 0
    for i in range(N-1):
        if S[i]==S[N-1]:
            dp[N-1][i]=1


    # ループ
    for i in reversed(range(N-1)):
        for j in reversed(range(N-1)):
            if i>j:
                if S[i]!=S[j]:
                    dp[i][j]=0
                else:
                    dp[i][j]=min(i-j,dp[i+1][j+1]+1)
    
    ans=0
    for i in reversed(range(N)):
        for j in reversed(range(N)):
            if i>j:
                ans=max(ans,dp[i][j])
    print(ans)

    
    
resolve()