from collections import defaultdict


def read():
    N = int(input().strip())
    S = input().strip()
    return N, S


def solve(N, S):
    low = 0
    high = (N >> 1) + 1
    while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
    return low


if __name__ == '__main__':
    inputs = read()
    outputs = solve(*inputs)
    if outputs is not None:
        print("%s" % str(outputs)) from collections import defaultdict def read():
    N = int(input().strip())
    S = input().strip()
    return N, S read N = int(input().strip()) N int(input().strip()) int input().strip() ().strip () input strip S = input().strip() S input().strip() ().strip () input strip return N, S return N, S N S def solve(N, S):
    low = 0
    high = (N >> 1) + 1
    while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
    return low solve low = 0 low 0 high = (N >> 1) + 1 high (N >> 1) + 1 N >> 1 N 1 1 while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
     high - low > 1 high - low high low 1 mid = (high + low) >> 1 mid (high + low) >> 1 high + low high low 1 is_match = False is_match False m = N-mid+1 m N-mid+1 N-mid N mid 1 d = defaultdict(list) d defaultdict(list) defaultdict list for i in range(0, m):
            d[S[i:i+mid]].append(i)
         i range(0, m) range 0 m d[S[i:i+mid]].append(i) [S[i:i+mid]].append [S[i:i+mid]] d S[i:i+mid] S i:i+mid i i+mid i mid append i for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
         v d.values() d.values d values if v[-1] - v[0] >= mid:
                is_match = True
                break
         v[-1] - v[0] >= mid v[-1] - v[0] v[-1] v -1 v[0] v 0 mid is_match = True is_match True break if is_match:
            low = mid
        else:
            high = mid
     is_match low = mid low mid high = mid high mid return low low N N S S if __name__ == '__main__':
    inputs = read()
    outputs = solve(*inputs)
    if outputs is not None:
        print("%s" % str(outputs)) __name__ == '__main__' __name__ '__main__' inputs = read() inputs read() read outputs = solve(*inputs) outputs solve(*inputs) solve *inputs inputs if outputs is not None:
        print("%s" % str(outputs)) outputs is not None outputs None print("%s" % str(outputs)) print "%s" % str(outputs) "%s" str(outputs) str outputs def solve(N, S):
    low = 0
    high = (N >> 1) + 1
    while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
    return low def solve(N, S):
    low = 0
    high = (N >> 1) + 1
    while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
    return low solve def read():
    N = int(input().strip())
    S = input().strip()
    return N, S def read():
    N = int(input().strip())
    S = input().strip()
    return N, S read outputs = solve(*inputs) solve(*inputs) outputs inputs = read() read() inputs
from collections import defaultdict


def read():
    N = int(input().strip())
    S = input().strip()
    return N, S


def solve(N, S):
    low = 0
    high = (N >> 1) + 1
    while high - low > 1:
        mid = (high + low) >> 1
        is_match = False
        m = N-mid+1
        d = defaultdict(list)
        for i in range(0, m):
            d[S[i:i+mid]].append(i)
        for v in d.values():
            if v[-1] - v[0] >= mid:
                is_match = True
                break
        if is_match:
            low = mid
        else:
            high = mid
    return low


if __name__ == '__main__':
    inputs = read()
    outputs = solve(*inputs)
    if outputs is not None:
        print("%s" % str(outputs))