#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <iomanip>
#include <utility>
#include <tuple>
#include <functional>
#include <bitset>
#include <cassert>
#include <complex>
#include <stdio.h>
#include <time.h>
#include <numeric>
#include <random>
#include <unordered_map>
#include <unordered_set>
#define all(a) a.begin(),a.end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define pb push_back
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> P;
typedef complex<ld> com;
constexpr int inf = 1000000000;
constexpr ll INF = 1000000000000000000;
constexpr ld EPS = 1e-12;
constexpr ld PI = 3.141592653589793238;
template<class T, class U> inline bool chmax(T &a, const U &b) { if (a < b) { a = b; return true; } return false; }
template<class T, class U> inline bool chmin(T &a, const U &b) { if (a > b) { a = b; return true; } return false; }

template<class T> class rollinghash {
	const ull mask30 = (1LL << 30) - 1;
	const ull mask31 = (1LL << 31) - 1;
	const ull mod61 = (1LL << 61) - 1;
	vector<ull> base;
	vector<vector<ull>> hashvalue, basepower;
	int length, basesize;
	ull multiply(ull a, ull b) {
		ull au = a >> 31; ull ad = a & mask31;
		ull bu = b >> 31; ull bd = b & mask31;
		ull mid = ad * bu + au * bd;
		ull midu = mid >> 30; ull midd = mid & mask30;
		return au * bu * 2 + midu + (midd << 31) + ad * bd;
	}
	ull modulo(ull a) {
		ull au = a >> 61; ull ad = a & mod61;
		ull res = au + ad; if (res >= mod61) res -= mod61;
		return res;
	}
public:
	rollinghash(T s) {
		length = s.size();
		base = { 200001,200004,200015 };
		basesize = base.size();
		hashvalue = vector<vector<ull>>(length + 1, vector<ull>(basesize));
		for (int j = 0; j < basesize; j++) {
			for (int i = 0; i < length; i++) {
				hashvalue[i + 1][j] = modulo(multiply(hashvalue[i][j], base[j]) + s[i]);
			}
		}
		basepower = vector<vector<ull>>(length + 1, vector<ull>(basesize));
		for (int j = 0; j < basesize; j++) {
			basepower[0][j] = 1;
			for (int i = 1; i <= length; i++) {
				basepower[i][j] = modulo(multiply(basepower[i - 1][j], base[j]));
			}
		}
	}
	ull hash(ll l, ll r, ll i) {
		assert(l < r && 0 <= l && l < length && 0 < r && r <= length);
		return modulo(hashvalue[r][i] + mod61 * 3 - multiply(hashvalue[l][i], basepower[r - l][i]));
	}
};

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(20);

	int n;
	cin >> n;
	string s;
	cin >> s;
	rollinghash<string> rol(s);
	int ans = 0;
	rep(i, n) {
		for (int j = i + 1; j < n; j++) {
			bool con = false;
			rep(k, 3) {
				if (j + ans > n || ans != 0 && rol.hash(i, i + ans, k) != rol.hash(j, j + ans, k)) con = true;
			}
			if (con) continue;
			int ok = ans, ng = j - i + 1;
			while (ng - ok > 1) {
				int mid = (ok + ng) / 2;
				bool flag = true;
				rep(k, 3) {
					if (j + mid > n || rol.hash(i, i + mid, k) != rol.hash(j, j + mid, k)) flag = false;
				}
				if (flag) ok = mid;
				else ng = mid;
			}
			chmax(ans, ok);
		}
	}
	cout << ans << '\n';
}

Measured memory_bytes: 768