//http://hihocoder.com/problemset/problem/1445
//后缀自动机模板题
//给定一个串，求本质不同的子串个数
#include<bits/stdc++.h>
const int MAXL = 1000000;
char s[MAXL + 10];
int n = 0, len, st;
int maxlen[2 * MAXL + 10], minlen[2 * MAXL + 10], trans[2 * MAXL + 10][26], slink[2 * MAXL + 10];

int new_state(int _maxlen, int _minlen, int* _trans, int _slink) {
        maxlen[n] = _maxlen;
        minlen[n] = _minlen;
        for(int i = 0; i < 26; i++) {
                if(_trans == NULL)
                        trans[n][i] = -1;
                else
                        trans[n][i] = _trans[i];
        }
        slink[n] = _slink;
        return n++;
}

int add_char(char ch, int u) {
        int c = ch - 'a';
        int z = new_state(maxlen[u] + 1, -1, NULL, -1);
        int v = u;
        while(v != -1 && trans[v][c] == -1) {
                trans[v][c] = z;
                v = slink[v];
        }
        if(v == -1) { //最简单的情况，suffix-path(u->S)上都没有对应字符ch的转移
                minlen[z] = 1;
                slink[z] = 0;
                return z;
        }
        int x = trans[v][c];
        if(maxlen[v] + 1 == maxlen[x]) { //较简单的情况，不用拆分x
                minlen[z] = maxlen[x] + 1;
                slink[z] = x;
                return z;
        }
        int y = new_state(maxlen[v] + 1, -1, trans[x], slink[x]); //最复杂的情况，拆分x
        slink[y] = slink[x];
        minlen[x] = maxlen[y] + 1;
        slink[x] = y;
        minlen[z] = maxlen[y] + 1;
        slink[z] = y;
        int w = v;
        while(w != -1 && trans[w][c] == x) {
                trans[w][c] = y;
                w = slink[w];
        }
        minlen[y] = maxlen[slink[y]] + 1;
        return z;
}

int main()
{
	scanf("%s",s+1);
	len=strlen(s+1);
	st=new_state(0,0,NULL,-1);
	for(int i=1;i<=len;i++)
	{
		st=add_char(s[i],st);
	}
	long long ans=0;
	for(int i=1;i<n;i++)
	{
		ans+=maxlen[i]-minlen[i]+1;
	}
	printf("%lld\n",ans);
	return 0;
}