text: import sys
  import typing
  
  import numba as nb
  import numpy as np
  
  
  @nb.njit((nb.i8[:], ))
  def sa_is(
    a: np.ndarray,
  ) -> np.ndarray:
    if a.min() <= 0: a += 1
    assert (a > 0).all()
    a = np.hstack((a, np.array([0])))
    n = a.size
  
    def _preprocess():
      n = a.size
      is_s = np.ones(n, np.bool8)
      for i in range(n - 1, 0, -1):
        is_s[i - 1] = (
          is_s[i] if a[i - 1] == a[i] else
          a[i - 1] < a[i]
        )
      is_lms = np.zeros(n, np.bool8)
      # is_lms[np.arange(1, n)[~is_s[:-1] & is_s[1:]]] = True
      for i in range(1, n): is_lms[i] = is_s[i] & ~is_s[i - 1]
      lms = np.flatnonzero(is_lms)
      bucket = np.zeros(a.max() + 1, np.int32)
      for x in a: bucket[x] += 1
      return is_s, is_lms, lms, bucket
  
    is_s, is_lms, lms, bucket = _preprocess()
  
    def _induce():
      sa = np.full(n, -1, np.int64)
  
      def _set_lms():
        sa_idx = bucket.cumsum()
        for i in lms[::-1]:
          x = a[i]
          sa_idx[x] -= 1
          sa[sa_idx[x]] = i
  
      def _induce_l():
        sa_idx = bucket.copy()
        s = 0
        for i in range(bucket.size):
          s, sa_idx[i] = s + sa_idx[i], s
        for i in range(n):
          i = sa[i] - 1
          if i < 0 or is_s[i]: continue
          x = a[i]
          sa[sa_idx[x]] = i
          sa_idx[x] += 1
  
      def _induce_s():
        sa_idx = bucket.cumsum()
        for i in range(n - 1, -1, -1):
          i = sa[i] - 1
          if i < 0 or not is_s[i]: continue
          x = a[i]
          sa_idx[x] -= 1
          sa[sa_idx[x]] = i
  
      _set_lms()
      _induce_l()
      _induce_s()
      return sa
  
    sa = _induce()
  
    def _correct_lms_order():
      n = a.size
      lms_idx = sa[is_lms[sa]]
      l = lms_idx.size
      na = np.full(n, -1, dtype=np.int64)
      na[-1] = i = 1
      for j in range(l - 1):
        j, k = lms_idx[j], lms_idx[j + 1]
        for d in range(n):
          j_is_lms = is_lms[j + d]
          k_is_lms = is_lms[k + d]
          if a[j + d] != a[k + d] or j_is_lms ^ k_is_lms:
            i += 1; break
          if d > 0 and j_is_lms | k_is_lms: break
        na[k] = i
      na = na[na > 0]
      if i == l:
        lms_order = np.empty(l, np.int64)
        for i in range(l):
          lms_order[na[i] - 1] = i
      else:
        lms_order = sa_is(na)
      nonlocal lms
      lms = lms[lms_order]
  
    _correct_lms_order()
    sa = _induce()
    return sa[1:]
  
  
  @nb.njit
  def lcp_kasai(
    a: np.array,
    sa: np.array,
  ) -> np.array:
    n = a.size
    assert n > 0 and sa.size == n
  
    rank = np.argsort(sa)
    h, l = np.empty(n - 1, np.int32), 0
    for i in range(n):
      if l: l -= 1
      r = rank[i]
      if r == n - 1: continue
      j = sa[r + 1]
      while i + l < n and j + l < n:
        if a[i + l] != a[j + l]: break
        l += 1
      h[r] = l
    return h
  
  
  
  @nb.njit(
    (nb.i8[:], ),
    cache=True,
  )
  def solve(
    a: np.ndarray,
  ) -> typing.NoReturn:
    sa = sa_is(a)
    lcp = lcp_kasai(a, sa)
    n = a.size
    s = n * (n + 1) // 2
    print(s - lcp.sum())
  
  
  
  def main() -> typing.NoReturn:
    s = np.frombuffer(
      sys.stdin.buffer.readline().rstrip(),
      dtype='b',
    ).astype(np.int64) - ord('a') + 1
    solve(s)
  
  
  main()
  