func_code_string: #include <bits/stdc++.h>   int n;   char S[300000];   struct edge {     int to, nxt;   } E[500000];   int H[500000], tot;   inline void add_edge(int a, int b) { E[++tot] = (edge){b, H[a]}, H[a] = tot; }   struct SegmentTree {     struct node {       node *L, *R;       node() { L = R = NULL; }     };     node *root;     void insert(node *&now, int l, int r, int k) {       if (!now) now = new node;       if (l == r) return;       int mdl = (l + r) >> 1;       if (k <= mdl)         insert(now->L, l, mdl, k);       else         insert(now->R, mdl + 1, r, k);     }     bool query(node *now, int l, int r, int L, int R) {       if (l > R || r < L || !now) return false;       if (L <= l && r <= R) return true;       int mdl = (l + r) >> 1;       return query(now->L, l, mdl, L, R) | query(now->R, mdl + 1, r, L, R);     }     SegmentTree() { root = NULL; }   };   SegmentTree::node *merge(SegmentTree::node *&A, SegmentTree::node *&B) {     if (!(A && B)) return A ? A : B;     SegmentTree::node *nw = new SegmentTree::node;     nw->L = merge(A->L, B->L), nw->R = merge(A->R, B->R);     return nw;   }   struct SAM {     struct node {       int son[26], len, link, R;       SegmentTree S;       node() {         memset(son, 0xff, sizeof(int) * 26);         len = link = R = 0;       }     } T[500000];     int tot, lst;     void insert(char C) {       C -=  a ;       int q = ++tot, p = lst;       T[q].len = T[p].len + 1,       T[q].S.insert(T[q].S.root, 1, n, T[q].R = T[q].len);       lst = q;       while (~p && !~T[p].son[C]) T[p].son[C] = q, p = T[p].link;       if (!~p) return;       int np = T[p].son[C];       if (T[p].len + 1 == T[np].len)         T[q].link = np;       else {         int nq = ++tot;         memcpy(T[nq].son, T[np].son, sizeof(int) * 26);         T[nq].link = T[np].link;         T[nq].len = T[p].len + 1;         T[np].link = T[q].link = nq;         while (~p && T[p].son[C] == np) T[p].son[C] = nq, p = T[p].link;       }     }     SAM() { tot = lst = 0, T[0].link = -1; }   } G;   void pre(int now) {     for (int i = H[now]; i; i = E[i].nxt) {       pre(E[i].to);       G.T[now].R = std::max(G.T[now].R, G.T[E[i].to].R);       G.T[now].S.root = merge(G.T[now].S.root, G.T[E[i].to].S.root);     }   }   int Ans;   void solve(int now, int ans, int top) {     Ans = std::max(Ans, ans);     for (int i = H[now]; i; i = E[i].nxt) {       if (G.T[top].S.query(G.T[top].S.root, 1, n,                            G.T[E[i].to].R - G.T[E[i].to].len + G.T[top].len,                            G.T[E[i].to].R - 1))         solve(E[i].to, ans + 1, E[i].to);       else         solve(E[i].to, ans, top);     }   }   int main() {     scanf( %d%s , &n, S + 1);     if (n == 1) return puts( 1 ), 0;     for (int i = 1; i <= n; i++) G.insert(S[i]);     for (int i = 1; i <= G.tot; i++) add_edge(G.T[i].link, i);     pre(0), solve(0, 0, 0);     printf( %d n , Ans);   }   