#pragma GCC optimize ("Ofast")
#include<bits/stdc++.h>
using namespace std;
void * wmem;
char memarr[ 96000000 ] ;
template < class T> inline void walloc1d( T ** arr, int x, void ** mem = & wmem) {
static int skip[ 16 ] = { 0 , 15 , 14 , 13 , 12 , 11 , 10 , 9 , 8 , 7 , 6 , 5 , 4 , 3 , 2 , 1 } ;
( * mem) = ( void * ) ( ( ( char * ) ( * mem) ) + skip[ ( ( unsigned long long ) ( * mem) ) & 15 ] ) ;
( * arr) = ( T* ) ( * mem) ;
( * mem) = ( ( * arr) + x) ;
}
template < class S, class T> inline S chmin( S & a, T b) {
if ( a> b) {
a= b;
}
return a;
}
template < class T> void SuffixArray( T * s, int N, int K, int * SA, int * LCP = NULL , void * mem = wmem) {
int i;
int j;
int d;
int m;
int * s1;
int name;
int prev;
int pos;
char * t;
char * lms;
int * cnt;
int * cnt1;
int * cnt2;
walloc1d( & t, N+ 1 , & mem) ;
walloc1d( & lms, N+ 1 , & mem) ;
walloc1d( & cnt, K+ 1 , & mem) ;
walloc1d( & cnt1, K+ 1 , & mem) ;
walloc1d( & cnt2, K+ 1 , & mem) ;
N++ ;
s[ N- 1 ] = 0 ;
t[ N- 1 ] = 1 ;
t[ N- 2 ] = 0 ;
for ( i= N- 3 ; i>= 0 ; i-- ) {
if ( s[ i] < s[ i+ 1 ] || ( s[ i] == s[ i+ 1 ] && t[ i+ 1 ] ) ) {
t[ i] = 1 ;
}
else {
t[ i] = 0 ;
}
}
lms[ 0 ] = 0 ;
int tU__gIr_ = N;
for ( i= ( 1 ) ; i< ( tU__gIr_) ; i++ ) {
if ( t[ i] && ! t[ i- 1 ] ) {
lms[ i] = 1 ;
}
else {
lms[ i] = 0 ;
}
}
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
cnt1[ i] = 0 ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
cnt1[ s[ i] ] ++ ;
}
j = 0 ;
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
j + = cnt1[ i] ;
cnt2[ i] = j - cnt1[ i] ;
cnt1[ i] = j;
}
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
cnt[ i] = cnt1[ i] ;
}
for ( i= 0 ; i< N; i++ ) {
SA[ i] = - 1 ;
}
for ( i= 1 ; i< N; i++ ) {
if ( lms[ i] ) {
SA[ -- cnt[ s[ i] ] ] = i;
}
}
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
cnt[ i] = cnt2[ i] ;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
j = SA[ i] - 1 ;
if ( j>= 0 && ! t[ j] ) {
SA[ cnt[ s[ j] ] ++ ] = j;
}
}
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
cnt[ i] = cnt1[ i] ;
}
for ( i= N- 1 ; i>= 0 ; i-- ) {
j = SA[ i] - 1 ;
if ( j>= 0 && t[ j] ) {
SA[ -- cnt[ s[ j] ] ] = j;
}
}
m = 0 ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
if ( lms[ SA[ i] ] ) {
SA[ m++ ] = SA[ i] ;
}
}
int H31bcJ8S = N;
for ( i= ( m) ; i< ( H31bcJ8S) ; i++ ) {
SA[ i] = - 1 ;
}
name= 0 ;
prev= - 1 ;
for ( i= ( 0 ) ; i< ( m) ; i++ ) {
pos = SA[ i] ;
for ( d= ( 0 ) ; d< ( N) ; d++ ) {
if ( prev== - 1 || s[ pos+ d] ! = s[ prev+ d] || t[ pos+ d] ! = t[ prev+ d] ) {
name++ ;
prev= pos;
break ;
}
else if ( d> 0 && ( lms[ pos+ d] || lms[ prev+ d] ) ) {
break ;
}
}
pos / = 2 ;
SA[ m+ pos] = name- 1 ;
}
for ( i= N- 1 , j= N- 1 ; i>= m; i-- ) {
if ( SA[ i] >= 0 ) {
SA[ j-- ] = SA[ i] ;
}
}
s1 = SA+ N- m;
if ( name< m) {
SuffixArray( s1, m- 1 , name- 1 , SA, NULL , mem) ;
}
else {
for ( i= 0 ; i< m; i++ ) {
SA[ s1[ i] ] = i;
}
}
for ( i= ( 0 ) ; i< ( K+ 1 ) ; i++ ) {
cnt[ i] = cnt1[ i] ;
}
for ( i= 1 , j= 0 ; i< N; i++ ) {
if ( lms[ i] ) {
s1[ j++ ] = i;
}
}
for ( i= 0 ; i< m; i++ ) {
SA[ i] = s1[ SA[ i] ] ;
}
for ( i= m; i< N; i++ ) {
SA[ i] = - 1 ;
}
for ( i= m- 1 ; i>= 0 ; i-- ) {
j= SA[ i] ;
SA[ i] = - 1 ;
SA[ -- cnt[ s[ j] ] ] = j;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
j = SA[ i] - 1 ;
if ( j>= 0 && ! t[ j] ) {
SA[ cnt2[ s[ j] ] ++ ] = j;
}
}
for ( i= N- 1 ; i>= 0 ; i-- ) {
j = SA[ i] - 1 ;
if ( j>= 0 && t[ j] ) {
SA[ -- cnt1[ s[ j] ] ] = j;
}
}
if ( LCP ! = NULL ) {
cnt = ( int * ) t;
d = 0 ;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
cnt[ SA[ i] ] = i;
}
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
if ( cnt[ i] ) {
for ( j= SA[ cnt[ i] - 1 ] ; j+ d< N- 1 && i+ d< N- 1 && s[ j+ d] == s[ i+ d] ; d++ ) {
;
}
LCP[ cnt[ i] ] = d;
}
else {
LCP[ cnt[ i] ] = - 1 ;
}
if ( d> 0 ) {
d-- ;
}
}
}
}
#define main dummy_main
int main( ) {
wmem = memarr;
return 0 ;
}
#undef main
int A[ 2002 ] ;
int ok[ 2002 ] ;
int SA[ 2002 ] ;
int LCP[ 2002 ] ;
class Solution{
public :
int distinctEchoSubstrings( string str) {
int i;
dummy_main( ) ;
int res = 0 ;
int N = str.size ( ) ;
int k;
int len;
for ( i= ( 0 ) ; i< ( N) ; i++ ) {
A[ i] = str[ i] - 'a' + 1 ;
}
SuffixArray( A,N,128 ,SA,LCP) ;
for ( i= ( 0 ) ; i< ( N+ 1 ) ; i++ ) {
ok[ i] = 0 ;
}
for ( i= ( 1 ) ; i< ( N+ 1 ) ; i++ ) {
int j;
for ( j= ( LCP[ i] + 1 ) ; j< ( N+ 1 ) ; j++ ) {
ok[ j] = 1 ;
}
len = 1073709056 ;
for ( j= ( i+ 1 ) ; j< ( N+ 1 ) ; j++ ) {
chmin( len, LCP[ j] ) ;
k = abs ( SA[ i] - SA[ j] ) ;
if ( k <= len) {
res + = ok[ k] ;
ok[ k] = 0 ;
}
}
}
return res;
}
}
;
// cLay varsion 20200112-1
// --- original code ---
// #define main dummy_main
// {}
// #undef main
//
// int A[2002];
// int ok[2002];
// int SA[2002], LCP[2002];
//
// class Solution {
// public:
// int distinctEchoSubstrings(string str) {
// dummy_main();
//
// int res = 0;
// int N = str.size();
// int k, len;
//
// rep(i,N) A[i] = str[i]-'a'+1;
// SuffixArray(A,N,128,SA,LCP);
//
// rep(i,N+1) ok[i] = 0;
// rep(i,1,N+1){
// rep(j,LCP[i]+1,N+1) ok[j] = 1;
// len = int_inf;
// rep(j,i+1,N+1){
// len <?= LCP[j];
// k = abs(SA[i]-SA[j]);
// if(k <= len) res += ok[k], ok[k] = 0;
// }
// }
//
// return res;
// }
// };
I3ByYWdtYSBHQ0Mgb3B0aW1pemUgKCJPZmFzdCIpCiNpbmNsdWRlPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CnZvaWQgKndtZW07CmNoYXIgbWVtYXJyWzk2MDAwMDAwXTsKdGVtcGxhdGU8Y2xhc3MgVD4gaW5saW5lIHZvaWQgd2FsbG9jMWQoVCAqKmFyciwgaW50IHgsIHZvaWQgKiptZW0gPSAmd21lbSl7CiAgc3RhdGljIGludCBza2lwWzE2XSA9IHswLCAxNSwgMTQsIDEzLCAxMiwgMTEsIDEwLCA5LCA4LCA3LCA2LCA1LCA0LCAzLCAyLCAxfTsKICAoKm1lbSkgPSAodm9pZCopKCAoKGNoYXIqKSgqbWVtKSkgKyBza2lwWygodW5zaWduZWQgbG9uZyBsb25nKSgqbWVtKSkgJiAxNV0gKTsKICAoKmFycik9KFQqKSgqbWVtKTsKICAoKm1lbSk9KCgqYXJyKSt4KTsKfQp0ZW1wbGF0ZTxjbGFzcyBTLCBjbGFzcyBUPiBpbmxpbmUgUyBjaG1pbihTICZhLCBUIGIpewogIGlmKGE+Yil7CiAgICBhPWI7CiAgfQogIHJldHVybiBhOwp9CnRlbXBsYXRlPGNsYXNzIFQ+IHZvaWQgU3VmZml4QXJyYXkoVCAqcywgaW50IE4sIGludCBLLCBpbnQgKlNBLCBpbnQgKkxDUCA9IE5VTEwsIHZvaWQgKm1lbSA9IHdtZW0pewogIGludCBpOwogIGludCBqOwogIGludCBkOwogIGludCBtOwogIGludCAqczE7CiAgaW50IG5hbWU7CiAgaW50IHByZXY7CiAgaW50IHBvczsKICBjaGFyICp0OwogIGNoYXIgKmxtczsKICBpbnQgKmNudDsKICBpbnQgKmNudDE7CiAgaW50ICpjbnQyOwogIHdhbGxvYzFkKCZ0LCBOKzEsICZtZW0pOwogIHdhbGxvYzFkKCZsbXMsIE4rMSwgJm1lbSk7CiAgd2FsbG9jMWQoJmNudCwgSysxLCAmbWVtKTsKICB3YWxsb2MxZCgmY250MSwgSysxLCAmbWVtKTsKICB3YWxsb2MxZCgmY250MiwgSysxLCAmbWVtKTsKICBOKys7CiAgc1tOLTFdID0gMDsKICB0W04tMV0gPSAxOwogIHRbTi0yXSA9IDA7CiAgZm9yKGk9Ti0zO2k+PTA7aS0tKXsKICAgIGlmKHNbaV0gPCBzW2krMV0gfHwgKHNbaV09PXNbaSsxXSAmJiB0W2krMV0pKXsKICAgICAgdFtpXSA9IDE7CiAgICB9CiAgICBlbHNlewogICAgICB0W2ldID0gMDsKICAgIH0KICB9CiAgbG1zWzBdID0gMDsKICBpbnQgdFVfX2dJcl8gPSBOOwogIGZvcihpPSgxKTtpPCh0VV9fZ0lyXyk7aSsrKXsKICAgIGlmKHRbaV0gJiYgIXRbaS0xXSl7CiAgICAgIGxtc1tpXSA9IDE7CiAgICB9CiAgICBlbHNlewogICAgICBsbXNbaV0gPSAwOwogICAgfQogIH0KICBmb3IoaT0oMCk7aTwoSysxKTtpKyspewogICAgY250MVtpXSA9IDA7CiAgfQogIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgY250MVtzW2ldXSsrOwogIH0KICBqID0gMDsKICBmb3IoaT0oMCk7aTwoSysxKTtpKyspewogICAgaiArPSBjbnQxW2ldOwogICAgY250MltpXSA9IGogLSBjbnQxW2ldOwogICAgY250MVtpXSA9IGo7CiAgfQogIGZvcihpPSgwKTtpPChLKzEpO2krKyl7CiAgICBjbnRbaV0gPSBjbnQxW2ldOwogIH0KICBmb3IoaT0wOyBpPE47IGkrKyl7CiAgICBTQVtpXSA9IC0xOwogIH0KICBmb3IoaT0xOyBpPE47IGkrKyl7CiAgICBpZihsbXNbaV0pewogICAgICBTQVstLWNudFtzW2ldXV09aTsKICAgIH0KICB9CiAgZm9yKGk9KDApO2k8KEsrMSk7aSsrKXsKICAgIGNudFtpXSA9IGNudDJbaV07CiAgfQogIGZvcihpPSgwKTtpPChOKTtpKyspewogICAgaiA9IFNBW2ldLTE7CiAgICBpZihqPj0wICYmICF0W2pdKXsKICAgICAgU0FbY250W3Nbal1dKytdID0gajsKICAgIH0KICB9CiAgZm9yKGk9KDApO2k8KEsrMSk7aSsrKXsKICAgIGNudFtpXSA9IGNudDFbaV07CiAgfQogIGZvcihpPU4tMTtpPj0wO2ktLSl7CiAgICBqID0gU0FbaV0gLSAxOwogICAgaWYoaj49MCAmJiB0W2pdKXsKICAgICAgU0FbLS1jbnRbc1tqXV1dID0gajsKICAgIH0KICB9CiAgbSA9IDA7CiAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICBpZihsbXNbU0FbaV1dKXsKICAgICAgU0FbbSsrXSA9IFNBW2ldOwogICAgfQogIH0KICBpbnQgSDMxYmNKOFMgPSBOOwogIGZvcihpPShtKTtpPChIMzFiY0o4Uyk7aSsrKXsKICAgIFNBW2ldID0gLTE7CiAgfQogIG5hbWU9MDsKICBwcmV2PS0xOwogIGZvcihpPSgwKTtpPChtKTtpKyspewogICAgcG9zID0gU0FbaV07CiAgICBmb3IoZD0oMCk7ZDwoTik7ZCsrKXsKICAgICAgaWYocHJldj09LTEgfHwgc1twb3MrZF0hPXNbcHJlditkXSB8fCB0W3BvcytkXSE9dFtwcmV2K2RdKXsKICAgICAgICBuYW1lKys7CiAgICAgICAgcHJldj1wb3M7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgICAgZWxzZSBpZihkPjAgJiYgKGxtc1twb3MrZF0gfHwgbG1zW3ByZXYrZF0pKXsKICAgICAgICBicmVhazsKICAgICAgfQogICAgfQogICAgcG9zIC89IDI7CiAgICBTQVttK3Bvc109bmFtZS0xOwogIH0KICBmb3IoaT1OLTEsIGo9Ti0xOyBpPj1tOyBpLS0pewogICAgaWYoU0FbaV0+PTApewogICAgICBTQVtqLS1dPVNBW2ldOwogICAgfQogIH0KICBzMSA9IFNBK04tbTsKICBpZihuYW1lPG0pewogICAgU3VmZml4QXJyYXkoczEsIG0tMSwgbmFtZS0xLCBTQSwgTlVMTCwgbWVtKTsKICB9CiAgZWxzZXsKICAgIGZvcihpPTA7IGk8bTsgaSsrKXsKICAgICAgU0FbczFbaV1dID0gaTsKICAgIH0KICB9CiAgZm9yKGk9KDApO2k8KEsrMSk7aSsrKXsKICAgIGNudFtpXSA9IGNudDFbaV07CiAgfQogIGZvcihpPTEsIGo9MDsgaTxOOyBpKyspewogICAgaWYobG1zW2ldKXsKICAgICAgczFbaisrXT1pOwogICAgfQogIH0KICBmb3IoaT0wOyBpPG07IGkrKyl7CiAgICBTQVtpXT1zMVtTQVtpXV07CiAgfQogIGZvcihpPW07IGk8TjsgaSsrKXsKICAgIFNBW2ldPS0xOwogIH0KICBmb3IoaT1tLTE7IGk+PTA7IGktLSl7CiAgICBqPVNBW2ldOwogICAgU0FbaV09LTE7CiAgICBTQVstLWNudFtzW2pdXV09ajsKICB9CiAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICBqID0gU0FbaV0tMTsKICAgIGlmKGo+PTAgJiYgIXRbal0pewogICAgICBTQVtjbnQyW3Nbal1dKytdID0gajsKICAgIH0KICB9CiAgZm9yKGk9Ti0xO2k+PTA7aS0tKXsKICAgIGogPSBTQVtpXSAtIDE7CiAgICBpZihqPj0wICYmIHRbal0pewogICAgICBTQVstLWNudDFbc1tqXV1dID0gajsKICAgIH0KICB9CiAgaWYoTENQICE9IE5VTEwpewogICAgY250ID0gKGludCopdDsKICAgIGQgPSAwOwogICAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICAgIGNudFtTQVtpXV0gPSBpOwogICAgfQogICAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICAgIGlmKGNudFtpXSl7CiAgICAgICAgZm9yKGo9U0FbY250W2ldLTFdOyBqK2Q8Ti0xJiZpK2Q8Ti0xJiZzW2orZF09PXNbaStkXTtkKyspewogICAgICAgICAgOwogICAgICAgIH0KICAgICAgICBMQ1BbY250W2ldXT1kOwogICAgICB9CiAgICAgIGVsc2V7CiAgICAgICAgTENQW2NudFtpXV0gPSAtMTsKICAgICAgfQogICAgICBpZihkPjApewogICAgICAgIGQtLTsKICAgICAgfQogICAgfQogIH0KfQojZGVmaW5lIG1haW4gZHVtbXlfbWFpbgppbnQgbWFpbigpewogIHdtZW0gPSBtZW1hcnI7CiAgcmV0dXJuIDA7Cn0KI3VuZGVmIG1haW4KaW50IEFbMjAwMl07CmludCBva1syMDAyXTsKaW50IFNBWzIwMDJdOwppbnQgTENQWzIwMDJdOwpjbGFzcyBTb2x1dGlvbnsKICBwdWJsaWM6CiAgaW50IGRpc3RpbmN0RWNob1N1YnN0cmluZ3Moc3RyaW5nIHN0cil7CiAgICBpbnQgaTsKICAgIGR1bW15X21haW4oKTsKICAgIGludCByZXMgPSAwOwogICAgaW50IE4gPSBzdHIuc2l6ZSgpOwogICAgaW50IGs7CiAgICBpbnQgbGVuOwogICAgZm9yKGk9KDApO2k8KE4pO2krKyl7CiAgICAgIEFbaV0gPSBzdHJbaV0tJ2EnKzE7CiAgICB9CiAgICBTdWZmaXhBcnJheShBLE4sMTI4LFNBLExDUCk7CiAgICBmb3IoaT0oMCk7aTwoTisxKTtpKyspewogICAgICBva1tpXSA9IDA7CiAgICB9CiAgICBmb3IoaT0oMSk7aTwoTisxKTtpKyspewogICAgICBpbnQgajsKICAgICAgZm9yKGo9KExDUFtpXSsxKTtqPChOKzEpO2orKyl7CiAgICAgICAgb2tbal0gPSAxOwogICAgICB9CiAgICAgIGxlbiA9IDEwNzM3MDkwNTY7CiAgICAgIGZvcihqPShpKzEpO2o8KE4rMSk7aisrKXsKICAgICAgICBjaG1pbihsZW4sIExDUFtqXSk7CiAgICAgICAgayA9IGFicyhTQVtpXS1TQVtqXSk7CiAgICAgICAgaWYoayA8PSBsZW4pewogICAgICAgICAgcmVzICs9IG9rW2tdOwogICAgICAgICAgb2tba10gPSAwOwogICAgICAgIH0KICAgICAgfQogICAgfQogICAgcmV0dXJuIHJlczsKICB9Cn0KOwovLyBjTGF5IHZhcnNpb24gMjAyMDAxMTItMQoKLy8gLS0tIG9yaWdpbmFsIGNvZGUgLS0tCi8vICNkZWZpbmUgbWFpbiBkdW1teV9tYWluCi8vIHt9Ci8vICN1bmRlZiBtYWluCi8vIAovLyBpbnQgQVsyMDAyXTsKLy8gaW50IG9rWzIwMDJdOwovLyBpbnQgU0FbMjAwMl0sIExDUFsyMDAyXTsKLy8gCi8vIGNsYXNzIFNvbHV0aW9uIHsKLy8gcHVibGljOgovLyAgIGludCBkaXN0aW5jdEVjaG9TdWJzdHJpbmdzKHN0cmluZyBzdHIpIHsKLy8gICAgIGR1bW15X21haW4oKTsKLy8gCi8vICAgICBpbnQgcmVzID0gMDsKLy8gICAgIGludCBOID0gc3RyLnNpemUoKTsKLy8gICAgIGludCBrLCBsZW47Ci8vIAovLyAgICAgcmVwKGksTikgQVtpXSA9IHN0cltpXS0nYScrMTsKLy8gICAgIFN1ZmZpeEFycmF5KEEsTiwxMjgsU0EsTENQKTsKLy8gCi8vICAgICByZXAoaSxOKzEpIG9rW2ldID0gMDsKLy8gICAgIHJlcChpLDEsTisxKXsKLy8gICAgICAgcmVwKGosTENQW2ldKzEsTisxKSBva1tqXSA9IDE7Ci8vICAgICAgIGxlbiA9IGludF9pbmY7Ci8vICAgICAgIHJlcChqLGkrMSxOKzEpewovLyAgICAgICAgIGxlbiA8Pz0gTENQW2pdOwovLyAgICAgICAgIGsgPSBhYnMoU0FbaV0tU0Fbal0pOwovLyAgICAgICAgIGlmKGsgPD0gbGVuKSByZXMgKz0gb2tba10sIG9rW2tdID0gMDsKLy8gICAgICAgfQovLyAgICAgfQovLyAKLy8gICAgIHJldHVybiByZXM7Ci8vICAgfQovLyB9Owo=