#include<algorithm>
#include <iostream>
#include  <cstdlib>
#include  <cstring>
#include   <string>
#include   <vector>
#include   <cstdio>
#include    <queue>
#include    <stack>
#include    <ctime>
#include    <cmath>
#include      <map>
#include      <set>
#define ll long long
#define INF 0x3f3f3f3f
#define pii pair<int,int>
#define mkp(a,b) make_pair(a,b)
#define FOR(i,a,b) for(int i=a;i<b;i++)
#define db1(x) cout<<#x<<"="<<(x)<<endl
#define db2(x,y) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<endl
#define db3(x,y,z) cout<<#x<<"="<<(x)<<", "<<#y<<"="<<(y)<<", "<<#z<<"="<<(z)<<endl
#define getchar()(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<22,stdin),p1==p2)?EOF:*p1++)


using namespace std;
const int maxn = 100100; // 字符串最大长度
const int sz = 1010;     // 字符集最大ASCII码

// 下面五个都是求后缀数组时基数排序用的
int cntA[maxn];
int cntB[maxn];
int A[maxn];
int B[maxn];
int tsa[maxn];

int sa[maxn];     // sa[i]表示字典序第i小的后缀的起始位置
int rk[maxn];       // rk[i]表示第i个字符开始的后缀字典序排第几
int height[maxn];   // height[i]表示字典序排第i的后缀与排第i-1的后缀的最长公共前缀长度
char ch[maxn];      // 待处理字符串，从1到n

// 传入字符串长度,求sa[]，rk[],height[]
void solve(int n)
{
    for (int i = 0; i < sz; i ++) cntA[i] = 0;
    for (int i = 1; i <= n; i ++) cntA[ch[i]] ++;
    for (int i = 1; i < sz; i ++) cntA[i] += cntA[i - 1];
    for (int i = n; i; i --) sa[cntA[ch[i]] --] = i;
    rk[sa[1]] = 1;
    for (int i = 2; i <= n; i ++)
    {
        rk[sa[i]] = rk[sa[i - 1]];
        if (ch[sa[i]] != ch[sa[i - 1]]) rk[sa[i]] ++;
    }
    for (int l = 1; rk[sa[n]] < n; l <<= 1)
    {
        for (int i = 0; i <= n; i ++) cntA[i] = 0;
        for (int i = 0; i <= n; i ++) cntB[i] = 0;
        for (int i = 1; i <= n; i ++)
        {
            cntA[A[i] = rk[i]] ++;
            cntB[B[i] = (i + l <= n) ? rk[i + l] : 0] ++;
        }
        for (int i = 1; i <= n; i ++) cntB[i] += cntB[i - 1];
        for (int i = n; i; i --) tsa[cntB[B[i]] --] = i;
        for (int i = 1; i <= n; i ++) cntA[i] += cntA[i - 1];
        for (int i = n; i; i --) sa[cntA[A[tsa[i]]] --] = tsa[i];
        rk[sa[1]] = 1;
        for (int i = 2; i <= n; i ++)
        {
            rk[sa[i]] = rk[sa[i - 1]];
            if (A[sa[i]] != A[sa[i - 1]] || B[sa[i]] != B[sa[i - 1]]) rk[sa[i]] ++;
        }
    }
    for (int i = 1, j = 0; i <= n; i ++)
    {
        if (j) j --;
        while (ch[i + j] == ch[sa[rk[i] - 1] + j]) j ++;
        height[rk[i]] = j;
    }
}

bool check(int n, int K)
{
    int minsa = 1e9, maxsa = -1e9;
    for(int i = 1; i <= n; i ++)
        if(height[i] < K)
        {
            minsa = sa[i];
            maxsa = sa[i];
        }
        else
        {
            minsa = min(minsa,sa[i]);
            maxsa = max(maxsa,sa[i]);
            if(maxsa-minsa >= K)
                return true;
        }
    return false;
}

int main()
{
    #ifdef test
    freopen("in.txt", "r", stdin);
    #endif

    int n;
    scanf("%d%s", &n, ch+1);

    solve(n);

    int l = 0, r = n;
    int ans = 0;
    while (l <= r)
    {
        int k = l + ((r-l) >> 1);
        if(check(n, k))
        {
            ans = k;
            l = k+1;
        }
        else
        {
            r = k-1;
        }
    }

    cout << ans << endl;


    return 0;
}


Measured memory_bytes: 384