import sys

read = sys.stdin.buffer.read

input=lambda :sys.stdin.readline().rstrip()

# inputs= sys.stdin.buffer.readlines

INF=float("inf")

MOD=10**9+7

#input = sys.stdin.buffer.readline

#sys.setrecursionlimit(2147483647)

#rstrip().decode('utf-8')

#import math

#import numpy as np

#import operator

#import bisect

#from heapq import heapify,heappop,heappush

#from math import gcd

#from fractions import gcd

#from collections import deque

#from collections import defaultdict

#from collections import Counter

#from itertools import accumulate

#from itertools import groupby

#from itertools import permutations

#from itertools import combinations

#from scipy.sparse import csr_matrix

#from scipy.sparse.csgraph import floyd_warshall

#from scipy.sparse.csgraph import csgraph_from_dense

#from scipy.sparse.csgraph import dijkstra

#map(int,input().split())



# Z-algorithm (O(N))

# https://deve68.hatenadiary.org/entry/20120201/1328109890

def Z(s):

    n=len(s)

    z=[0]*n

    z[0]=n

    L,R=0,0

    for i in range(1,n):

        if(i>=R): # 過去の結果が全く使えない

            L=R=i

            while(R<n and s[R-L]==s[R]): R+=1

            z[i]=R-L

        elif(z[i-L]<R-i): # 過去の結果が全て使える

            z[i]=z[i-L]

        else: # 過去の結果が一部使える

            L=i

            while(R<n and s[R-L]==s[R]): R+=1

            z[i]=R-L

    return z



# example

#print(Z("abaaabaabb")) # [10,0,1,1,4,0,1,2,0,0]





def main():

	n=int(eval(input()))

	s=eval(input())

	ans=0

	for i in range(n-1):

		z=Z(s[i:])

		k=len(z)

		for j in range(k):

			ans=max(ans,min(j,z[j]))

	print(ans)

	

if __name__ == '__main__':

	main()
n = int(eval(input()))

s = input().rstrip()

 

 

def check(length):

    d = set()

    for i in range(n - 2 * length + 1):

        d.add(s[i:i + length])

        if s[i + length:i + 2 * length] in d:

            return True

    return False

 

 

lo = 0

hi = n // 2 + 1

while lo + 1 < hi:

    mid = (lo + hi) // 2

    if check(mid):

        lo = mid

    else:

        hi = mid

print(lo)
import sys

read = sys.stdin.buffer.read
input = lambda: sys.stdin.readline().rstrip()
# inputs= sys.stdin.buffer.readlines
INF = float("inf")
MOD = 10**9 + 7
# input = sys.stdin.buffer.readline
# sys.setrecursionlimit(2147483647)
# rstrip().decode('utf-8')
# import math
# import numpy as np
# import operator
# import bisect
# from heapq import heapify,heappop,heappush
# from math import gcd
# from fractions import gcd
# from collections import deque
# from collections import defaultdict
# from collections import Counter
# from itertools import accumulate
# from itertools import groupby
# from itertools import permutations
# from itertools import combinations
# from scipy.sparse import csr_matrix
# from scipy.sparse.csgraph import floyd_warshall
# from scipy.sparse.csgraph import csgraph_from_dense
# from scipy.sparse.csgraph import dijkstra
# map(int,input().split())
# Z-algorithm (O(N))
# https://deve68.hatenadiary.org/entry/20120201/1328109890
def Z(s):
    n = len(s)
    z = [0] * n
    z[0] = n
    L, R = 0, 0
    for i in range(1, n):
        if i >= R:  # 過去の結果が全く使えない
            L = R = i
            while R < n and s[R - L] == s[R]:
                R += 1
            z[i] = R - L
        elif z[i - L] < R - i:  # 過去の結果が全て使える
            z[i] = z[i - L]
        else:  # 過去の結果が一部使える
            L = i
            while R < n and s[R - L] == s[R]:
                R += 1
            z[i] = R - L
    return z


# example
# print(Z("abaaabaabb")) # [10,0,1,1,4,0,1,2,0,0]
def main():
    n = int(eval(input()))
    s = eval(input())
    ans = 0
    for i in range(n - 1):
        z = Z(s[i:])
        k = len(z)
        for j in range(k):
            ans = max(ans, min(j, z[j]))
    print(ans)


if __name__ == "__main__":
    main()

n = int(eval(input()))
s = input().rstrip()


def check(length):
    d = set()
    for i in range(n - 2 * length + 1):
        d.add(s[i : i + length])
        if s[i + length : i + 2 * length] in d:
            return True
    return False


lo = 0
hi = n // 2 + 1
while lo + 1 < hi:
    mid = (lo + hi) // 2
    if check(mid):
        lo = mid
    else:
        hi = mid
print(lo)

-import sys - -read = sys.stdin.buffer.read -input = lambda: sys.stdin.readline().rstrip() -# inputs= sys.stdin.buffer.readlines -INF = float("inf") -MOD = 10**9 + 7 -# input = sys.stdin.buffer.readline -# sys.setrecursionlimit(2147483647) -# rstrip().decode('utf-8') -# import math -# import numpy as np -# import operator -# import bisect -# from heapq import heapify,heappop,heappush -# from math import gcd -# from fractions import gcd -# from collections import deque -# from collections import defaultdict -# from collections import Counter -# from itertools import accumulate -# from itertools import groupby -# from itertools import permutations -# from itertools import combinations -# from scipy.sparse import csr_matrix -# from scipy.sparse.csgraph import floyd_warshall -# from scipy.sparse.csgraph import csgraph_from_dense -# from scipy.sparse.csgraph import dijkstra -# map(int,input().split()) -# Z-algorithm (O(N)) -# https://deve68.hatenadiary.org/entry/20120201/1328109890 -def Z(s): -    n = len(s) -    z = [0] * n -    z[0] = n -    L, R = 0, 0 -    for i in range(1, n): -        if i >= R:  # 過去の結果が全く使えない -            L = R = i -            while R < n and s[R - L] == s[R]: -                R += 1 -            z[i] = R - L -        elif z[i - L] < R - i:  # 過去の結果が全て使える -            z[i] = z[i - L] -        else:  # 過去の結果が一部使える -            L = i -            while R < n and s[R - L] == s[R]: -                R += 1 -            z[i] = R - L -    return z +n = int(eval(input())) +s = input().rstrip() -# example -# print(Z("abaaabaabb")) # [10,0,1,1,4,0,1,2,0,0] -def main(): -    n = int(eval(input())) -    s = eval(input()) -    ans = 0 -    for i in range(n - 1): -        z = Z(s[i:]) -        k = len(z) -        for j in range(k): -            ans = max(ans, min(j, z[j])) -    print(ans) +def check(length): +    d = set() +    for i in range(n - 2 * length + 1): +        d.add(s[i : i + length]) +        if s[i + length : i + 2 * length] in d: +            return True +    return False -if __name__ == "__main__": -    main() +lo = 0 +hi = n // 2 + 1 +while lo + 1 < hi: +    mid = (lo + hi) // 2 +    if check(mid): +        lo = mid +    else: +        hi = mid +print(lo)