#include <bits/stdc++.h>
using namespace std;
const int N = 400400;
int n;
char ss[N];
int ch[N][26], fa[N], len[N], R[N], C[N], f[N], TP[N], ans;
int las = 1, tot = 1, sta[N], top;
void Get(int x, int y) {
  fa[x] = fa[y];
  len[x] = len[y];
  for (int i = 0; i <= 25; i++) ch[x][i] = ch[y][i];
}
void add(int c, int id) {
  int p = las, np = las = ++tot;
  len[np] = len[p] + 1;
  R[id] = np;
  C[np] = id;
  for (; p && !ch[p][c]; p = fa[p]) ch[p][c] = np;
  if (!p)
    fa[np] = 1;
  else {
    int q = ch[p][c];
    if (len[q] == len[p] + 1)
      fa[np] = q;
    else {
      int nq = ++tot;
      Get(nq, q);
      len[nq] = len[p] + 1;
      fa[np] = fa[q] = nq;
      for (; p && ch[p][c] == q; p = fa[p]) ch[p][c] = nq;
    }
  }
}
const int M = N * 20, INF = 1e9;
int sz[M], lc[M], rc[M], T[N], ID, zhi[N], cnt;
int merge(int x, int y) {
  if (!x || !y) return x | y;
  int w = ++cnt;
  lc[w] = merge(lc[x], lc[y]);
  rc[w] = merge(rc[x], rc[y]);
  return w;
}
void change(int &u, int l, int r, int k) {
  if (!u) u = ++cnt;
  if (l == r) return;
  if (k <= ((l + r) / 2))
    change(lc[u], l, ((l + r) / 2), k);
  else
    change(rc[u], ((l + r) / 2) + 1, r, k);
}
int query(int u, int l, int r, int L, int R) {
  if (!u) return 0;
  if (L <= l && r <= R) return u;
  int ans = 0;
  if (L <= ((l + r) / 2)) ans |= query(lc[u], l, ((l + r) / 2), L, R);
  if (((l + r) / 2) < R) ans |= query(rc[u], ((l + r) / 2) + 1, r, L, R);
  return ans;
}
struct pr {
  int next, to;
} a[N];
int head[N], tt;
void ADD(int u, int v) {
  a[++tt] = (pr){head[u], v};
  head[u] = tt;
}
void dfspre(int x) {
  if (C[x]) {
    change(T[x], 1, n, C[x]);
    if (!zhi[x]) zhi[x] = C[x];
  }
  for (int i = head[x]; i; i = a[i].next) {
    int y = a[i].to;
    dfspre(y);
    T[x] = merge(T[x], T[y]);
    if (!zhi[x]) zhi[x] = zhi[y];
  }
}
int Find(int y, int x) {
  int t = zhi[x];
  int l = t - len[x] + 1 + len[fa[y]], r = t - 1;
  if (l > r) return 1;
  return query(T[y], 1, n, l, r) > 0;
}
void dfs(int x) {
  if (x != 1) {
    if (Find(TP[fa[x]], x))
      f[x] = max(f[x], f[fa[x]] + 1), TP[x] = x;
    else
      TP[x] = TP[fa[x]], f[x] = max(f[x], f[fa[x]]);
  }
  ans = max(ans, f[x]);
  for (int i = head[x]; i; i = a[i].next) {
    int y = a[i].to;
    dfs(y);
  }
  top--;
}
int main() {
  cin >> n;
  scanf("%s", ss + 1);
  for (int i = 1; i <= n; i++) add(ss[i] - 'a', i);
  for (int i = 1; i <= tot; i++) ADD(fa[i], i);
  dfspre(1);
  TP[1] = 1;
  dfs(1);
  cout << ans << '\n';
}
