constint $n = 200001; constint S = $n * 2; constint $c = 26; constint mod = 1000000007;
inlineintadd(int x, int y){ return (x += y) >= mod ? x - mod : x; } inlinevoidAdd(int &x, int y){ if ((x += y) >= mod) x -= mod; } inlinevoidSub(int &x, int y){ if ((x -= y) < 0) x += mod; }
int n, lst[S], pre[S], tar[S]; #define go(x) for (int b = ::lst[x], v = ::tar[b]; b; v = ::tar[b = ::pre[b]])
namespace sam { int tar[S][$c], len[S], pre[S], too[$n], seq[S]; int sum[S]; set<int> w[S]; int lst = 1, tot = 1; inlineintnode(int l){ len[++tot] = l; return tot; } inlinevoidextend(int c){ int i = lst; lst = node(len[i] + 1); w[lst].insert(len[lst]); while (!tar[i][c]) { tar[i][c] = lst; if (!(i = pre[i])) return (void)(pre[lst] = 1); } constint o = tar[i][c]; if (len[i] + 1 == len[o]) return (void)(pre[lst] = o); constint s = node(len[i] + 1); memcpy(tar[s], tar[o], sizeof(tar[0])); pre[s] = pre[o]; pre[lst] = pre[o] = s; do { tar[i][c] = s; i = pre[i]; } while (i && tar[i][c] == o); } inline qe calc(int x){ return ((qe)x * (x + 1)) >> 1; } inlinevoidmerge(int x, int y){ if (w[x].size() < w[y].size()) { std::swap(w[x], w[y]); std::swap(sum[x], sum[y]); } for (int v : w[y]) { auto iter = w[x].lower_bound(v); assert(iter == w[x].end() || *iter != v); if (w[x].empty()) ; elseif (iter == w[x].end()) Add(sum[x], (qe)(n - v + 1) * (v - *--w[x].end()) % mod); elseif (iter == w[x].begin()) { constint t = *w[x].begin(); Add(sum[x], (qe)(n - t + 1) * (t - v) % mod); } else { constint l = *std::prev(iter), r = *iter; Sub(sum[x], (qe)(n - r + 1) * (r - l) % mod); Add(sum[x], (qe)(n - r + 1) * (r - v) % mod); Add(sum[x], (qe)(n - v + 1) * (v - l) % mod); } w[x].insert(v); } } inlineintsolve(){ for (int i = 1; i <= tot; ++i) ++too[len[i]]; for (int i = 1; i <= n; ++i) too[i] += too[i - 1]; for (int i = 1; i <= tot; ++i) seq[too[len[i]]--] = i; int ans = 0; for (int i = tot; i > 1; --i) { constint x = seq[i]; if (w[x].empty()) continue; constint b = *w[x].begin(), cnt = n - b + 1, l = len[x] - len[pre[x]]; constint rsum = add(sum[x], (qe)cnt * (b - len[x] + 1) % mod); Add(ans, add((qe)rsum * l % mod, (qe)cnt * calc(l - 1) % mod)); merge(pre[x], x); } return ans; } } // namespace sam
intmain(){ char c = cin.read<char>(); while (c != -1 && !isspace(c)) { sam::extend(c - 'a'); c = cin.get(); } n = sam::len[sam::lst]; cout < sam::solve() < endl; }