#include <bits/stdc++.h>
using namespace std;
const int N = 200500;
struct Node {
  int len, link;
  bool term;
  map<char, int> go;
  Node() : len(0), link(-1), term(false) {}
};
int n;
char s[N];
Node sa[N];
int sa_size, last;
int cnt[N];
void extend(char c) {
  int cur = sa_size++;
  sa[cur].len = sa[last].len + 1;
  int p = last;
  for (; p != -1 && sa[p].go.count(c) == 0; p = sa[p].link) sa[p].go[c] = cur;
  if (p == -1) {
    sa[cur].link = 0;
  } else {
    int q = sa[p].go[c];
    if (sa[q].len == sa[p].len + 1) {
      sa[cur].link = q;
    } else {
      int clone = sa_size++;
      sa[clone] = sa[q];
      sa[clone].len = sa[p].len + 1;
      sa[q].link = clone;
      for (; p != -1 && sa[p].go[c] == q; p = sa[p].link) sa[p].go[c] = clone;
      sa[cur].link = clone;
    }
  }
  last = cur;
}
void build_suffix_automaton() {
  sa_size = 1;
  for (int i = 0; i < n; i++) extend(s[i]);
}
void mark_terminal() {
  for (int p = last; p != -1; p = sa[p].link) sa[p].term = true;
}
int get_cnt(int v) {
  if (cnt[v] == -1) {
    cnt[v] = (sa[v].term ? 1 : 0);
    for (auto it = sa[v].go.begin(); it != sa[v].go.end(); it++) {
      int to = it->second;
      cnt[v] += get_cnt(to);
    }
  }
  return cnt[v];
}
int main() {
  scanf("%s", s);
  n = strlen(s);
  build_suffix_automaton();
  mark_terminal();
  fill(cnt, cnt + sa_size, -1);
  long long res = 0;
  for (int i = 1; i < sa_size; i++) {
    long long val = (long long)get_cnt(i);
    res += val * (val + 1) / 2 * (sa[i].len - sa[sa[i].link].len);
  }
  printf("%I64d", res);
  return 0;
}
