import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()

class SuffixArray:

    """

    construct:

        suffix array: O(N(logN)^2)

        lcp array: O(N)

        sparse table: O(NlogN)

    query:

        get_lcp: O(1)

    """

    def __init__(self, s):

        """

        s: str

        """

        self.__s=s

        self.__n=len(s)

        self.__suffix_array()

        self.__lcp_array()

        self.__sparse_table()



    # suffix array

    def __suffix_array(self):

        s=self.__s; n=self.__n

        # initialize

        sa=list(range(n))

        rank=[ord(s[i]) for i in range(n)]

        tmp=[0]*n

        k=1

        cmp_key=lambda i:(rank[i],rank[i+k] if i+k<n else -1)

        # iterate

        while(k<=n):

            sa.sort(key=cmp_key)

            tmp[sa[0]]=0

            for i in range(1,n):

                tmp[sa[i]]=tmp[sa[i-1]]+(cmp_key(sa[i-1])<cmp_key(sa[i]))

            rank=tmp[:]

            k<<=1

        self.__sa=sa

        self.__rank=rank



    # LCP array

    def __lcp_array(self):

        n=self.__n; s=self.__s;

        sa=self.__sa; rank=self.__rank

        lcp=[0]*n

        h=0

        for i in range(n):

            j=sa[rank[i]-1]

            if h > 0: h -= 1

            while j+h<n and i+h<n and s[j+h]==s[i+h]: h+=1

            lcp[rank[i]]=h

        self.__lcp=lcp



    # sparse table (LCPのminをとるindexを持つ)

    def __sparse_table(self):

        n=self.__n

        logn=max(0,(n-1).bit_length())

        table=[[0]*n for _ in range(logn)]

        table[0]=list(range(n))

        # construct

        for i in range(1,logn):

            for k in range(n):

                if k+(1<<(i-1))>=n:

                    table[i][k]=table[i-1][k]

                    continue

                if self.__lcp[table[i-1][k]]<=self.__lcp[table[i-1][k+(1<<(i-1))]]:

                    table[i][k]=table[i-1][k]

                else:

                    table[i][k]=table[i-1][k+(1<<(i-1))]

        self.__table=table



    def get_lcp(self,a,b):

        """

        a,b: int 0<=a,b<n

        return LCP length between s[a:] and s[b:]

        """

        if a==b: return self.__n-a

        l,r=self.__rank[a],self.__rank[b]

        l,r=min(l,r)+1,max(l,r)+1

        if r-l==1: return self.__lcp[l]

        i=(r-l-1).bit_length()-1

        if self.__lcp[self.__table[i][l]]<=self.__lcp[self.__table[i][r-(1<<i)]]:

            return self.__lcp[self.__table[i][l]]

        else:

            return self.__lcp[self.__table[i][r-(1<<i)]]

def resolve():

    n=int(eval(input()))

    s=eval(input())

    sa=SuffixArray(s)

    ans=0

    for i in range(n):

        for j in range(i+1,n):

            ans=max(ans,min(sa.get_lcp(i,j),j-i))

    print(ans)

resolve()
import sys

sys.setrecursionlimit(2147483647)

INF=float("inf")

MOD=10**9+7

input=lambda :sys.stdin.readline().rstrip()

class SuffixArray(object):

    """

    construct:

        suffix array: O(N(logN)^2)

        lcp array: O(N)

        sparse table: O(NlogN)

    query:

        lcp: O(1)

    """

    def __init__(self,s):

        """

        s: str

        """

        self.__s=s

        self.__n=len(s)

        self.__suffix_array()

        self.__lcp_array()

        self.__sparse_table()



    # suffix array

    def __suffix_array(self):

        s=self.__s; n=self.__n

        # initialize

        sa=list(range(n))

        rank=[ord(s[i]) for i in range(n)]

        tmp=[0]*n

        k=1

        cmp_key=lambda i:(rank[i],rank[i+k] if i+k<n else -1)

        # iterate

        while(k<=n):

            sa.sort(key=cmp_key)

            tmp[sa[0]]=0

            for i in range(1,n):

                tmp[sa[i]]=tmp[sa[i-1]]+(cmp_key(sa[i-1])<cmp_key(sa[i]))

            rank=tmp[:]

            k<<=1

        self.__sa=sa

        self.__rank=rank



    # LCP array

    def __lcp_array(self):

        s=self.__s; n=self.__n

        sa=self.__sa; rank=self.__rank

        lcp=[0]*n

        h=0

        for i in range(n):

            j=sa[rank[i]-1]

            if h>0: h-=1

            while j+h<n and i+h<n and s[j+h]==s[i+h]: h+=1

            lcp[rank[i]]=h

        self.__lcp=lcp



    # sparse table

    def __sparse_table(self):

        n=self.__n

        logn=max(0,(n-1).bit_length())

        table=[[0]*n for _ in range(logn)]

        table[0]=self.__lcp[:]

        # construct

        from itertools import product

        for i,k in product(list(range(1,logn)),list(range(n))):

            if k+(1<<(i-1))>=n:

                table[i][k]=table[i-1][k]

            else:

                table[i][k]=min(table[i-1][k],table[i-1][k+(1<<(i-1))])

        self.__table=table



    def lcp(self,a,b):

        """

        a,b: int 0<=a,b<n

        return LCP length between s[a:] and s[b:]

        """

        if a==b: return self.__n-a

        l,r=self.__rank[a],self.__rank[b]

        l,r=min(l,r)+1,max(l,r)+1

        i=max(0,(r-l-1).bit_length()-1)

        table=self.__table

        return min(table[i][l],table[i][r-(1<<i)])

def resolve():

    n=int(eval(input()))

    s=eval(input())

    sa=SuffixArray(s)

    ans=0

    for i in range(n):

        for j in range(i+1,n):

            ans=max(ans,min(sa.lcp(i,j),j-i))

    print(ans)

resolve()
import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


class SuffixArray:
    """
    construct:
        suffix array: O(N(logN)^2)
        lcp array: O(N)
        sparse table: O(NlogN)
    query:
        get_lcp: O(1)
    """

    def __init__(self, s):
        """
        s: str
        """
        self.__s = s
        self.__n = len(s)
        self.__suffix_array()
        self.__lcp_array()
        self.__sparse_table()

    # suffix array
    def __suffix_array(self):
        s = self.__s
        n = self.__n
        # initialize
        sa = list(range(n))
        rank = [ord(s[i]) for i in range(n)]
        tmp = [0] * n
        k = 1
        cmp_key = lambda i: (rank[i], rank[i + k] if i + k < n else -1)
        # iterate
        while k <= n:
            sa.sort(key=cmp_key)
            tmp[sa[0]] = 0
            for i in range(1, n):
                tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_key(sa[i - 1]) < cmp_key(sa[i]))
            rank = tmp[:]
            k <<= 1
        self.__sa = sa
        self.__rank = rank

    # LCP array
    def __lcp_array(self):
        n = self.__n
        s = self.__s
        sa = self.__sa
        rank = self.__rank
        lcp = [0] * n
        h = 0
        for i in range(n):
            j = sa[rank[i] - 1]
            if h > 0:
                h -= 1
            while j + h < n and i + h < n and s[j + h] == s[i + h]:
                h += 1
            lcp[rank[i]] = h
        self.__lcp = lcp

    # sparse table (LCPのminをとるindexを持つ)
    def __sparse_table(self):
        n = self.__n
        logn = max(0, (n - 1).bit_length())
        table = [[0] * n for _ in range(logn)]
        table[0] = list(range(n))
        # construct
        for i in range(1, logn):
            for k in range(n):
                if k + (1 << (i - 1)) >= n:
                    table[i][k] = table[i - 1][k]
                    continue
                if (
                    self.__lcp[table[i - 1][k]]
                    <= self.__lcp[table[i - 1][k + (1 << (i - 1))]]
                ):
                    table[i][k] = table[i - 1][k]
                else:
                    table[i][k] = table[i - 1][k + (1 << (i - 1))]
        self.__table = table

    def get_lcp(self, a, b):
        """
        a,b: int 0<=a,b<n
        return LCP length between s[a:] and s[b:]
        """
        if a == b:
            return self.__n - a
        l, r = self.__rank[a], self.__rank[b]
        l, r = min(l, r) + 1, max(l, r) + 1
        if r - l == 1:
            return self.__lcp[l]
        i = (r - l - 1).bit_length() - 1
        if self.__lcp[self.__table[i][l]] <= self.__lcp[self.__table[i][r - (1 << i)]]:
            return self.__lcp[self.__table[i][l]]
        else:
            return self.__lcp[self.__table[i][r - (1 << i)]]


def resolve():
    n = int(eval(input()))
    s = eval(input())
    sa = SuffixArray(s)
    ans = 0
    for i in range(n):
        for j in range(i + 1, n):
            ans = max(ans, min(sa.get_lcp(i, j), j - i))
    print(ans)


resolve()

import sys

sys.setrecursionlimit(2147483647)
INF = float("inf")
MOD = 10**9 + 7
input = lambda: sys.stdin.readline().rstrip()


class SuffixArray(object):
    """
    construct:
        suffix array: O(N(logN)^2)
        lcp array: O(N)
        sparse table: O(NlogN)
    query:
        lcp: O(1)
    """

    def __init__(self, s):
        """
        s: str
        """
        self.__s = s
        self.__n = len(s)
        self.__suffix_array()
        self.__lcp_array()
        self.__sparse_table()

    # suffix array
    def __suffix_array(self):
        s = self.__s
        n = self.__n
        # initialize
        sa = list(range(n))
        rank = [ord(s[i]) for i in range(n)]
        tmp = [0] * n
        k = 1
        cmp_key = lambda i: (rank[i], rank[i + k] if i + k < n else -1)
        # iterate
        while k <= n:
            sa.sort(key=cmp_key)
            tmp[sa[0]] = 0
            for i in range(1, n):
                tmp[sa[i]] = tmp[sa[i - 1]] + (cmp_key(sa[i - 1]) < cmp_key(sa[i]))
            rank = tmp[:]
            k <<= 1
        self.__sa = sa
        self.__rank = rank

    # LCP array
    def __lcp_array(self):
        s = self.__s
        n = self.__n
        sa = self.__sa
        rank = self.__rank
        lcp = [0] * n
        h = 0
        for i in range(n):
            j = sa[rank[i] - 1]
            if h > 0:
                h -= 1
            while j + h < n and i + h < n and s[j + h] == s[i + h]:
                h += 1
            lcp[rank[i]] = h
        self.__lcp = lcp

    # sparse table
    def __sparse_table(self):
        n = self.__n
        logn = max(0, (n - 1).bit_length())
        table = [[0] * n for _ in range(logn)]
        table[0] = self.__lcp[:]
        # construct
        from itertools import product

        for i, k in product(list(range(1, logn)), list(range(n))):
            if k + (1 << (i - 1)) >= n:
                table[i][k] = table[i - 1][k]
            else:
                table[i][k] = min(table[i - 1][k], table[i - 1][k + (1 << (i - 1))])
        self.__table = table

    def lcp(self, a, b):
        """
        a,b: int 0<=a,b<n
        return LCP length between s[a:] and s[b:]
        """
        if a == b:
            return self.__n - a
        l, r = self.__rank[a], self.__rank[b]
        l, r = min(l, r) + 1, max(l, r) + 1
        i = max(0, (r - l - 1).bit_length() - 1)
        table = self.__table
        return min(table[i][l], table[i][r - (1 << i)])


def resolve():
    n = int(eval(input()))
    s = eval(input())
    sa = SuffixArray(s)
    ans = 0
    for i in range(n):
        for j in range(i + 1, n):
            ans = max(ans, min(sa.lcp(i, j), j - i))
    print(ans)


resolve()

-class SuffixArray: +class SuffixArray(object): -        get_lcp: O(1) +        lcp: O(1) +        s = self.__s -        s = self.__s -    # sparse table (LCPのminをとるindexを持つ) +    # sparse table -        table[0] = list(range(n)) +        table[0] = self.__lcp[:] -        for i in range(1, logn): -            for k in range(n): -                if k + (1 << (i - 1)) >= n: -                    table[i][k] = table[i - 1][k] -                    continue -                if ( -                    self.__lcp[table[i - 1][k]] -                    <= self.__lcp[table[i - 1][k + (1 << (i - 1))]] -                ): -                    table[i][k] = table[i - 1][k] -                else: -                    table[i][k] = table[i - 1][k + (1 << (i - 1))] +        from itertools import product + +        for i, k in product(list(range(1, logn)), list(range(n))): +            if k + (1 << (i - 1)) >= n: +                table[i][k] = table[i - 1][k] +            else: +                table[i][k] = min(table[i - 1][k], table[i - 1][k + (1 << (i - 1))]) -    def get_lcp(self, a, b): +    def lcp(self, a, b): -        if r - l == 1: -            return self.__lcp[l] -        i = (r - l - 1).bit_length() - 1 -        if self.__lcp[self.__table[i][l]] <= self.__lcp[self.__table[i][r - (1 << i)]]: -            return self.__lcp[self.__table[i][l]] -        else: -            return self.__lcp[self.__table[i][r - (1 << i)]] +        i = max(0, (r - l - 1).bit_length() - 1) +        table = self.__table +        return min(table[i][l], table[i][r - (1 << i)]) -            ans = max(ans, min(sa.get_lcp(i, j), j - i)) +            ans = max(ans, min(sa.lcp(i, j), j - i))