class RollingHash():

    def __init__(self,s):

        self.n=n=len(s)

        self.b=b=129

        self.M=M=2**61-1

        x,y=1,0

        self.f=f=[x]*(n+1)

        self.h=h=[y]*(n+1)

        for i,c in enumerate(s.encode()):

            f[i+1]=x=x*b%M

            h[i+1]=y=(y*b+c)%M

    def get(self,l,r):

        return(self.h[r]-self.h[l]*self.f[r-l])%self.M

def main():

    n=int(eval(input()))

    s=RollingHash(eval(input()))

    ok,ng=0,n

    while ng-ok>1:

        mid=ok+ng>>1

        d={}

        for i in range(0,n-mid+1):

            k=s.get(i,i+mid)

            if k in d:

                if d[k]+mid<=i:

                    ok=mid

                    break

            else:

                d[k]=i

        else:

            ng=mid

    print(ok)

main()
def main():

    import sys

    input=sys.stdin.buffer.readline

    n=int(eval(input()))

    b=129

    M=2**61-1

    x,y=1,0

    f=[x]*(n+2)

    h=[y]*(n+2)

    for i,c in enumerate(eval(input())):

        f[i+1]=x=x*b%M

        h[i+1]=y=(y*b+c)%M

    ok,ng=0,n//2+1

    while ng-ok>1:

        mid=ok+ng>>1

        d={}

        for i in range(0,n-mid+1):

            k=(h[i+mid]-h[i]*f[mid])%M

            if k in d:

                if d[k]+mid<=i:

                    ok=mid

                    break

            else:

                d[k]=i

        else:

            ng=mid

    print(ok)

main()
class RollingHash:
    def __init__(self, s):
        self.n = n = len(s)
        self.b = b = 129
        self.M = M = 2**61 - 1
        x, y = 1, 0
        self.f = f = [x] * (n + 1)
        self.h = h = [y] * (n + 1)
        for i, c in enumerate(s.encode()):
            f[i + 1] = x = x * b % M
            h[i + 1] = y = (y * b + c) % M

    def get(self, l, r):
        return (self.h[r] - self.h[l] * self.f[r - l]) % self.M


def main():
    n = int(eval(input()))
    s = RollingHash(eval(input()))
    ok, ng = 0, n
    while ng - ok > 1:
        mid = ok + ng >> 1
        d = {}
        for i in range(0, n - mid + 1):
            k = s.get(i, i + mid)
            if k in d:
                if d[k] + mid <= i:
                    ok = mid
                    break
            else:
                d[k] = i
        else:
            ng = mid
    print(ok)


main()

def main():
    import sys

    input = sys.stdin.buffer.readline
    n = int(eval(input()))
    b = 129
    M = 2**61 - 1
    x, y = 1, 0
    f = [x] * (n + 2)
    h = [y] * (n + 2)
    for i, c in enumerate(eval(input())):
        f[i + 1] = x = x * b % M
        h[i + 1] = y = (y * b + c) % M
    ok, ng = 0, n // 2 + 1
    while ng - ok > 1:
        mid = ok + ng >> 1
        d = {}
        for i in range(0, n - mid + 1):
            k = (h[i + mid] - h[i] * f[mid]) % M
            if k in d:
                if d[k] + mid <= i:
                    ok = mid
                    break
            else:
                d[k] = i
        else:
            ng = mid
    print(ok)


main()

-class RollingHash: -    def __init__(self, s): -        self.n = n = len(s) -        self.b = b = 129 -        self.M = M = 2**61 - 1 -        x, y = 1, 0 -        self.f = f = [x] * (n + 1) -        self.h = h = [y] * (n + 1) -        for i, c in enumerate(s.encode()): -            f[i + 1] = x = x * b % M -            h[i + 1] = y = (y * b + c) % M +def main(): +    import sys -    def get(self, l, r): -        return (self.h[r] - self.h[l] * self.f[r - l]) % self.M - - -def main(): +    input = sys.stdin.buffer.readline -    s = RollingHash(eval(input())) -    ok, ng = 0, n +    b = 129 +    M = 2**61 - 1 +    x, y = 1, 0 +    f = [x] * (n + 2) +    h = [y] * (n + 2) +    for i, c in enumerate(eval(input())): +        f[i + 1] = x = x * b % M +        h[i + 1] = y = (y * b + c) % M +    ok, ng = 0, n // 2 + 1 -            k = s.get(i, i + mid) +            k = (h[i + mid] - h[i] * f[mid]) % M