#include<algorithm>
#include<chrono>
#include<climits>
#include<numeric>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<random>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<vector>
#include<cassert>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
using namespace std;
 
struct Debug{
    int cnt = 0;
    bool on = false;
    char debug[10] = "debug";
    template<class T>
    Debug & operator<<(const T & v) {
        if(on && cnt++ == 0) cerr << "debug: ";
        if(on) cerr << v << ' ';
        return *this;
    }
    Debug & operator<<(ostream&(*pManip)(ostream&)) {
        if(on) cerr << (*pManip);
        cnt = 0;
        return *this;
    }
} debug;
#define rep(i, a, b) for(auto i = (a); i < (b); i++)
#define rrep(i, a, b) for(auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define print(v) {if(debug.on){for(auto x : v) debug << x; debug << endl;}}
#define printn(v, n) {if(debug.on){for(int _i = 0; _i < n; _i++) debug << *(v + _i); debug << endl;}}
 

typedef unsigned long long ull;
typedef long long ll;
 
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
 
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;


const int MAXN = 5e3 + 20;

vector<int> suffix_array(const string & s) {
    int n = s.size();
    vector<int> cnt(max(n, 128), 0), pos(n), pos_t(n), c(n), c_t(n);
    for(int i = 0; i < n; i++) {
        c[i] = s[i];
        pos[i] = i;
    }
    for(int len = -1; len < 0 || (1 << len) < n; len++) {
        int l = (len < 0 ? 0 : (1 << len));
        for(int i = 0; i < n; i++)
            pos_t[i] = (pos[i] + n - l) % n;
        
        fill(cnt.begin(), cnt.end(), 0);
        for(int i = 0; i < n; i++)
            cnt[c[i]]++;
        partial_sum(cnt.begin(), cnt.end(), cnt.begin());
        for(int i = n - 1; i >= 0; i--)
            pos[--cnt[c[pos_t[i]]]] = pos_t[i];
        
        c_t[pos[0]] = 0;
        for(int i = 1; i < n; i++)
            c_t[pos[i]] = c_t[pos[i - 1]] + (c[pos[i]] != c[pos[i - 1]] || c[(pos[i] + l) % n] != c[(pos[i - 1] + l) % n]);
        swap(c, c_t);
    }
    return pos;
}

pair<vector<int>, vector<int>> get_lcp(const string & s) {
    int n = s.size();
    vector<int> pos = suffix_array(s);
    vector<int> lcp(n), rank(n);
    for(int i = 0; i < n; i++)
        rank[pos[i]] = i;
    int k = 0;
    for(int i = 0; i < n; i++) {
        if(rank[i] == n - 1)
            k = 0;
        int j = pos[(rank[i] + 1) % n];
        for(; i + k < n && j + k < n && s[i + k] == s[j + k]; k++);
        lcp[rank[i]] = k;
        if(k) k--;
        // if(rank[i] == n - 1) k = 0;
    }
    return {pos, lcp};
}


int main(int argc, char * argv[]) {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    if(argc > 1 && !strcmp(argv[1], debug.debug)) debug.on = true;


	int n;
	string s;
    cin >> n;
    cin >> s;
	s += 'a' - 1;
	n++;

    auto pos_lcp = get_lcp(s);
    auto pos = pos_lcp.first;
    auto lcp = pos_lcp.second;
    // print(pos);
    // print(lcp);
    int res = 0;
    for(int i = 0; i < n - 1; i++) {
    	int tmp = lcp[i];
    	for(int j = i; j < n - 1; j++) {
    		tmp = min(tmp, lcp[j]);
    		res = max(res, min(tmp, abs(pos[i] - pos[j + 1])));
    	}
    }
    cout << res << endl;


    return 0;
}






















Measured memory_bytes: 384