class RollingHash:
    def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

    def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
    def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

    def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2)

from collections import defaultdict

def solve1():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    ans = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

    print(ans)


def solve2():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

    left, right = 0, size//2 + 1
    while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

    print(left)

if __name__ == "__main__":
    # solve1()
    solve2()
 class RollingHash:
    def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

    def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
    def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

    def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2) RollingHash def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

     __init__ b1, b2 = 1007, 2009 b1 1007 b2 2009 self.mod1, self.mod2 = 10**9+7, 10**9+9 self.mod1 self mod1 10**9+7 10**9 10 9 7 self.mod2 self mod2 10**9+9 10**9 10 9 9 self.size = len(s) self.size self size len(s) len s self.string = s self.string self string s self.hash1 = self.make_hashtable(b1, self.mod1) self.hash1 self hash1 self.make_hashtable(b1, self.mod1) self.make_hashtable self make_hashtable b1 self.mod1 self mod1 self.hash2 = self.make_hashtable(b2, self.mod2) self.hash2 self hash2 self.make_hashtable(b2, self.mod2) self.make_hashtable self make_hashtable b2 self.mod2 self mod2 self.pow1 = self.make_powtable(b1, self.mod1) self.pow1 self pow1 self.make_powtable(b1, self.mod1) self.make_powtable self make_powtable b1 self.mod1 self mod1 self.pow2 = self.make_powtable(b2, self.mod2) self.pow2 self pow2 self.make_powtable(b2, self.mod2) self.make_powtable self make_powtable b2 self.mod2 self mod2 self self s s def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
     make_hashtable hashtable = [0] * (self.size+1) hashtable [0] * (self.size+1) [0] 0 self.size+1 self.size self size 1 for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
         i range(1, self.size+1) range 1 self.size+1 self.size self size 1 hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD hashtable[i] hashtable i (hashtable[i-1] * B + ord(self.string[i-1]))%MOD hashtable[i-1] * B + ord(self.string[i-1]) hashtable[i-1] * B hashtable[i-1] hashtable i-1 i 1 B ord(self.string[i-1]) ord self.string[i-1] self.string self string i-1 i 1 MOD return hashtable hashtable self self B B MOD MOD def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

     make_powtable power = [0] * (self.size+1) power [0] * (self.size+1) [0] 0 self.size+1 self.size self size 1 power[0] = 1 power[0] power 0 1 for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
         i range(1, self.size+1) range 1 self.size+1 self.size self size 1 power[i] = (B * power[i-1])%MOD power[i] power i (B * power[i-1])%MOD B * power[i-1] B power[i-1] power i-1 i 1 MOD return power power self self B B MOD MOD def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2) get_hash r = length+l-1 r length+l-1 length+l length l 1 l -= 1 l 1 h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1 h1 (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1 self.hash1[r]-self.hash1[l]*self.pow1[r-l] self.hash1[r] self.hash1 self hash1 r self.hash1[l]*self.pow1[r-l] self.hash1[l] self.hash1 self hash1 l self.pow1[r-l] self.pow1 self pow1 r-l r l self.mod1 self mod1 h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2 h2 (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2 self.hash2[r]-self.hash2[l]*self.pow2[r-l] self.hash2[r] self.hash2 self hash2 r self.hash2[l]*self.pow2[r-l] self.hash2[l] self.hash2 self hash2 l self.pow2[r-l] self.pow2 self pow2 r-l r l self.mod2 self mod2 return (h1, h2) (h1, h2) h1 h2 self self l l length length from collections import defaultdict def solve1():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    ans = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

    print(ans) solve1 N = int(input()) N int(input()) int input() input S = input() S input() input size = len(S) size len(S) len S hash_table = RollingHash(S) hash_table RollingHash(S) RollingHash S ans = 0 ans 0 for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

     i range(1, N+1) range 1 N+1 N 1 for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

     j range(i+1, N+1) range i+1 i 1 N+1 N 1 if S[i-1]!=S[j-1]:continue

             S[i-1]!=S[j-1] S[i-1] S i-1 i 1 S[j-1] S j-1 j 1 left = 1 left 1 right = min(j-i, size-j+1)+1 right min(j-i, size-j+1)+1 min(j-i, size-j+1) min j-i j i size-j+1 size-j size j 1 1 while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
             right-left>1 right-left right left 1 m = (left+right)//2 m (left+right)//2 left+right left right 2 if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
             hash_table.get_hash(i, m)==hash_table.get_hash(j, m) hash_table.get_hash(i, m) hash_table.get_hash hash_table get_hash i m hash_table.get_hash(j, m) hash_table.get_hash hash_table get_hash j m left = m left m right = m right m ans = max(ans, left) ans max(ans, left) max ans left print(ans) print ans def solve2():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

    left, right = 0, size//2 + 1
    while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

    print(left) solve2 N = int(input()) N int(input()) int input() input S = input() S input() input size = len(S) size len(S) len S hash_table = RollingHash(S) hash_table RollingHash(S) RollingHash S def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

     check d = defaultdict(lambda :10**20) d defaultdict(lambda :10**20) defaultdict lambda :10**20 10**20 10 20 for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
         i range(1, size-m+2) range 1 size-m+2 size-m size m 2 h = hash_table.get_hash(i, m) h hash_table.get_hash(i, m) hash_table.get_hash hash_table get_hash i m d[h] = min(d[h], i) d[h] d h min(d[h], i) min d[h] d h i if (i-d[h])>=m:
                return True
         (i-d[h])>=m i-d[h] i d[h] d h m return True True return False False m m left, right = 0, size//2 + 1 left 0 right size//2 + 1 size//2 size 2 1 while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

     right-left>1 right-left right left 1 m = (right+left)//2 m (right+left)//2 right+left right left 2 if check(m):
            left = m
        else:
            right = m

     check(m) check m left = m left m right = m right m print(left) print left if __name__ == "__main__":
    # solve1()
    solve2() __name__ == "__main__" __name__ "__main__" solve2() solve2 class RollingHash:
    def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

    def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
    def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

    def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2) class RollingHash:
    def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

    def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
    def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

    def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2) RollingHash def solve2():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

    left, right = 0, size//2 + 1
    while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

    print(left) def solve2():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

    left, right = 0, size//2 + 1
    while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

    print(left) solve2 def solve1():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    ans = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

    print(ans) def solve1():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    ans = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

    print(ans) solve1
class RollingHash:
    def __init__(self, s):
        b1, b2 = 1007, 2009
        self.mod1, self.mod2 = 10**9+7, 10**9+9
        self.size = len(s)
        self.string = s

        self.hash1 = self.make_hashtable(b1, self.mod1)
        self.hash2 = self.make_hashtable(b2, self.mod2)
        self.pow1 = self.make_powtable(b1, self.mod1)
        self.pow2 = self.make_powtable(b2, self.mod2)

    def make_hashtable(self, B, MOD):
        hashtable = [0] * (self.size+1)
        for i in range(1, self.size+1):
            hashtable[i] = (hashtable[i-1] * B + ord(self.string[i-1]))%MOD
        return hashtable
    
    def make_powtable(self, B, MOD):
        power = [0] * (self.size+1)
        power[0] = 1
        for i in range(1, self.size+1):
            power[i] = (B * power[i-1])%MOD
        return power

    def get_hash(self, l, length):
        r = length+l-1
        l -= 1
        h1 = (self.hash1[r]-self.hash1[l]*self.pow1[r-l])%self.mod1
        h2 = (self.hash2[r]-self.hash2[l]*self.pow2[r-l])%self.mod2
        return (h1, h2)

from collections import defaultdict

def solve1():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    ans = 0
    for i in range(1, N+1):
        for j in range(i+1, N+1):
            if S[i-1]!=S[j-1]:continue

            left = 1
            right = min(j-i, size-j+1)+1

            while right-left>1:
                m = (left+right)//2
                if hash_table.get_hash(i, m)==hash_table.get_hash(j, m):
                    left = m
                else:
                    right = m
            ans = max(ans, left)

    print(ans)


def solve2():
    N = int(input())
    S = input()
    size = len(S)
    hash_table = RollingHash(S)

    def check(m):
        d = defaultdict(lambda :10**20)
        for i in range(1, size-m+2):
            h = hash_table.get_hash(i, m)
            d[h] = min(d[h], i)
            if (i-d[h])>=m:
                return True
        return False

    left, right = 0, size//2 + 1
    while right-left>1:
        m = (right+left)//2
        if check(m):
            left = m
        else:
            right = m

    print(left)

if __name__ == "__main__":
    # solve1()
    solve2()

