#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, j, n) for (ll i = j; i < n; i++)
#define all(x) (x).begin(),(x).end()
#define INF (1000000000000)
#define MOD (1000000007)
#define MAX (500000)
#define pii pair<int, int>

/////////////////////////////////////////////////////////

class XY{
public:
  ll x, y;
  XY() {x = y = 0;}
  XY(ll u, ll v) {x = u; y = v;}
};

class e{
public:
  ll a, b;
  e() {a = b = -1;}
  e(ll u, ll v) {a = u; b = v;}
};

template<typename T1, typename T2>
void chmin(T1 &a, T2 b) {if(a > b) a = b;}
template<typename T1, typename T2>
void chmax(T1 &a, T2 b) {if(a < b) a = b;}

template<typename T1, typename T2>
ll mypow(T1 a, T2 n){
  if(n == 0) return 1;
  if(n == 1) return a;
  if(n % 2) return a * mypow(a, n - 1);
  ll tmp = mypow(a, n / 2);
  return tmp * tmp;
}

template<typename T>
int BS(vector<T> &V, int left, int right, T key){
  int mid = (left + right) / 2;
  if(V[mid] <= key) left = mid;
  else right = mid;
  if(right - mid == 1) return left;
  else return BS(V, left, right, key);
}

ll comb(ll n, ll r){
	ll res = 1;
  rep(i, 0, r){
    res *= n - i;
    res /= i + 1;
  }
  return res;
}

template<typename T>
T euclid(T a, T b){
  if(b == 0) return a;
  else return euclid(b, a % b);
}

vector<ll> fact(MAX, 0), fact_inv(MAX, 0);

ll pow_mod(ll a, ll b){
	ll res = 1;
	while(b > 0){
		if(b & 1) res = res * a % MOD;
		a = a * a % MOD;
		b >>= 1;
	}
	return res;
}

void prepare_comb_mod(ll n){
	fact[0] = 1LL;
	for(ll i = 0; i < n; i++) fact[i+1] = fact[i] * (i + 1) % MOD;
	fact_inv[n] = pow_mod(fact[n], MOD - 2);
	for(ll i = n - 1; i >= 0; i--) fact_inv[i] = fact_inv[i + 1] * (i + 1) % MOD;
}

ll comb_mod(ll n, ll r){
	return (fact[n] * fact_inv[r]) % MOD * fact_inv[n - r] % MOD;
}

/////////////////////////////////////////////////////////

class v3{
public:
  ll a, f, c;
  v3(ll x, ll y, ll z){
      a = x; f = y; c = z;
  };
};

bool check(vector<v3> &vv, ll K, ll x){
  rep(i, 0, vv.size()){
    if(vv[i].c - x < 0) continue;
    if((vv[i].c - x) % vv[i].f == 0) K -= max(0ll, (vv[i].c - x) / vv[i].f);
    else K -= max(0ll, (vv[i].c - x) / vv[i].f + 1);
  }
  if(K >= 0) return true;
  else return false;
}

ll BS(vector<v3> &vv, ll K, ll left, ll right){
  if(right - left == 1) return right;
  ll mid = (left + right) / 2;
  if(check(vv, K, mid)) right = mid;
  else left = mid;
  return BS(vv, K, left, right);
}

void Main() {
  int N; cin >> N;
  string S; cin >> S;
  int res = 0;

  rep(n, 0, N){
    string T = S.substr(n, N - n);
    vector<int> A(N - n, 0);
    A[0] = T.size();
    int i = 1, j = 0;
    while (i < T.size()) {
      while(i + j < T.size() && T[j] == T[i+j]) j++;
      A[i] = j;
      if (j == 0) {i++; continue;}
      int k = 1;
      while (i + k < T.size() && k + A[k] < j) A[i+k] = A[k], k++;
      i += k; j -= k;
    }
    int ma = 0;
    rep(l, 0, T.size()){
      if(A[l] <= l) chmax(ma, A[l]);
    }
    chmax(res, ma);
  }
  cout << res << endl;
}

/////////////////////////////////////////////////////////

int main(){
  cin.tie(nullptr);
  ios_base::sync_with_stdio(false);
  cout << std::fixed << std::setprecision(15);

  Main();
}


Measured memory_bytes: 10112