#include <bits/stdc++.h>
using namespace std;
const int MAXN = 400000 + 5;
const int MAXS = 1e7 + 5;
char s[MAXN];
int n;
namespace Seg {
int ch[MAXS][2], cnt;
void ins(int &x, int l, int r, int pos) {
  if (!x) x = ++cnt;
  if (l == r) return;
  int mid = l + r >> 1;
  if (pos <= mid)
    ins(ch[x][0], l, mid, pos);
  else
    ins(ch[x][1], mid + 1, r, pos);
}
bool find(int x, int l, int r, int ql, int qr) {
  if (!x) return 0;
  if (ql <= l && r <= qr) return 1;
  int mid = l + r >> 1;
  if (ql > mid) return find(ch[x][1], mid + 1, r, ql, qr);
  if (qr <= mid) return find(ch[x][0], l, mid, ql, qr);
  return find(ch[x][1], mid + 1, r, ql, qr) || find(ch[x][0], l, mid, ql, qr);
}
int merge(int x, int y, int l, int r) {
  if (!x || !y) return x | y;
  int z = ++cnt;
  if (l == r) return z;
  int mid = l + r >> 1;
  ch[z][0] = merge(ch[x][0], ch[y][0], l, mid);
  ch[z][1] = merge(ch[x][1], ch[y][1], mid + 1, r);
  return z;
}
}  // namespace Seg
namespace SAM {
int ch[MAXN][27], len[MAXN], fail[MAXN], cnt, last, rt[MAXN], pos[MAXN];
void init() { cnt = last = 1; }
void clr() { last = 1; }
void expend(int c, int id) {
  int np = ++cnt, p = last;
  pos[np] = id;
  last = np;
  len[np] = len[p] + 1;
  while (p && !ch[p][c]) ch[p][c] = np, p = fail[p];
  if (!p) {
    fail[np] = 1;
    return;
  }
  int q = ch[p][c];
  if (len[q] == len[p] + 1) {
    fail[np] = q;
    return;
  }
  int nq = ++cnt;
  len[nq] = len[p] + 1;
  fail[nq] = fail[q];
  memcpy(ch[nq], ch[q], sizeof(ch[q]));
  fail[q] = fail[np] = nq;
  while (p && ch[p][c] == q) ch[p][c] = nq, p = fail[p];
  return;
}
vector<int> g[MAXN];
void dfs(int x) {
  for (int i = 0; i < g[x].size(); i++) {
    int v = g[x][i];
    dfs(v);
    pos[x] = pos[v];
    rt[x] = Seg::merge(rt[x], rt[v], 1, n);
  }
}
int f[MAXN], tp[MAXN], ans;
void solve(int x) {
  for (int i = 0; i < g[x].size(); i++) {
    int v = g[x][i];
    if (x == 1)
      f[v] = 1, tp[v] = v;
    else {
      if (Seg::find(rt[tp[x]], 1, n, pos[v] - len[v] + len[tp[x]], pos[v] - 1))
        f[v] = f[x] + 1, tp[v] = v;
      else
        f[v] = f[x], tp[v] = tp[x];
    }
    solve(v);
  }
  ans = max(ans, f[x]);
}
void build() {
  for (int i = 2; i <= cnt; i++) g[fail[i]].push_back(i);
  dfs(1);
  solve(1);
  printf("%d\n", ans);
}
}  // namespace SAM
int main() {
  scanf("%d", &n);
  scanf("%s", s + 1);
  SAM::init();
  for (int i = 1; i <= n; i++)
    SAM::expend(s[i] - 'a', i), Seg::ins(SAM::rt[SAM::last], 1, n, i);
  SAM::build();
  return 0;
}
