struct suffix_automaton { string s; int son[maxn][26],pre[maxn],step[maxn],last,total; inline void push_back(int v) { step[++total]=v; } void Extend(char ch) { push_back(step[last]+1); int p=last,np=total; for (;!son[p][ch];p=pre[p]) son[p][ch]=np; if(!p) pre[np]=0; else { int q=son[p][ch]; if(step[q]!=step[p]+1) { push_back(step[p]+1); int nq=total; memcpy(son[nq],son[q],sizeof(son[q])); pre[nq]=pre[q]; pre[q]=pre[np]=nq; for (; son[p][ch]==q; p=pre[p]) son[p][ch]=nq; } else pre[np]=q; } last=np; } void Build() { cin>>s; total=last=0; memset(son,0,sizeof(son)); memset(pre,0,sizeof(pre)); memset(step,0,sizeof(step)); for (int i=0,End=s.size(); i!=End; i++) Extend(s[i]-'A'); visit(0,0); } }suf;