#include <bits/stdc++.h>
using namespace std;
char Start;
int n, m;
char S[400005], T[400005];
int fa[400005], tr[400005][26], len[400005], rt[400005], pos[400005], tot, last;
vector<int> G[400005];
void ins(int c, bool debug = 0) {
  if (tr[last][c]) {
    int p = last, q = tr[last][c];
    if (len[q] != len[p] + 1) {
      int v = ++tot;
      memcpy(tr[v], tr[q], sizeof tr[q]);
      fa[v] = fa[q], len[v] = len[p] + 1;
      for (; ~p && tr[p][c] == q; p = fa[p]) tr[p][c] = v;
      fa[q] = v;
    }
  } else {
    int u = ++tot, p = last, q;
    len[u] = len[p] + 1;
    for (; ~p && !tr[p][c]; p = fa[p]) tr[p][c] = u;
    if (p == -1)
      fa[u] = 0;
    else if (len[q = tr[p][c]] == len[p] + 1)
      fa[u] = q;
    else {
      int v = ++tot;
      memcpy(tr[v], tr[q], sizeof tr[q]);
      fa[v] = fa[q], len[v] = len[p] + 1;
      for (; ~p && tr[p][c] == q; p = fa[p]) tr[p][c] = v;
      fa[q] = fa[u] = v;
    }
  }
}
int lc[400005 * 30], rc[400005 * 30], mx[400005 * 30], mxp[400005 * 30];
void upd(int u) {
  if (mx[lc[u]] >= mx[rc[u]])
    mx[u] = mx[lc[u]], mxp[u] = mxp[lc[u]];
  else
    mx[u] = mx[rc[u]], mxp[u] = mxp[rc[u]];
}
void ins(int &u, int l, int r, int p) {
  if (!u) u = ++tot, mxp[u] = l;
  if (l == r) return (void)(mx[u]++);
  int m = l + r >> 1;
  p <= m ? ins(lc[u], l, m, p) : ins(rc[u], m + 1, r, p);
  upd(u);
}
void merge(int &u, int l, int r) {
  if (!l || !r) return (void)(u = l + r);
  u = ++tot;
  if (lc[l] || rc[l]) {
    merge(lc[u], lc[l], lc[r]), merge(rc[u], rc[l], rc[r]);
    upd(u);
  } else {
    mx[u] = mx[l] + mx[r], mxp[u] = mxp[l];
  }
}
pair<int, int> qry(int u, int l, int r, int ql, int qr) {
  if (ql > r || l > qr || !u || ql > qr) return make_pair(0, 0x3f3f3f3f);
  if (ql <= l && r <= qr) return make_pair(mx[u], mxp[u]);
  int m = l + r >> 1;
  pair<int, int> r1 = qry(lc[u], l, m, ql, qr),
                 r2 = qry(rc[u], m + 1, r, ql, qr);
  if (r1.first >= r2.first)
    return r1;
  else
    return r2;
}
int f[400005], g[400005], ps[400005];
void dfs(int u) {
  for (int v : G[u]) {
    dfs(v), merge(rt[u], rt[u], rt[v]);
    if (!ps[u]) ps[u] = ps[v];
  }
}
int ans;
void dfs2(int u) {
  ans = max(ans, f[u]);
  for (int v : G[u]) {
    if (!u || qry(rt[g[u]], 1, n, ps[v] - len[v] + len[g[u]], ps[v] - 1).first)
      f[v] = f[u] + 1, g[v] = v;
    else
      f[v] = f[u], g[v] = g[u];
    dfs2(v);
  }
}
char End;
int main() {
  scanf("%d", &n);
  scanf("%s", S + 1);
  fa[0] = -1;
  for (int i = (1), LIM = (n); i <= LIM; i++)
    ins(S[i] - 'a'), last = tr[last][S[i] - 'a'], ps[last] = i;
  for (int i = (1), LIM = (tot); i <= LIM; i++) {
    G[fa[i]].push_back(i);
    if (ps[i]) ins(rt[i], 1, n, ps[i]);
  }
  dfs(0);
  dfs2(0);
  printf("%d\n", ans);
}
