#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);
}