#include <cstdio>
#include <cstring>
#include <cassert>
#define forn(i, n) for (int i = 0; i < (int)(n); i++)
const int N = (int)1e5;
const int VN = N * 2;
struct Edge {
int start, len, to;
};
char s[N + 1];
int sn, vn = 1, ans;
Edge next[VN][26];
int newV() { assert(vn < VN); return vn++; }
int v = 0, shift = 0, ch = 0;
void down( int i, int len ) {
v = 0, shift = 0;
len -= i;
while (len > 0) {
Edge &r = next[v][s[i] - 'a'];
if (r.len > len)
shift = len, ch = s[i] - 'a', len = 0;
else
len -= r.len, i += r.len, v = r.to;
}
}
int main()
{
gets(s), sn = strlen(s), assert(sn <= N);
int i = 0, len = 0;
while (i < sn && len < sn) {
int good = 0, new_c = s[len] - 'a';
while (!good && i <= len) {
Edge &r = next[v][ch];
if (shift && r.len == shift)
v = r.to, shift = 0;
if (shift == 0) {
Edge &r = next[v][new_c];
if (!r.len) {
r = Edge {len, sn - len, newV()};
ans += sn - len;
i++, down(i, len);
} else {
good = 1;
ch = new_c, shift = 1;
}
} else {
if (s[r.start + shift] - 'a' != new_c) {
int q = newV();
int old_c = s[r.start + shift] - 'a';
next[q][new_c] = Edge {len, sn - len, newV()};
ans += sn - len;
next[q][old_c] = Edge {r.start + shift, r.len - shift, r.to};
r.len = shift, r.to = q;
i++, down(i, len);
} else {
good = 1;
shift++;
}
}
}
len++;
}
printf("%d\n", ans);
}