#include <bits/stdc++.h>
using namespace std;
int n, ans;
char ss[200010];
int xds_sz, root[200010 << 1], ls[200010 * 100], rs[200010 * 100],
    cnt[200010 * 100];
inline void Insert(int &u, int l, int r, int v) {
  if (!u) u = ++xds_sz;
  if (l == r) return;
  int mid = (l + r) >> 1;
  if (v <= mid)
    Insert(ls[u], l, mid, v);
  else
    Insert(rs[u], mid + 1, r, v);
}
inline int Merge(int x, int y) {
  if (!x || !y) return x ^ y;
  int t = ++xds_sz;
  ls[t] = Merge(ls[x], ls[y]);
  rs[t] = Merge(rs[x], rs[y]);
  return t;
}
inline bool Get(int u, int l, int r, int L, int R) {
  if (!u) return 0;
  if (L <= l && r <= R) return 1;
  int mid = (l + r) >> 1;
  if (L <= mid && Get(ls[u], l, mid, L, R)) return 1;
  if (mid < R && Get(rs[u], mid + 1, r, L, R)) return 1;
  return 0;
}
struct suffix_automation {
  int sz, last;
  int c[200010];
  int f[200010 << 1];
  int id[200010 << 1];
  int pos[200010 << 1];
  int top[200010 << 1];
  int len[200010 << 1];
  int prt[200010 << 1];
  int ch[200010 << 1][26];
  suffix_automation() { sz = last = 1; }
  inline void insert(int c) {
    int u = last, np = last = ++sz;
    pos[np] = len[np] = len[u] + 1;
    while (u && !ch[u][c]) ch[u][c] = np, u = prt[u];
    if (!u)
      prt[np] = 1;
    else {
      int v = ch[u][c];
      if (len[v] == len[u] + 1)
        prt[np] = v;
      else {
        int nq = ++sz;
        len[nq] = len[u] + 1;
        memcpy(ch[nq], ch[v], sizeof(ch[v]));
        pos[nq] = pos[v], prt[nq] = prt[v];
        prt[np] = prt[v] = nq;
        while (u && ch[u][c] == v) ch[u][c] = nq, u = prt[u];
      }
    }
  }
  inline void calc() {
    for (int i = 1; i <= sz; i++) c[len[i]]++;
    for (int i = 1; i <= n; i++) c[i] += c[i - 1];
    for (int i = sz; i; i--) id[c[len[i]]--] = i;
    for (int i = sz; i > 1; i--)
      root[prt[id[i]]] = Merge(root[prt[id[i]]], root[id[i]]);
    for (int i = 2; i <= sz; i++) {
      int u = id[i], fa = prt[u];
      if (fa == 1) {
        ans = max(ans, f[u] = 1);
        top[u] = u;
        continue;
      }
      if (Get(root[top[fa]], 1, n, pos[u] - len[u] + len[top[fa]], pos[u] - 1))
        f[u] = f[fa] + 1, top[u] = u;
      else
        f[u] = f[fa], top[u] = top[fa];
      ans = max(ans, f[u]);
    }
  }
} sam;
int main() {
  scanf("%d%s", &n, ss + 1);
  for (int i = 1; i <= n; i++)
    sam.insert(ss[i] - 'a'), Insert(root[sam.last], 1, n, i);
  sam.calc();
  printf("%d\n", ans);
  return 0;
}
