import collections





class RollingHashSingle:

    def __init__(self, s, base, mod):

        self.base = base

        self.mod = mod



        self.hash = [0]

        self.power = [1]

        for c in s:

            self.hash.append((self.hash[-1] * base + ord(c)) % mod)

            self.power.append(self.power[-1] * base % mod)



    def get(self, left, right):

        h = self.hash[right] - self.hash[left] * self.power[right - left]

        return (h + self.mod) % self.mod





class RollingHash:

    def __init__(self,

                 s,

                 base=(10**4 + 7, 10**4 + 9),

                 mod=(10**9 + 7, 10**9 + 9)):

        if isinstance(base, int):

            assert isinstance(mod, int)

            self.base = (base, )

            self.mod = (mod, )

        elif isinstance(base, tuple):

            assert isinstance(mod, tuple)

            assert len(base) == len(mod)

            self.base = base

            self.mod = mod

        else:

            raise ValueError()



        self._rh = [

            RollingHashSingle(s, base, mod)

            for base, mod in zip(self.base, self.mod)

        ]



    def get(self, left, right):

        return tuple(rh.get(left, right) for rh in self._rh)





n = int(eval(input()))

s = input().rstrip()

rh = RollingHash(s)





def check(diff):

    d = collections.defaultdict(list)

    for i in range(n - diff + 1):

        h = rh.get(i, i + diff)

        d[h].append(i)

    for l in list(d.values()):

        if max(l) - min(l) >= diff:

            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)
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 collections


class RollingHashSingle:
    def __init__(self, s, base, mod):
        self.base = base
        self.mod = mod
        self.hash = [0]
        self.power = [1]
        for c in s:
            self.hash.append((self.hash[-1] * base + ord(c)) % mod)
            self.power.append(self.power[-1] * base % mod)

    def get(self, left, right):
        h = self.hash[right] - self.hash[left] * self.power[right - left]
        return (h + self.mod) % self.mod


class RollingHash:
    def __init__(
        self, s, base=(10**4 + 7, 10**4 + 9), mod=(10**9 + 7, 10**9 + 9)
    ):
        if isinstance(base, int):
            assert isinstance(mod, int)
            self.base = (base,)
            self.mod = (mod,)
        elif isinstance(base, tuple):
            assert isinstance(mod, tuple)
            assert len(base) == len(mod)
            self.base = base
            self.mod = mod
        else:
            raise ValueError()
        self._rh = [
            RollingHashSingle(s, base, mod) for base, mod in zip(self.base, self.mod)
        ]

    def get(self, left, right):
        return tuple(rh.get(left, right) for rh in self._rh)


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


def check(diff):
    d = collections.defaultdict(list)
    for i in range(n - diff + 1):
        h = rh.get(i, i + diff)
        d[h].append(i)
    for l in list(d.values()):
        if max(l) - min(l) >= diff:
            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)

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 collections +n = int(eval(input())) +s = input().rstrip() -class RollingHashSingle: -    def __init__(self, s, base, mod): -        self.base = base -        self.mod = mod -        self.hash = [0] -        self.power = [1] -        for c in s: -            self.hash.append((self.hash[-1] * base + ord(c)) % mod) -            self.power.append(self.power[-1] * base % mod) - -    def get(self, left, right): -        h = self.hash[right] - self.hash[left] * self.power[right - left] -        return (h + self.mod) % self.mod - - -class RollingHash: -    def __init__( -        self, s, base=(10**4 + 7, 10**4 + 9), mod=(10**9 + 7, 10**9 + 9) -    ): -        if isinstance(base, int): -            assert isinstance(mod, int) -            self.base = (base,) -            self.mod = (mod,) -        elif isinstance(base, tuple): -            assert isinstance(mod, tuple) -            assert len(base) == len(mod) -            self.base = base -            self.mod = mod -        else: -            raise ValueError() -        self._rh = [ -            RollingHashSingle(s, base, mod) for base, mod in zip(self.base, self.mod) -        ] - -    def get(self, left, right): -        return tuple(rh.get(left, right) for rh in self._rh) - - -n = int(eval(input())) -s = input().rstrip() -rh = RollingHash(s) - - -def check(diff): -    d = collections.defaultdict(list) -    for i in range(n - diff + 1): -        h = rh.get(i, i + diff) -        d[h].append(i) -    for l in list(d.values()): -        if max(l) - min(l) >= diff: +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: