import sys

sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline


class RollingHash:
    def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
    def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod


def solve():
    N = int(rl())
    S = input()
    
    rh = RollingHash(S)
    
    def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
    ok, ng = 0, N // 2 + 1
    while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok)


if __name__ == '__main__':
    solve() import sys sys sys.setrecursionlimit(10 ** 7) sys.setrecursionlimit sys setrecursionlimit 10 ** 7 10 7 rl = sys.stdin.readline rl sys.stdin.readline sys.stdin sys stdin readline class RollingHash:
    def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
    def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod RollingHash def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
     __init__ self.mod = mod self.mod self mod mod length = len(s) length len(s) len s self.pw = [1] * (length + 1) self.pw self pw [1] * (length + 1) [1] 1 length + 1 length 1 self.h = [0] * (length + 1) self.h self h [0] * (length + 1) [0] 0 length + 1 length 1 v = 0 v 0 for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
         i range(length) range length self.h[i + 1] = v = (v * base + ord(s[i])) % mod self.h[i + 1] self.h self h i + 1 i 1 (v * base + ord(s[i])) % mod v * base + ord(s[i]) v * base v base ord(s[i]) ord s[i] s i mod = v = (v * base + ord(s[i])) % mod v (v * base + ord(s[i])) % mod v = 1 v 1 for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
     i range(length) range length self.pw[i + 1] = v = v * base % mod self.pw[i + 1] self.pw self pw i + 1 i 1 v * base % mod v * base v base mod = v = v * base % mod v v * base % mod self self s: str s base=1007 base 1007 mod=10 ** 9 + 7 mod 10 ** 9 + 7 10 ** 9 10 9 7 def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod query return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod self.h[right] - self.h[left] * self.pw[right - left] self.h[right] self.h self h right self.h[left] * self.pw[right - left] self.h[left] self.h self h left self.pw[right - left] self.pw self pw right - left right left self.mod self mod self self left left right right def solve():
    N = int(rl())
    S = input()
    
    rh = RollingHash(S)
    
    def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
    ok, ng = 0, N // 2 + 1
    while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok) solve N = int(rl()) N int(rl()) int rl() rl S = input() S input() input rh = RollingHash(S) rh RollingHash(S) RollingHash S def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
     check dist = dict() dist dict() dict for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
         i range(N - t + 1) range N - t + 1 N - t N t 1 h = rh.query(i, i + t) h rh.query(i, i + t) rh.query rh query i i + t i t if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
         h in dist h dist if t <= i - dist[h]:
                    return True
             t <= i - dist[h] t i - dist[h] i dist[h] dist h return True True dist[h] = i dist[h] dist h i return False False t t ok, ng = 0, N // 2 + 1 ok 0 ng N // 2 + 1 N // 2 N 2 1 while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
     1 < ng - ok 1 ng - ok ng ok mid = (ok + ng) // 2 mid (ok + ng) // 2 ok + ng ok ng 2 if check(mid):
            ok = mid
        else:
            ng = mid
     check(mid) check mid ok = mid ok mid ng = mid ng mid print(ok) print ok if __name__ == '__main__':
    solve() __name__ == '__main__' __name__ '__main__' solve() solve rl = sys.stdin.readline sys.stdin.readline rl class RollingHash:
    def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
    def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod class RollingHash:
    def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
    def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod RollingHash def solve():
    N = int(rl())
    S = input()
    
    rh = RollingHash(S)
    
    def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
    ok, ng = 0, N // 2 + 1
    while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok) def solve():
    N = int(rl())
    S = input()
    
    rh = RollingHash(S)
    
    def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
    ok, ng = 0, N // 2 + 1
    while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok) solve
import sys

sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline


class RollingHash:
    def __init__(self, s: str, base=1007, mod=10 ** 9 + 7):
        self.mod = mod
        length = len(s)
        self.pw = [1] * (length + 1)
        self.h = [0] * (length + 1)
        
        v = 0
        for i in range(length):
            self.h[i + 1] = v = (v * base + ord(s[i])) % mod
        v = 1
        for i in range(length):
            self.pw[i + 1] = v = v * base % mod
    
    def query(self, left, right):
        return (self.h[right] - self.h[left] * self.pw[right - left]) % self.mod


def solve():
    N = int(rl())
    S = input()
    
    rh = RollingHash(S)
    
    def check(t):
        dist = dict()
        for i in range(N - t + 1):
            h = rh.query(i, i + t)
            if h in dist:
                if t <= i - dist[h]:
                    return True
            else:
                dist[h] = i
        return False
    
    ok, ng = 0, N // 2 + 1
    while 1 < ng - ok:
        mid = (ok + ng) // 2
        if check(mid):
            ok = mid
        else:
            ng = mid
    print(ok)


if __name__ == '__main__':
    solve()
