#include <bits/stdc++.h>
using namespace std;
inline int IN() {
  char c;
  register int first = 0;
  for (; (c = getchar()) < 48 && c ^ '-' || c > 57;)
    ;
  bool f = c == '-';
  if (f) (c = getchar());
  for (; c > 47 && c < 58; (c = getchar()))
    first = (first << 3) + (first << 1) + c - 48;
  if (f) first = -first;
  return first;
}
inline void glance() { freopen("ha.in", "r", stdin); }
int root, last, node, n, ans, L, R, seg_node, go[400010][26];
vector<int> li[400010];
typedef int Arr[400010];
Arr len, par, dp, rt, sky, sad;
int l[8000000], r[8000000];
inline void init() { node = root = last = 1; }
inline void append(int w) {
  int p = last, u = ++node;
  len[u] = len[p] + 1;
  sad[u] = 1;
  sky[u] = len[u];
  for (; p && !go[p][w]; p = par[p]) go[p][w] = u;
  if (!p)
    par[u] = root;
  else {
    int t = go[p][w];
    if (len[t] == len[p] + 1)
      par[u] = t;
    else {
      int nt = ++node;
      for (int _r = 26, i = 0; i < _r; ++i) go[nt][i] = go[t][i];
      len[nt] = len[p] + 1;
      par[nt] = par[t];
      par[t] = par[u] = nt;
      sky[nt] = len[u];
      for (; p && go[p][w] == t; p = par[p]) go[p][w] = nt;
    }
  }
  last = u;
}
int Merge(int u, int v) {
  if (!u || !v) return u + v;
  int first = ++seg_node;
  l[first] = Merge(l[u], l[v]);
  r[first] = Merge(r[u], r[v]);
  return first;
}
void ins(int v, int &u, int ll, int rr, int pos) {
  u = ++seg_node;
  l[u] = l[v];
  r[u] = r[v];
  if (ll == rr) return;
  int mm = ll + rr >> 1;
  if (pos <= mm)
    ins(l[v], l[u], ll, mm, pos);
  else
    ins(r[v], r[u], mm + 1, rr, pos);
}
bool Qs(int u, int ll, int rr) {
  if (!u) return 0;
  if (L <= ll && rr <= R) return 1;
  int mm = ll + rr >> 1;
  bool res = 0;
  if (L <= mm) res = Qs(l[u], ll, mm);
  if (R > mm) res = res || Qs(r[u], mm + 1, rr);
  return res;
}
void dfs(int u) {
  for (int v : li[u]) dfs(v), rt[u] = Merge(rt[u], rt[v]);
  if (sad[u]) ins(rt[u], rt[u], 1, n, sky[u]);
}
void DFS(int u, int jc) {
  for (int v : li[u]) {
    if (u == root) {
      dp[v] = 1;
      DFS(v, v);
    } else {
      L = sky[v] - len[v] + len[jc];
      R = sky[v] - 1;
      if (L <= R && Qs(rt[jc], 1, n))
        ans = max(ans, dp[v] = dp[jc] + 1), DFS(v, v);
      else
        DFS(v, jc);
    }
  }
}
int main() {
  n = IN();
  init();
  for (char c; isalpha((c = getchar()));) append(c - 'a');
  for (int _r = node, i = 2; i <= _r; ++i) li[par[i]].push_back(i);
  dfs(root);
  ans = 1;
  DFS(root, 0);
  printf("%d\n", ans);
}
