#include <iostream>
#include <sstream>
#include <fstream>
#include <string>
#include <vector>
#include <deque>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <algorithm>
#include <functional>
#include <utility>
#include <bitset>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <cstdio>

using namespace std;

#define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
#define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)

typedef long long ll;

char buf[100010];
string s;
int N;

#define MAXN 100010

int sa[MAXN+10], sainv[MAXN+10], lcp[MAXN+10];
pair <pair <int, int>, int> p[MAXN+10], q[MAXN+10];

void suffix_array(void){
	int i,j,tmp=0;

	REP(i,N) sainv[i] = s[i];

	for(int t=1;t<N;t*=2){
		REP(i,N) p[i] = make_pair(make_pair(sainv[i], ((i+t >= N) ? -1 : sainv[i+t])), i);
		sort(p, p+N);
		int sz = 0;
		REP(i,N){
			if(i > 0 && p[i].first != p[i-1].first) sz++;
			sainv[p[i].second] = sz;
		}
	}

	REP(i,N) sa[sainv[i]] = i;

	REP(i,N) if(sainv[i] != N-1){
		j = sa[sainv[i] + 1];
		while(i+tmp < N && j+tmp < N && s[i+tmp] == s[j+tmp]) tmp++;
		lcp[sainv[i]] = tmp;
		if(tmp > 0) tmp--;
	}
}

#define INF (1<<29)

ll main2(void){
	int i,j,k;
	ll ans = 0;

	set <int> sep;
	sep.insert(0);
	sep.insert(N);

	vector <pair <int, int> > v;
	REP(i,N-1) v.push_back(make_pair(lcp[i], i+1));
	sort(v.begin(),v.end());

	REP(i,v.size()){
		int x = v[i].second;
		ll val = v[i].first;
		sep.insert(x);
		__typeof(sep.begin()) itr = sep.find(x);
		itr--;
		int L = *(itr);
		itr++; itr++;
		int R = *(itr);
		ans += val * (x - L) * (R - x);
	}

	ans = 2 * ans;
	for(i=1;i<=N;i++) ans += i;

	return ans;
}

int main(void){
	int T,t;

	cin >> T;
	REP(t,T){
		scanf("%s", buf);
		s = buf;
		N = s.length();
		suffix_array();
		ll ans = main2();
		cout << ans << endl;
	}

	return 0;
}


#include <iostream>
#include <cstring>

struct StackElement
{
	int t;
	int val;
};

long long int solve();

char string[100001];
int text[100001];
int length;

int main()
{
	std::ios::sync_with_stdio(false);

	int tests;

	std::cin >> tests;

	std::cin.ignore(1, '\n');

	for (int i = 0; i < tests; i++)
	{
		std::cin.getline(string, 100001);
		length = strlen(string) + 1;
		std::cout << solve() << '\n';
	}
}

void convertAscii()
{
	for (int i = 0; i < length; i++)
	{
		if (string[i] == 0) text[i] = 0;
		else text[i] = string[i] - 'a' + 1;
	}
}

int prepareBuckets(int *index, int *start)
{
	int used[27] = {0};

	for (int i = 0; i < length; i++)
		used[text[i]]++;

	int buckets = 0;

	for (int i = 0; i < 27; i++)
		if (used[i])
			buckets++;

	{
		int use = 0;
		int st = 0;

		for (int i = 0; i < length; i++)
		{
			if (used[use] == 0)
			{
				used[use++] = st;
				st = i;
				while (used[use] == 0)
					use++;
			}
			start[i] = st;
			used[use]--;
		}
		used[use++] = st;
	}

	for (int i = 0; i < length; i++)
	{
		index[used[text[i]]] = i;
		used[text[i]]++;
	}

	return buckets;
}

void createSuffixArray(int *index)
{
	int *original = index;
	convertAscii();

	int *data = new int[length * 5];

	int *nindex = data;
	int *start = data + length;
	int *lookup = data + 2 * length;
	int *cause = data + 3 * length;
	int *offset = data + 4 * length;

	int buckets = prepareBuckets(index, start);

	int s = 1;

	while (buckets != length)
	{
		for (int i = 0; i < length; i++)
		{
			lookup[index[i]] = i;
			offset[i] = 0;
		}

		for (int i = 0; i < length; i++)
		{
			int mov = index[i] - s;
			if (mov < 0)
				mov += length;

			int pos = lookup[mov];
			int npos = start[pos] + offset[start[pos]]++;
			nindex[npos] = mov;
			cause[npos] = start[i];
		}

		buckets = 1;

		int lstart = start[0];
		int nstart = 0;

		for (int i = 1; i < length; i++)
		{
			if (start[i] == lstart)
			{
				if (cause[i] != cause[i - 1])
				{
					nstart = i;
					buckets++;
				}
			} else
			{
				nstart = i;
				buckets++;
			}

			lstart = start[i];
			start[i] = nstart;
		}

		int *temp = nindex;
		nindex = index;
		index = temp;

		s <<= 1;
	}

	if (original != index)
		for (int i = 0; i < length; i++)
			original[i] = index[i];

	delete[] data;
}

long long int solve()
{
	int *index = new int[length];

	createSuffixArray(index);

	long long int sum = 0;

	{
		int *lcp = new int[2 * length];
		int *lookup = lcp + length;

		for (int i = 0; i < length; i++)
			lookup[index[i]] = i;

		int k = 0;

		for (int i = 0; i < length; i++)
		{
			if (lookup[i] == length - 1)
			{
				k = 0;
				continue;
			}

			int j = index[lookup[i] + 1];

			while (i + k < length && j + k < length && string[i + k] == string[j + k])
				k++;

			lcp[lookup[i]] = k;

			if (k > 0)
				k--;
		}

		//for (int j = 0; j < length; j++)
		//{
		//	std::cout << string + index[j] << std::endl;
		//}

		StackElement *stack = new StackElement[length - 2];
		int p = 0;

		int current = 0;
		int lastLCP = 0;

		for (int i = 1; i < length - 1; i++)
		{
			int val = lcp[i];
			sum += (length - 1 - index[i]) - (lastLCP > val ? lastLCP : val);

			int dif = val - current;

			while (p > 0 && (dif + stack[p - 1].val) < 0)
			{
				long long int s = (i - stack[p - 1].t + 1);
				sum += stack[p - 1].val * s * s;
				dif += stack[p - 1].val;
				current -= stack[p - 1].val;
				p--;
			}
			int t = i;
			if (dif < 0)
			{
				long long int s = (i - stack[p - 1].t + 1);
				sum += (-dif) * s * s;
				dif += stack[p - 1].val;
				current -= stack[p - 1].val;
				t = stack[p - 1].t;
				p--;
			}
			if (dif > 0)
			{
				stack[p].t = t;
				stack[p].val = dif;
				current += dif;
				p++;
			}

			lastLCP = val;
		}
		sum += (length - 1 - index[length - 1]) - lastLCP;

		while (p > 0)
		{
			long long int s = (length - stack[p - 1].t);
			sum += stack[p - 1].val * s * s;
			p--;
		}

		delete[] lcp;
	}

	delete[] index;

	return sum;
}


#include <iostream>
#include <cstring>

struct StackElement
{
	int t;
	int val;
};

long long int solve();

char string[100001];
int text[100001];
int length;

int main()
{
	std::ios::sync_with_stdio(false);

	int tests;

	std::cin >> tests;

	std::cin.ignore(1, '\n');

	for (int i = 0; i < tests; i++)
	{
		std::cin.getline(string, 100001);
		length = strlen(string) + 1;
		std::cout << solve() << '\n';
	}
}

void convertAscii()
{
	for (int i = 0; i < length; i++)
	{
		if (string[i] == 0) text[i] = 0;
		else text[i] = string[i] - 'a' + 1;
	}
}

int prepareBuckets(int *index, int *start)
{
	int used[27] = {0};

	for (int i = 0; i < length; i++)
		used[text[i]]++;

	int buckets = 0;

	for (int i = 0; i < 27; i++)
		if (used[i])
			buckets++;

	{
		int use = 0;
		int st = 0;

		for (int i = 0; i < length; i++)
		{
			if (used[use] == 0)
			{
				used[use++] = st;
				st = i;
				while (used[use] == 0)
					use++;
			}
			start[i] = st;
			used[use]--;
		}
		used[use++] = st;
	}

	for (int i = 0; i < length; i++)
	{
		index[used[text[i]]] = i;
		used[text[i]]++;
	}

	return buckets;
}

void createSuffixArray(int *index)
{
	int *original = index;
	convertAscii();

	int *data = new int[length * 5];

	int *nindex = data;
	int *start = data + length;
	int *lookup = data + 2 * length;
	int *cause = data + 3 * length;
	int *offset = data + 4 * length;

	int buckets = prepareBuckets(index, start);

	int s = 1;

	while (buckets != length)
	{
		for (int i = 0; i < length; i++)
		{
			lookup[index[i]] = i;
			offset[i] = 0;
		}

		for (int i = 0; i < length; i++)
		{
			int mov = index[i] - s;
			if (mov < 0)
				mov += length;

			int pos = lookup[mov];
			int npos = start[pos] + offset[start[pos]]++;
			nindex[npos] = mov;
			cause[npos] = start[i];
		}

		buckets = 1;

		int lstart = start[0];
		int nstart = 0;

		for (int i = 1; i < length; i++)
		{
			if (start[i] == lstart)
			{
				if (cause[i] != cause[i - 1])
				{
					nstart = i;
					buckets++;
				}
			} else
			{
				nstart = i;
				buckets++;
			}

			lstart = start[i];
			start[i] = nstart;
		}

		int *temp = nindex;
		nindex = index;
		index = temp;

		s <<= 1;
	}

	if (original != index)
		for (int i = 0; i < length; i++)
			original[i] = index[i];

	delete[] data;
}

long long int solve()
{
	int *index = new int[length];

	createSuffixArray(index);

	long long int sum = 0;

	{
		int *lcp = new int[2 * length];
		int *lookup = lcp + length;

		for (int i = 0; i < length; i++)
			lookup[index[i]] = i;

		int k = 0;

		for (int i = 0; i < length; i++)
		{
			if (lookup[i] == length - 1)
			{
				k = 0;
				continue;
			}

			int j = index[lookup[i] + 1];

			while (i + k < length && j + k < length && string[i + k] == string[j + k])
				k++;

			lcp[lookup[i]] = k;

			if (k > 0)
				k--;
		}

		//for (int j = 0; j < length; j++)
		//{
		//	std::cout << string + index[j] << std::endl;
		//}

		StackElement *stack = new StackElement[length - 2];
		int p = 0;

		int current = 0;
		int lastLCP = 0;

		for (int i = 1; i < length - 1; i++)
		{
			int val = lcp[i];
			sum += (length - 1 - index[i]) - (lastLCP > val ? lastLCP : val);

			int dif = val - current;
			lastLCP = val;

			while (p > 0 && (dif + stack[p - 1].val) < 0)
			{
				long long int s = (i - stack[p - 1].t + 1);
				sum += stack[p - 1].val * s * s;
				dif += stack[p - 1].val;
				current -= stack[p - 1].val;
				p--;
			}
			if (dif < 0)
			{
				long long int s = (i - stack[p - 1].t + 1);
				sum += (-dif) * s * s;
				dif += stack[p - 1].val;
				current -= stack[p - 1].val;
				p--;
			}
			if (dif > 0)
			{
				stack[p].t = i;
				stack[p].val = dif;
				current += dif;
				p++;
			}
		}
		sum += (length - 1 - index[length - 1]) - lastLCP;

		while (p > 0)
		{
			long long int s = (length - stack[p - 1].t);
			sum += stack[p - 1].val * s * s;
			p--;
		}

		delete[] lcp;
	}

	delete[] index;

	return sum;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<map>
#define mp make_pair
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;

inline ll read() {
	char ch = getchar(); ll x = 0; int op = 1;
	for(; !isdigit(ch); ch = getchar()) if(ch == '-') op = -1;
	for(; isdigit(ch); ch = getchar()) x = x*10+ch-'0';
	return x*op;
}
inline void write(ll a) {
	if(a < 0) putchar('-'), a = -a;
	if(a >= 10) write(a/10); putchar('0'+a%10);
}

const int N = 100010;
char s[N];
int n, all, top;
int tong[N], rk[N], tp[N], sa[N], h[N], st[N];
ll ans;

inline ll sqr(ll x) { return x*x; }
inline void ssort() {
    for(int i = 0; i <= all; i ++) tong[i] = 0;
    for(int i = 1; i <= n; i ++) tong[rk[tp[i]]] ++;
    for(int i = 1; i <= all; i ++) tong[i] += tong[i-1];
    for(int i = n; i >= 1; i --) sa[tong[rk[tp[i]]] --] = tp[i];
}
inline void get_sa() {
    for(int i = 1; i <= n; i ++) rk[i] = s[i], tp[i] = i;
    all = 127; ssort(); int w = 1; all = 1;
    while(all < n) {
        int t = 0;
        for(int i = n-w+1; i <= n; i ++) tp[++ t] = i;
        for(int i = 1; i <= n; i ++) if(sa[i]>w) tp[++ t] = sa[i]-w;
        ssort(); for(int i = 1; i <= n; i ++) tp[i] = rk[i];
        rk[sa[1]] = all = 1;
        for(int i = 2; i <= n; i ++)
            rk[sa[i]] = (tp[sa[i]] == tp[sa[i-1]] && tp[sa[i]+w] == tp[sa[i-1]+w])?all:++ all;
        w <<= 1;
    } int k = 0;
    for(int i = 1; i <= n; i ++) {
        if(k) k --; int j = sa[rk[i]-1];
        for(; i+k<=n && j+k<=n && s[i+k] == s[j+k]; k ++);
        h[rk[i]] = k;
    }
}
int main() {
	int test = read();
	while(test --) {
		scanf("%s", s+1); n = strlen(s+1);
		get_sa(); ans = 0; h[0] = h[n+1] = 0;
		for(int i = 1; i <= n; i ++) ans += n-sa[i]+1-max(h[i], h[i+1]);
		st[++ top] = 0;
		for(int i = 1; i <= n+1; i ++) {
			if(h[i] > h[st[top]]) { st[++ top] = i; continue; }
			if(h[i] == h[st[top]]) continue;
			while(top && h[i] <= h[st[top-1]]) {
				ans += sqr(i-st[top]+1)*(h[st[top]]-h[st[top-1]]);
				top --;
			}
			ans += sqr(i-st[top]+1)*(h[st[top]]-h[i]);
			h[st[top]] = h[i];
		}
		write(ans); puts("");
	}
	return 0;
}


#include<cstdio>
#include<cstring>
#include<iostream>
#include<stdlib.h>
#include<ctime>
#include<string>
#include<cmath>
#include<algorithm>
#include<complex>
#include<vector>
#include<set>
#include<map>
#include<queue>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define LL long long
#define FOR(i,a,b) for (int i=a;i<=b;++i)
#define FORD(i,a,b) for (int i=a;i>=b;--i)
using namespace std;
typedef pair<int,int> pa;
void getint(int &v){
    char ch,fu=0;
    for(ch='*'; (ch<'0'||ch>'9')&&ch!='-'; ch=getchar());
    if(ch=='-') fu=1, ch=getchar();
    for(v=0; ch>='0'&&ch<='9'; ch=getchar()) v=v*10+ch-'0';
    if(fu) v=-v;
}
LL ans;
const int INF=1e9+10;
int n,m,t[1000010],T,rk[1000010],top,stk[1000010],h[1000010],l[1000010],r[1000010],sa[1000010],tt[1000010];
char s[1000010];
void da(){
	FOR(i,0,m) t[i]=0;
	FOR(i,1,n) t[s[i]-'a'+1]++;
	FOR(i,1,m) t[i]+=t[i-1];
	FOR(i,1,n) sa[t[s[i]-'a'+1]--]=i;
	FOR(i,1,n) rk[sa[i]]=rk[sa[i-1]]+(s[sa[i]]!=s[sa[i-1]]);
	for (int j=1;j<n;j<<=1){
		int p=0;
		FOR(i,n-j+1,n) tt[++p]=i;
		FOR(i,1,n) if (sa[i]>j) tt[++p]=sa[i]-j;
		FOR(i,0,n) t[i]=0;
		FOR(i,1,n) t[rk[i]]++;
		FOR(i,1,n) t[i]+=t[i-1];
		FORD(i,n,1) sa[t[rk[tt[i]]]--]=tt[i];
		FOR(i,1,n){
			int A=sa[i-1],B=sa[i];
			tt[B]=tt[A]+(rk[A]!=rk[B] || rk[A+j]!=rk[B+j]);
		}
		FOR(i,1,n) rk[i]=tt[i];
	}
}
void ht(){
	FOR(i,1,n){
		int A=rk[i],B=rk[i-1],p=sa[rk[i]-1];
		int t=max(h[B]-1,0);
		while (s[i+t]==s[p+t]) t++;
		h[A]=t;
	}
}
int main(){
	scanf("%d",&T);
	while (T--){
		scanf("%s",s+1);
		n=strlen(s+1);
		m=26;
		da();
		ht();
		top=0;
		stk[++top]=0;
		h[0]=-INF;
		FOR(i,1,n){
			while (top>0 && h[i]<h[stk[top]]) top--;
			l[i]=i-stk[top]-1;
			stk[++top]=i;
		}
		top=0;
		stk[++top]=n+1;
		h[n+1]=-INF;
		FORD(i,n,1){
			while (top>0 && h[i]<=h[stk[top]]) top--;
			r[i]=stk[top]-1-i;
			stk[++top]=i;
		}
		ans=(LL)n*(n+1)/2;
		FOR(i,1,n) ans+=(LL)h[i]*(r[i]+1)*(l[i]+1)*2;
		cout<<ans<<endl;
	}
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <list>
#include <cassert>
#include <ctime>
#include <climits>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
typedef unsigned long long ull;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXLEN=100000;

char s[MAXLEN+2]; int n;

typedef struct Node {
	int start,end;
	int childs[27];
	int suffix;
	int nleafs;
	Node(int start,int end):start(start),end(end) { memset(childs,-1,sizeof(childs)); suffix=-1; }
} Node;

vector<Node> nodes;
int addnode(int start,int end) {
	nodes.push_back(Node(start,end));
	return SZ(nodes)-1;
}

int build() {
	int root=addnode(0,0);
	int atnode=root,atedge=0,atlen=0,rem=0,prev=-1;
	for(int i=0;i<n;++i) {
		++rem; prev=-1;
		while(rem>0) {
			int tonode=nodes[atnode].childs[s[atedge]-'a'];
			int tostart=tonode==-1?-1:nodes[tonode].start;
			if(tonode!=-1&&nodes[tonode].start+atlen>=nodes[tonode].end) {
				atedge+=nodes[tonode].end-nodes[tonode].start;
				atlen-=nodes[tonode].end-nodes[tonode].start;
				atnode=tonode;
				continue;
			}
			if(tonode==-1) { //atlen should be 0
				int leaf=addnode(i,n);
				nodes[atnode].childs[s[atedge]-'a']=leaf;
				if(prev!=-1) nodes[prev].suffix=atnode; prev=atnode;
			} else if(s[tostart+atlen]==s[i]) {
				++atlen;
				if(prev!=-1) nodes[prev].suffix=atnode; prev=atnode;
				break;
			} else {
				int branch=addnode(tostart,tostart+atlen);
				nodes[tonode].start+=atlen;
				int leaf=addnode(i,n);
				nodes[atnode].childs[s[atedge]-'a']=branch;
				nodes[branch].childs[s[tostart+atlen]-'a']=tonode;
				nodes[branch].childs[s[i]-'a']=leaf;
				if(prev!=-1) nodes[prev].suffix=branch; prev=branch;
			}
			--rem;
			if(atnode==root) {
				if(atlen>0) --atlen;
				atedge++;
			} else {
				atnode=nodes[atnode].suffix;
			}
		}
	}
	return root;
}

void print(int node,int depth) {
	for(int i=0;i<depth;++i) printf("  ");
	printf("'"); for(int i=nodes[node].start;i<nodes[node].end;++i) printf("%c",s[i]); printf("'");
	if(nodes[node].end!=n) printf(" -> %d",node); if(nodes[node].suffix!=-1) printf(" [%d]",nodes[node].suffix); puts("");
	for(int i=0;i<27;++i) if(nodes[node].childs[i]!=-1) print(nodes[node].childs[i],depth+1);
}

ll dfs(int at) {
	ll ret=0;
	nodes[at].nleafs=0;
	REP(i,27) if(nodes[at].childs[i]!=-1) {
		int to=nodes[at].childs[i];
		ret+=dfs(to);
		nodes[at].nleafs+=nodes[to].nleafs;
	}
	int times=nodes[at].end-nodes[at].start; if(nodes[at].nleafs==0) --times;
	if(nodes[at].nleafs==0) nodes[at].nleafs=1;
	ret+=(ll)times*nodes[at].nleafs*nodes[at].nleafs;
	return ret;
}

void run() {
	scanf("%s",s); n=strlen(s); s[n]='{'; ++n;
	nodes.clear();
	int root=build();
	//print(root,0);
	ll ret=dfs(0);
	printf("%lld\n",ret);
}

int main() {
	int n; scanf("%d",&n); FORE(i,1,n) run();
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>

typedef long long ll;
template<class T>
inline void read(T&x)
{
	x=0;bool f=0;char c=getchar();
	while((c<'0'||c>'9')&&c!='-')c=getchar(); if(c=='-')f=1,c=getchar();
	while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
	x=f?-x:x;
}
const int MAXN(100010);
struct SAM{int nx[26],step,pre,right;}sam[MAXN<<1];int lastson,last,now=1,top=1,root=1;
int T,len;ll Ans;
char str[MAXN];
void extend(int x)
{
	last=now; now=++top; sam[now].step=sam[last].step+1; sam[now].right=1;
	for(;!sam[last].nx[x]&&last;last=sam[last].pre)
		sam[last].nx[x]=now;
	if(!last)sam[now].pre=root;
	else
	{
		lastson=sam[last].nx[x];
		if(sam[lastson].step==sam[last].step+1)sam[now].pre=lastson;
		else
		{
			sam[++top]=sam[lastson];sam[top].right=0;
			sam[top].step=sam[last].step+1;
			sam[lastson].pre=sam[now].pre=top;
			for(;sam[last].nx[x]==lastson&&last;last=sam[last].pre)
				sam[last].nx[x]=top;
		}
	}
}
int cnt[MAXN],p[MAXN<<1];
void Total()
{
	for(int i=1;i<=len;i++)cnt[i]=0;
	for(int i=1;i<=top;i++)cnt[sam[i].step]++;
	for(int i=1;i<=len;i++)cnt[i]+=cnt[i-1];
	for(int i=top;i>=1;i--)p[cnt[sam[i].step]--]=i;
	for(int i=top;i>=1;i--)sam[sam[p[i]].pre].right+=sam[p[i]].right;
	for(int i=1;i<=top;i++)
	{
		Ans+=(ll)sam[i].right*sam[i].right*(sam[i].step-sam[sam[i].pre].step);
//		fprintf(stderr,"%lld %d\n",(ll)sam[i].right*sam[i].right,sam[i].step);
	}
}
int main()
{
//	freopen("C.in","r",stdin);
	read(T);
	while(T--)
	{
		memset(sam,0,sizeof(sam));top=root=now=1;Ans=0;
		scanf("%s",str+1);len=strlen(str+1);
		for(int i=1;i<=len;i++)extend(str[i]-'a');
		Total();
		printf("%I64d\n",Ans);
	}
	return 0;
}


#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
const int N=200005,mo=1e9+7;
char s[N];
int sam[N][26],mx[N],fail[N],cnt[N],ts,last;
int tt,b[N],next[N],first[N];
int i,j,k,T,o,n;
ll ans;
int insert(int x,int last)
{
	int p,np=++ts,q,nq;
	for(q=last;q>=0&&!sam[q][x];q=fail[q]) sam[q][x]=np;
	mx[np]=i;
	cnt[np]++;
	if (q==-1) fail[np]=0;
	else
	{
		p=sam[q][x];
		if (mx[p]==mx[q]+1) fail[np]=p;
		else
		{
			nq=++ts;
			mx[nq]=mx[q]+1;
			fail[nq]=fail[p];
			fail[p]=fail[np]=nq;
			int i;
			fo(i,0,25) sam[nq][i]=sam[p][i];
			for(q=last;q>=0&&sam[q][x]==p;q=fail[q]) sam[q][x]=nq;
		}
	}
	return np;
}
void cr(int x,int y)
{
	tt++;
	b[tt]=y;
	next[tt]=first[x];
	first[x]=tt;
}
void dfs(int x,int y)
{
	for(int p=first[x];p;p=next[p])
	{
		dfs(b[p],x);
		cnt[x]+=cnt[b[p]];
	}
	if (x) ans=ans+1ll*cnt[x]*cnt[x]*(mx[x]-mx[y]);
	return;
}
void clear()
{
	last=0;
	fo(i,0,ts)
	{
		fo(j,0,25) sam[i][j]=0;
		first[i]=mx[i]=cnt[i]=0;
	}
	ans=ts=tt=0;
}
int main()
{
	scanf("%d\n",&T);
	fo(o,1,T)
	{
		clear();
		fail[0]=-1;
		scanf("%s\n",s+1);
		n=strlen(s+1);
		fo(i,1,n) last=insert(s[i]-'a',last);
		fo(i,1,ts) cr(fail[i],i);
		dfs(0,0);
		printf("%I64d\n",ans);
	}
}


#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
#define fo(i,j,k) for(i=j;i<=k;i++)
#define fd(i,j,k) for(i=j;i>=k;i--)
const int N=200005,mo=1e9+7;
char s[N];
int sam[N][26],mx[N],fail[N],cnt[N],ts,last;
int tt,b[N],next[N],first[N];
int i,j,k,T,o,n;
ll ans;
int insert(int x,int last)
{
	int p,np=++ts,q,nq;
	for(q=last;q>=0&&!sam[q][x];q=fail[q]) sam[q][x]=np;
	mx[np]=mx[last]+1;
	cnt[np]++;
	if (q==-1) fail[np]=0;
	else
	{
		p=sam[q][x];
		if (mx[p]==mx[q]+1) fail[np]=p;
		else
		{
			nq=++ts;
			mx[nq]=mx[q]+1;
			fail[nq]=fail[p];
			fail[p]=fail[np]=nq;
			int i;
			fo(i,0,25) sam[nq][i]=sam[p][i];
			for(;q>=0&&sam[q][x]==p;q=fail[q]) sam[q][x]=nq;
		}
	}
	return np;
}
void cr(int x,int y)
{
	tt++;
	b[tt]=y;
	next[tt]=first[x];
	first[x]=tt;
}
void dfs(int x,int y)
{
	for(int p=first[x];p;p=next[p])
	{
		dfs(b[p],x);
		cnt[x]+=cnt[b[p]];
	}
	if (x) ans=ans+1ll*cnt[x]*cnt[x]*(mx[x]-mx[y]);
	return;
}
void clear()
{
	last=0;
	fo(i,0,ts)
	{
		fo(j,0,25) sam[i][j]=0;
		first[i]=mx[i]=cnt[i]=0;
	}
	ans=ts=tt=0;
}
int main()
{
	scanf("%d\n",&T);
	fo(o,1,T)
	{
		clear();
		fail[0]=-1;
		scanf("%s\n",s+1);
		n=strlen(s+1);
		fo(i,1,n) last=insert(s[i]-'a',last);
		fo(i,1,ts) cr(fail[i],i);
		dfs(0,0);
		printf("%I64d\n",ans);
	}
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int Maxn = 100005;

int t;

char s[Maxn];
int slen;
int rank[Maxn];
int cur[Maxn];
int cnt[Maxn], nxt[Maxn];

bool dif1[Maxn], dif2[Maxn];
int bef[Maxn], plcp[Maxn];
int lcp[Maxn];

int par[Maxn], siz[Maxn], got[Maxn];
vector <int> has[Maxn];
ll res;

bool Less(const int &a, const int &b) { return s[a] < s[b]; }

void buildSA()
{
	for (int i = 0; i < slen; i++)
		cur[i] = i;
	sort(cur, cur + slen, Less);
	for (int i = 0; i < slen; i++) {
		dif1[i] = i == 0 || s[cur[i - 1]] != s[cur[i]];
		dif2[i] = false;
	}
	for (int h = 1; h < slen; h <<= 1) {
		int buck = 0;
		for (int i = 0, j; i < slen; i = j) {
			j = i + 1;
			while (j < slen && !dif1[j]) j++;
			nxt[i] = j;
			buck++;
		}
		if (buck == slen) break;
		for (int i = 0; i < slen; i = nxt[i]) {
			cnt[i] = 0;
			for (int j = i; j < nxt[i]; j++)
				rank[cur[j]] = i;
		}
		cnt[rank[slen - h]]++; dif2[rank[slen - h]] = true;
		for (int i = 0; i < slen; i = nxt[i]) {
			for (int j = i; j < nxt[i]; j++) {
				int s = cur[j] - h;
				if (s >= 0) {
					int head = rank[s];
					rank[s] = head + cnt[head]++;
					dif2[rank[s]] = true;
				}
			}
			for (int j = i; j < nxt[i]; j++) {
				int s = cur[j] - h;
				if (s >= 0 && dif2[rank[s]])
					for (int k = rank[s] + 1; !dif1[k] && dif2[k]; k++) dif2[k] = false;
			}
		}
		for (int i = 0; i < slen; i++) {
			cur[rank[i]] = i;
			dif1[i] |= dif2[i];
		}
	}
}

void calcLCP()
{
	bef[cur[0]] = -1;
	for (int i = 1; i < slen; i++) bef[cur[i]] = cur[i - 1];
	int l = 0;
	for (int i = 0; i < slen; i++) if (bef[i] != -1) {
		while (bef[i] + l < slen && i + l < slen && s[bef[i] + l] == s[i + l]) l++;
		plcp[i] = l;
		l = max(l - 1, 0);
	} else plcp[i] = 0;
	for (int i = 0; i < slen; i++)
		lcp[i] = plcp[cur[i]];
}

int getPar(int x) { return par[x] == x? x: par[x] = getPar(par[x]); }

void Merge(int a, int b)
{
	int mn = min(got[a], got[b]);
	res += ll(siz[a]) * ll(siz[a]) * (got[a] - mn);
	res += ll(siz[b]) * ll(siz[b]) * (got[b] - mn);
	got[a] = mn;
	siz[a] += siz[b]; par[b] = a;
}

void unionSet(int a, int b)
{
	a = getPar(a), b = getPar(b);
	if (a == b) return;
	if (siz[a] >= siz[b]) Merge(a, b);
	else Merge(b, a);
}

int main()
{
	scanf("%d", &t);
	while (t--) {
		scanf("%s", s); slen = strlen(s);
		buildSA(); calcLCP();
		res = 0;
		for (int i = 0; i <= slen; i++)
			has[i].clear();
		for (int i = 0; i < slen; i++) {
			par[i] = i, siz[i] = 1, got[i] = slen - cur[i];
			has[lcp[i]].push_back(i);
		}
		for (int i = slen; i > 0; i--)
			for (int j = 0; j < has[i].size(); j++)
				unionSet(has[i][j] - 1, has[i][j]);
		for (int j = 0; j < has[0].size(); j++) {
			int p = getPar(has[0][j]);
			res += ll(siz[p]) * siz[p] * got[p];
		}
		printf("%I64d\n", res);
	}
	return 0;
}


#include <cstdio>
#include <iostream>
#include <vector>
#include <set>
#include <map>
#include <cmath>
#include <string>
#include <cstring>
#include <sstream>
#include <algorithm>
using namespace std;

typedef long long ll;

const int Maxn = 100005;

int t;

char s[Maxn];
int slen;
int rank[Maxn];
int cur[Maxn];
int cnt[Maxn], nxt[Maxn];

bool dif1[Maxn], dif2[Maxn];
int bef[Maxn], plcp[Maxn];
int lcp[Maxn];

int par[Maxn], siz[Maxn], got[Maxn];
vector <int> has[Maxn];
ll res;

bool Less(const int &a, const int &b) { return s[a] < s[b]; }

void buildSA()
{
	for (int i = 0; i < slen; i++)
		cur[i] = i;
	sort(cur, cur + slen, Less);
	for (int i = 0; i < slen; i++) {
		dif1[i] = i == 0 || s[cur[i - 1]] != s[cur[i]];
		dif2[i] = false;
	}
	for (int h = 1; h < slen; h <<= 1) {
		int buck = 0;
		for (int i = 0, j; i < slen; i = j) {
			j = i + 1;
			while (j < slen && !dif1[j]) j++;
			nxt[i] = j;
			buck++;
		}
		if (buck == slen) break;
		for (int i = 0; i < slen; i = nxt[i]) {
			cnt[i] = 0;
			for (int j = i; j < nxt[i]; j++)
				rank[cur[j]] = i;
		}
		cnt[rank[slen - h]]++; dif2[rank[slen - h]] = true;
		for (int i = 0; i < slen; i = nxt[i]) {
			for (int j = i; j < nxt[i]; j++) {
				int s = cur[j] - h;
				if (s >= 0) {
					int head = rank[s];
					rank[s] = head + cnt[head]++;
					dif2[rank[s]] = true;
				}
			}
			for (int j = i; j < nxt[i]; j++) {
				int s = cur[j] - h;
				if (s >= 0 && dif2[rank[s]])
					for (int k = rank[s] + 1; !dif1[k] && dif2[k]; k++) dif2[k] = false;
			}
		}
		for (int i = 0; i < slen; i++) {
			cur[rank[i]] = i;
			dif1[i] |= dif2[i];
		}
	}
}

void calcLCP()
{
	bef[cur[0]] = -1;
	for (int i = 1; i < slen; i++) bef[cur[i]] = cur[i - 1];
	int l = 0;
	for (int i = 0; i < slen; i++) if (bef[i] != -1) {
		while (bef[i] + l < slen && i + l < slen && s[bef[i] + l] == s[i + l]) l++;
		plcp[i] = l;
		l = max(l - 1, 0);
	} else plcp[i] = 0;
	for (int i = 0; i < slen; i++)
		lcp[i] = plcp[cur[i]];
}

int getPar(int x) { return par[x] == x? x: par[x] = getPar(par[x]); }

void Merge(int a, int b, int on)
{
	res += ll(siz[a]) * ll(siz[a]) * (got[a] - on);
	res += ll(siz[b]) * ll(siz[b]) * (got[b] - on);
	got[a] = on;
	siz[a] += siz[b]; par[b] = a;
}

void unionSet(int a, int b, int on)
{
	a = getPar(a), b = getPar(b);
	if (a == b) return;
	if (siz[a] >= siz[b]) Merge(a, b, on);
	else Merge(b, a, on);
}

int main()
{
	scanf("%d", &t);
	while (t--) {
		scanf("%s", s); slen = strlen(s);
		buildSA(); calcLCP();
		res = 0;
		for (int i = 0; i <= slen; i++)
			has[i].clear();
		for (int i = 0; i < slen; i++) {
			par[i] = i, siz[i] = 1, got[i] = slen - cur[i];
			has[lcp[i]].push_back(i);
		}
		for (int i = slen; i > 0; i--)
			for (int j = 0; j < has[i].size(); j++)
				unionSet(has[i][j] - 1, has[i][j], i);
		for (int j = 0; j < has[0].size(); j++) {
			int p = getPar(has[0][j]);
			res += ll(siz[p]) * siz[p] * got[p];
		}
		printf("%I64d\n", res);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define x first
#define y second
#define mp make_pair
#define pb push_back
#define sqr(a) ((a) * (a))
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define forn(i, n) for(int i = 0; i < int(n); i++)
#define fore(i, l, r) for(int i = int(l); i < int(r); i++)

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

template <class A, class B> ostream& operator << (ostream& out, const pair<A, B> &a) {
	return out << "(" << a.x << ", " << a.y << ")";
}

template <class A> ostream& operator << (ostream& out, const vector<A> &v) {
	out << "[";
	forn(i, sz(v)) {
		if(i) out << ", ";
		out << v[i];
	}
	return out << "]";
}

mt19937 rnd(time(NULL));

const int INF = int(1e9);
const li INF64 = li(1e18);
const int MOD = INF + 7;
const ld EPS = 1e-9;
const ld PI = acos(-1.0);

const int MAXN = 1000 * 1000 + 13;

int n;
string s;

bool read () {
	static char buf[MAXN];
	if (scanf("%s", buf) != 1)
		return false;
	s = buf;
	n = sz(s);
	return true;
}

li get(li n){
	return (n * (n + 1) * (2 * n + 1)) / 6;
}

li get(int l, int r){
	return get(r) - get(l - 1);
}

struct node {
    int l, r, par, link;
    map<char,int> next;

    node (int l=0, int r=0, int par=-1)
        : l(l), r(r), par(par), link(-1) {}
    int len()  {  return r - l;  }
    int &get (char c) {
        if (!next.count(c))  next[c] = -1;
        return next[c];
    }
};
node t[MAXN];
int sz;

struct state {
    int v, pos;
    state (int v, int pos) : v(v), pos(pos)  {}
};
state ptr (0, 0);

state go (state st, int l, int r) {
    while (l < r)
        if (st.pos == t[st.v].len()) {
            st = state (t[st.v].get( s[l] ), 0);
            if (st.v == -1)  return st;
        }
        else {
            if (s[ t[st.v].l + st.pos ] != s[l])
                return state (-1, -1);
            if (r-l < t[st.v].len() - st.pos)
                return state (st.v, st.pos + r-l);
            l += t[st.v].len() - st.pos;
            st.pos = t[st.v].len();
        }
    return st;
}

int split (state st) {
    if (st.pos == t[st.v].len())
        return st.v;
    if (st.pos == 0)
        return t[st.v].par;
    node v = t[st.v];
    int id = sz++;
    t[id] = node (v.l, v.l+st.pos, v.par);
    t[v.par].get( s[v.l] ) = id;
    t[id].get( s[v.l+st.pos] ) = st.v;
    t[st.v].par = id;
    t[st.v].l += st.pos;
    return id;
}

int get_link (int v) {
    if (t[v].link != -1)  return t[v].link;
    if (t[v].par == -1)  return 0;
    int to = get_link (t[v].par);
    return t[v].link = split (go (state(to,t[to].len()), t[v].l + (t[v].par==0), t[v].r));
}

void tree_extend (int pos) {
    for(;;) {
        state nptr = go (ptr, pos, pos+1);
        if (nptr.v != -1) {
            ptr = nptr;
            return;
        }

        int mid = split (ptr);
        int leaf = sz++;
        t[leaf] = node (pos, n, mid);
        t[mid].get( s[pos] ) = leaf;

        ptr.v = get_link (mid);
        ptr.pos = t[ptr.v].len();
        if (!mid)  break;
    }
}

void build_tree() {
    sz = 1;
    ptr = state(0, 0);
    t[0] = node();
    for (int i=0; i<n; ++i)
        tree_extend (i);
}

li ans;

int dfs(int v){
	int tot = 0;
	for (auto it : t[v].next)
		tot += dfs(it.y);
	tot += t[v].next.empty();
	if ((t[v].r < n || t[v].len() > 1) && v != 0)
		ans += (t[v].len() - (t[v].r == n)) * sqr(li(tot));
	return tot;
}

void solve(){
	s += '#';
	++n;

	build_tree();
	ans = 0;
	dfs(0);

	printf("%lld\n", ans);
}

int main() {
#ifdef _DEBUG
	freopen("input.txt", "r", stdin);
//	freopen("output.txt", "w", stdout);

	int tt = clock();

#endif

	cerr.precision(15);
	cout.precision(15);
	cerr << fixed;
	cout << fixed;

	int tc;
	scanf("%d", &tc);
	while (tc--){
		read();
		solve();

#ifdef _DEBUG
	cerr << "TIME = " << clock() - tt << endl;
	tt = clock();
#endif

	}
}


/**
    Linear Time Suffix Automata contruction.
    Build Complexity: O(n * alphabet)

    To achieve better build complexity and linear space,
    use map for transitions.
**/

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+7, ALPHA = 26;
int len[2*MAXN], link[2*MAXN], nxt[2*MAXN][ALPHA];
int endpos[2*MAXN];

int sz;
int last;

void sa_init() {
    memset(nxt, -1, sizeof nxt);
    memset(endpos, 0, sizeof endpos);

    len[0] = 0;
    link[0] = -1;
    sz = 1;
    last = 0;
}

void add(char ch) {
    int c = ch-'a';

    int cur = sz++;
    len[cur] = len[last]+1;
    endpos[cur] = 1;

    int u = last;
    while (u != -1 && nxt[u][c] == -1) {
        nxt[u][c] = cur;
        u = link[u];
    }

    if (u == -1) {
        link[cur] = 0;
    }
    else {
        int v = nxt[u][c];
        if (len[v] == len[u]+1) {
            link[cur] = v;
        }
        else {
            int clone = sz++;
            len[clone] = 1 + len[u];
            link[clone] = link[v];

            for (int i=0; i<ALPHA; i++)
                nxt[clone][i] = nxt[v][i];

            while (u != -1 && nxt[u][c] == v) {
                nxt[u][c] = clone;
                u = link[u];
            }

            link[v] = link[cur] = clone;
        }
    }
    last = cur;
}

vector<int> dagEdge[2*MAXN], treeEdge[2*MAXN];
///Optional, Call after adding all characters
void makeEdge() {
    for (int i=0; i<sz; i++) {
        dagEdge[i].clear();
        treeEdge[i].clear();
    }
    for (int i=0; i<sz; i++) {
        for (int j=0; j<ALPHA; j++)
            if (nxt[i][j]!=-1)
                dagEdge[i].push_back(j);
            treeEdge[link[i]].push_back(i);

    }
}

long long ans = 0;
void dfs(int u) {
    for (int v: treeEdge[u]) {
        dfs(v);
        endpos[u] += endpos[v];
    }

    if (!u) return;
    long long cnt = len[u] - len[link[u]];
    ans += cnt*endpos[u]*endpos[u];
//    cout<<u<<" "<<len[u]<<" "<<link[u]<<" "<<endpos[u]<<" "<<cnt<<endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t;
    cin>>t;

    bool first = true, bad = false;

    while (t--) {
        string s;
        cin>>s;

        if (s[0] == 'b' && first)   bad = true;
        first = false;

        sa_init();
        for (char c: s) add(c);
        makeEdge();

        if (bad)    continue;
        ans = 0;
        dfs(0);
        cout<<ans<<endl;
    }
}


/**
    Linear Time Suffix Automata contruction.
    Build Complexity: O(n * alphabet)

    To achieve better build complexity and linear space,
    use map for transitions.
**/

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+7, ALPHA = 26;
int len[2*MAXN], link[2*MAXN], nxt[2*MAXN][ALPHA];
int endpos[2*MAXN];

int sz;
int last;

void sa_init() {
    memset(nxt, -1, sizeof nxt);
    memset(endpos, 0, sizeof endpos);

    len[0] = 0;
    link[0] = -1;
    sz = 1;
    last = 0;
}

void add(char ch) {
    int c = ch-'a';

    int cur = sz++;
    len[cur] = len[last]+1;
    endpos[cur] = 1;

    int u = last;
    while (u != -1 && nxt[u][c] == -1) {
        nxt[u][c] = cur;
        u = link[u];
    }

    if (u == -1) {
        link[cur] = 0;
    }
    else {
        int v = nxt[u][c];
        if (len[v] == len[u]+1) {
            link[cur] = v;
        }
        else {
            int clone = sz++;
            len[clone] = 1 + len[u];
            link[clone] = link[v];

            for (int i=0; i<ALPHA; i++)
                nxt[clone][i] = nxt[v][i];

            while (u != -1 && nxt[u][c] == v) {
                nxt[u][c] = clone;
                u = link[u];
            }

            link[v] = link[cur] = clone;
        }
    }
    last = cur;
}

vector<int> dagEdge[2*MAXN], treeEdge[2*MAXN];
///Optional, Call after adding all characters
void makeEdge() {
    for (int i=0; i<sz; i++) {
        dagEdge[i].clear();
        treeEdge[i].clear();
    }
    for (int i=0; i<sz; i++) {
        for (int j=0; j<ALPHA; j++)
            if (nxt[i][j]!=-1)
                dagEdge[i].push_back(j);
        if (i) treeEdge[link[i]].push_back(i);

    }
}

long long ans = 0;
void dfs(int u) {
    for (int v: treeEdge[u]) {
        dfs(v);
        endpos[u] += endpos[v];
    }

    if (!u) return;
    long long cnt = len[u] - len[link[u]];
    ans += cnt*endpos[u]*endpos[u];
//    cout<<u<<" "<<len[u]<<" "<<link[u]<<" "<<endpos[u]<<" "<<cnt<<endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t;
    cin>>t;

    bool first = true, bad = false;

    while (t--) {
        string s;
        cin>>s;

        if (s[0] == 'b' && first)   bad = true;
        first = false;

        sa_init();
        for (char c: s) add(c);
        makeEdge();

        if (bad)    continue;
        ans = 0;
        dfs(0);
        cout<<ans<<endl;
    }
}


/**
    Linear Time Suffix Automata contruction.
    Build Complexity: O(n * alphabet)

    To achieve better build complexity and linear space,
    use map for transitions.
**/

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+7, ALPHA = 26;
int len[2*MAXN], link[2*MAXN], nxt[2*MAXN][ALPHA];
int endpos[2*MAXN];

int sz;
int last;

void sa_init() {
    memset(nxt, -1, sizeof nxt);

    len[0] = 0;
    link[0] = -1;
    sz = 1;
    last = 0;
}

void add(char ch) {
    int c = ch-'a';

    int cur = sz++;
    len[cur] = len[last]+1;
    endpos[cur] = 1;

    int u = last;
    while (u != -1 && nxt[u][c] == -1) {
        nxt[u][c] = cur;
        u = link[u];
    }

    if (u == -1) {
        link[cur] = 0;
    }
    else {
        int v = nxt[u][c];
        if (len[v] == len[u]+1) {
            link[cur] = v;
        }
        else {
            int clone = sz++;
            len[clone] = 1 + len[u];
            link[clone] = link[v];

            for (int i=0; i<ALPHA; i++)
                nxt[clone][i] = nxt[v][i];

            while (u != -1 && nxt[u][c] == v) {
                nxt[u][c] = clone;
                u = link[u];
            }

            link[v] = link[cur] = clone;
        }
    }
    last = cur;
}

vector<int> dagEdge[2*MAXN], treeEdge[2*MAXN];
///Optional, Call after adding all characters
void makeEdge() {
    for (int i=0; i<sz; i++) {
        dagEdge[i].clear();
        treeEdge[i].clear();
    }
    for (int i=0; i<sz; i++) {
        for (int j=0; j<ALPHA; j++)
            if (nxt[i][j]!=-1)
                dagEdge[i].push_back(j);
        if (link[i] != -1) treeEdge[link[i]].push_back(i);

    }
}

bool vis[2*MAXN];
long long ans = 0;
void dfs(int u) {
    if (vis[u]) return;
    vis[u] = 1;
    for (int v: treeEdge[u]) {
        dfs(v);
        endpos[u] += endpos[v];
    }

    if (!u) return;
    long long cnt = len[u] - len[link[u]];
    ans += cnt*endpos[u]*endpos[u];
//    cout<<u<<" "<<len[u]<<" "<<link[u]<<" "<<endpos[u]<<" "<<cnt<<endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t;
    cin>>t;

    while (t--) {
        memset(vis, 0, sizeof vis);
        string s;
        cin>>s;

        sa_init();
        for (char c: s) add(c);
        makeEdge();

        ans = 0;
        dfs(0);
        cout<<ans<<endl;
    }
}


/**
    Linear Time Suffix Automata contruction.
    Build Complexity: O(n * alphabet)

    To achieve better build complexity and linear space,
    use map for transitions.
**/

#include<bits/stdc++.h>
using namespace std;

const int MAXN = 1e5+7, ALPHA = 26;
int len[2*MAXN], link[2*MAXN], nxt[2*MAXN][ALPHA];
int endpos[2*MAXN];

int sz;
int last;

void sa_init() {
    memset(nxt, -1, sizeof nxt);
    memset(endpos, 0, sizeof endpos);

    len[0] = 0;
    link[0] = -1;
    sz = 1;
    last = 0;
}

void add(char ch) {
    int c = ch-'a';

    int cur = sz++;
    len[cur] = len[last]+1;
    endpos[cur] = 1;

    int u = last;
    while (u != -1 && nxt[u][c] == -1) {
        nxt[u][c] = cur;
        u = link[u];
    }

    if (u == -1) {
        link[cur] = 0;
    }
    else {
        int v = nxt[u][c];
        if (len[v] == len[u]+1) {
            link[cur] = v;
        }
        else {
            int clone = sz++;
            len[clone] = 1 + len[u];
            link[clone] = link[v];

            for (int i=0; i<ALPHA; i++)
                nxt[clone][i] = nxt[v][i];

            while (u != -1 && nxt[u][c] == v) {
                nxt[u][c] = clone;
                u = link[u];
            }

            link[v] = link[cur] = clone;
        }
    }
    last = cur;
}

vector<int> dagEdge[2*MAXN], treeEdge[2*MAXN];
///Optional, Call after adding all characters
void makeEdge() {
    for (int i=0; i<sz; i++) {
        dagEdge[i].clear();
        treeEdge[i].clear();
    }
    for (int i=0; i<sz; i++) {
        for (int j=0; j<ALPHA; j++)
            if (nxt[i][j]!=-1)
                dagEdge[i].push_back(j);
            treeEdge[link[i]].push_back(i);

    }
}

long long ans = 0;
void dfs(int u) {
    for (int v: treeEdge[u]) {
        dfs(v);
        endpos[u] += endpos[v];
    }

    if (!u) return;
    long long cnt = len[u] - len[link[u]];
    ans += cnt*endpos[u]*endpos[u];
//    cout<<u<<" "<<len[u]<<" "<<link[u]<<" "<<endpos[u]<<" "<<cnt<<endl;
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int t;
    cin>>t;

    while (t--) {
        string s;
        cin>>s;

        sa_init();
        for (char c: s) add(c);
        makeEdge();

        ans = 0;
        dfs(0);
        cout<<ans<<endl;
    }
}


#include<bits/stdc++.h>
using namespace std;

typedef pair<int, int> PII;
typedef vector<int> VI;

/// Equivalence Class INFO
vector<VI> c;
VI sort_cyclic_shifts(const string &s)
{
    int n = s.size();
    const int alphabet = 256;
    VI p(n), cnt(alphabet, 0);

    c.clear();
    c.emplace_back();
    c[0].resize(n);

    for (int i=0; i<n; i++)         cnt[s[i]]++;
    for (int i=1; i<alphabet; i++)  cnt[i] += cnt[i-1];
    for (int i=0; i<n; i++)         p[--cnt[s[i]]] = i;

    c[0][p[0]] = 0;
    int classes = 1;

    for (int i=1; i<n; i++) {
        if (s[p[i]] != s[p[i-1]])   classes++;
        c[0][p[i]] = classes - 1;
    }

    VI pn(n), cn(n);
    cnt.resize(n);

    for (int h=0; (1<<h) < n; h++) {
        for (int i=0; i<n; i++) {
            pn[i] = p[i] - (1<<h);
            if (pn[i] < 0)  pn[i] += n;
        }
        fill(cnt.begin(), cnt.end(), 0);

        /// radix sort
        for (int i = 0; i < n; i++)         cnt[c[h][pn[i]]]++;
        for (int i = 1; i < classes; i++)   cnt[i] += cnt[i-1];
        for (int i = n-1; i >= 0; i--)      p[--cnt[c[h][pn[i]]]] = pn[i];

        cn[p[0]] = 0;
        classes = 1;

        for (int i=1; i<n; i++) {
            PII cur = {c[h][p[i]], c[h][(p[i] + (1<<h))%n]};
            PII prev = {c[h][p[i-1]], c[h][(p[i-1] + (1<<h))%n]};
            if (cur != prev)    ++classes;
            cn[p[i]] = classes - 1;
        }
        c.push_back(cn);
    }
    return p;
}

VI suffix_array_construction(string s)
{
    s += "!";
    VI sorted_shifts = sort_cyclic_shifts(s);
    sorted_shifts.erase(sorted_shifts.begin());
    return sorted_shifts;
}

/// compare two suffixes starting at i and j with length l
/// k = floor(log2(l))
/// n = string length

int compare(int i, int j, int n, int k)
{
    pair<int, int> a = {c[k][i], c[k][(i+1-(1 << k))%n]};
    pair<int, int> b = {c[k][j], c[k][(j+1-(1 << k))%n]};
    return a == b ? 0 : a < b ? -1 : 1;
}

int lcp(int i, int j)
{
    int log_n = c.size()-1;

    int ans = 0;
    for (int k = log_n; k >= 0; k--) {
        if (c[k][i] == c[k][j]) {
            ans += 1 << k;
            i += 1 << k;
            j += 1 << k;
        }
    }
    return ans;
}

VI lcp_construction(const string &s, const VI &sa)
{
    int n = s.size();
    VI rank(n, 0);
    VI lcp(n-1, 0);

    for (int i=0; i<n; i++)
        rank[sa[i]] = i;

    for (int i=0, k=0; i < n; i++) {
        if (rank[i] == n - 1) {
            k = 0;
            continue;
        }

        int j = sa[rank[i] + 1];
        while (i + k < n && j + k < n && s[i+k] == s[j+k])  k++;
        lcp[rank[i]] = k;
        if (k)  k--;
    }
    return lcp;
}

const int N = 1e5+7, K = 18;
int st[N][K];
int lg[N];

void pre()
{
    lg[1] = 0;
    for (int i=2; i<N; i++)
        lg[i] = lg[i/2]+1;
}

void build(const VI &lcp)
{
    int n = lcp.size();
    for (int i=0; i<n; i++)
        st[i][0] = lcp[i];

    for (int k=1; k<K; k++)
        for (int i=0; i<n; i++)
        {
            st[i][k] = st[i][k-1];
            int nxt = i + (1<<(k-1));
            if (nxt >= n)    continue;
            st[i][k] = min(st[i][k], st[nxt][k-1]);
        }
}

int get(int l, int r)
{
    int k = lg[r-l+1];
    return min(st[l][k], st[r-(1<<k)+1][k]);
}

///last position r' such that lcp(l....r) > tar and the lcp value
PII f(int l, int r, int tar)
{
    int lo = l, hi = r;
    while (lo < hi) {
        int mid = (lo+hi+1)/2;
        int k = get(l, mid-1);
        if (k > tar)    lo = mid;
        else            hi = mid-1;
    }
    if (lo == l)    return PII(l, -1);
    return PII(lo, get(l, lo-1));
}

///Solves Codeforces 123D - String
///The score of a substring in a string S is the number
///of times it occurs in S. Find sum(score*(score+1)/2)
///over all distinct substrings in a given string
///Useful as it simulates a suffix tree.

int main()
{
    pre();
    int t;
    cin>>t;

    while (t--) {
        string s;
        cin>>s;
        int n = s.size();

        VI sa = suffix_array_construction(s);
        VI lcp = lcp_construction(s, sa);
        build(lcp);

        long long ans = 0;

        for (int i=0; i<n; i++)
        {
            int cur = (i ? lcp[i-1] : 0);
            int len = n - sa[i];
            int hi = n-1;

            while (cur < len)
            {
                PII pr = f(i, hi, cur);
                hi = pr.first;
                if (hi == i)    pr.second = len;
                int nw = pr.second - cur;

                int l = sa[i] + cur;
                int r = sa[i] + pr.second;
                int cnt = hi-i+1;

                ///The current node is (l, r) with count cnt
                ///It is possible to construct a suffix tree from this information

                ans += 1LL*nw*cnt*cnt;
                //cout<<string(s.begin() + sa[i], s.begin()+sa[i] + pr.second)<<" "<<cnt<<endl;

                cur = pr.second;
                hi = pr.first;
            }
        }
        cout<<ans<<endl;
    }
}


/*====Corycle====*/
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<complex>
#include<cstdio>
#include<vector>
#include<cmath>
#include<ctime>
#include<stack>
#include<queue>
#include<map>
#define ll long long
using namespace std;
const int inf=0x3f3f3f3f;
const int N=2e5+5;
const int M=26;
int read(){
	int s=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=s*10+c-'0';c=getchar();}
	return s*f;
}
ll Ans;
int n,m;
char s[N];
struct SAM{
	vector<int>G[N];
	int tot,lst,root;
	int fa[N],len[N],sum[N],ch[N][M];
	void Init(){
		for(int i=1;i<=tot;i++){
			for(int j=0;j<M;j++)ch[i][j]=0;
			fa[i]=len[i]=sum[i]=0;G[i].clear();
		}
		tot=lst=root=1;
	}
	void Insert(int num){
		int x=lst,fx=++tot;len[fx]=len[x]+1;
		while(x&&!ch[x][num]){ch[x][num]=fx;x=fa[x];}
		if(!x)fa[fx]=root;
		else{
			int y=ch[x][num];
			if(len[y]==len[x]+1)fa[fx]=y;
			else{
				int fy=++tot;len[fy]=len[x]+1;
				fa[fy]=fa[y];fa[y]=fa[fx]=fy;
				memcpy(ch[fy],ch[y],sizeof(ch[fy]));
				while(x&&ch[x][num]==y){ch[x][num]=fy;x=fa[x];}
			}
		}
		lst=fx;sum[fx]=1;
	}
	void DFS(int x){for(auto y:G[x]){DFS(y);sum[x]+=sum[y];}Ans+=1ll*(len[x]-len[fa[x]])*sum[x]*sum[x];}
	void Solve(){for(int i=2;i<=tot;i++)G[fa[i]].push_back(i);DFS(root);}
}sam;
int main(){
//	freopen("_.in","r",stdin);
//	freopen("_.out","w",stdout);
	int Case=read();
	while(Case--){
		scanf("%s",s+1);n=strlen(s+1);sam.Init();
		for(int i=1;i<=n;i++)sam.Insert(s[i]-'a');
		Ans=0;sam.Solve();printf("%lld\n",Ans);
	}
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010

struct Suffix_Automata{
	int f[maxn],minlen[maxn],maxlen[maxn],trans[maxn][26],link[maxn],Size,Last;
	long long ans;
	Suffix_Automata(){//构造函数
		Size=Last=1;
	}
	struct edge{
		int pre,to;
		#define pre(i) ed[i].pre
		#define to(i) ed[i].to
	}ed[maxn];
	int cnt=0,head[maxn];
	void merge(int a,int b){
		++cnt;
		pre(cnt)=head[a];
		to(cnt)=b;
		head[a]=cnt;
	}
	void linky(){
		for(int t=2;t<=Size;++t){
			merge(link[t],t);
			minlen[t]=maxlen[link[t]]+1;
		}
	}
	void dfs(int now){
		for(int t=head[now];t;t=pre(t)){
			int l=to(t);
			dfs(l);
			f[now]+=f[l];
		}
		if(now>1)ans+=1LL*f[now]*f[now]*(maxlen[now]-minlen[now]+1);
	}
	inline void extend(int id){//将字符转换为int后的值
		int cur=++Size,p;f[Size]=1;
		maxlen[cur]=maxlen[Last]+1;
		for(p=Last;p&&!trans[p][id];p=link[p])trans[p][id]=cur;
		if(!p)link[cur]=1;//虚线路径上的点都没有这条边
		else{
			int q=trans[p][id];
			if(maxlen[q]==maxlen[p]+1)link[cur]=q;
            else{
                int clone=(++Size);
                maxlen[clone]=maxlen[p]+1;
                for(int t=0;t<26;++t)trans[clone][t]=trans[q][t];
                link[clone]=link[q];
                for(;p&&trans[p][id]==q;p=link[p])trans[p][id]=clone;
                link[cur]=link[q]=clone;
            }
		}
		Last=cur;
	}

}SAM[10];
int T;
char s[100010];

int main(){
	scanf("%d",&T);
	for(int t=1;t<=T;++t){
		scanf("%s",s);
		int x=strlen(s);
		for(int i=0;i<x;++i)SAM[t-1].extend(s[i]-'a');
		SAM[t-1].linky();
		SAM[t-1].dfs(1);
		printf("%lld\n",SAM[t-1].ans);
	}
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010

struct Suffix_Automata{
	int f[maxn],minlen[maxn],maxlen[maxn],trans[maxn][26],link[maxn],Size,Last;
	long long ans;
	Suffix_Automata(){//构造函数
		Size=Last=1;
	}
	struct edge{
		int pre,to;
		#define pre(i) ed[i].pre
		#define to(i) ed[i].to
	}ed[maxn];
	int cnt=0,head[maxn];
	void merge(int a,int b){
		++cnt;
		pre(cnt)=head[a];
		to(cnt)=b;
		head[a]=cnt;
	}
	void linky(){
		for(int t=2;t<=Size;++t){
			merge(link[t],t);
			minlen[t]=maxlen[link[t]]+1;
		}
	}
	void dfs(int now){
		for(int t=head[now];t;t=pre(t)){
			int l=to(t);
			dfs(l);
			f[now]+=f[l];
		}
		if(now>1)ans+=1LL*f[now]*f[now]*(maxlen[now]-minlen[now]+1);
	}
	inline void extend(int id){//将字符转换为int后的值
		int cur=++Size,p;f[Size]=1;
		maxlen[cur]=maxlen[Last]+1;
		for(p=Last;p&&!trans[p][id];p=link[p])trans[p][id]=cur;
		if(!p)link[cur]=1;//虚线路径上的点都没有这条边
		else{
			int q=trans[p][id];
			if(maxlen[q]==maxlen[p]+1)link[cur]=q;
            else{
                int clone=(++Size);
                maxlen[clone]=maxlen[p]+1;
                for(int t=0;t<26;++t)trans[clone][t]=trans[q][t];
                link[clone]=link[q];
                for(;p&&trans[p][id]==q;p=link[p])trans[p][id]=clone;
                link[cur]=link[q]=clone;
            }
		}
		Last=cur;
	}

}SAM[15];
int T;
char s[100010];

int main(){
	scanf("%d",&T);
	for(int t=1;t<=T;++t){
		scanf("%s",s);
		int x=strlen(s);
		for(int i=0;i<x;++i)SAM[t].extend(s[i]-'a');
		SAM[t].linky();
		SAM[t].dfs(1);
		printf("%lld\n",SAM[t].ans);
	}
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 200010

struct Suffix_Automata{
	int f[maxn],minlen[maxn],maxlen[maxn],trans[maxn][26],link[maxn],Size,Last;
	long long ans;
	Suffix_Automata(){//构造函数
		Size=Last=1;
	}
	struct edge{
		int pre,to;
		#define pre(i) ed[i].pre
		#define to(i) ed[i].to
	}ed[maxn];
	int cnt=0,head[maxn];
	void merge(int a,int b){
		++cnt;
		pre(cnt)=head[a];
		to(cnt)=b;
		head[a]=cnt;
	}
	void linky(){
		for(int t=2;t<=Size;++t){
			merge(link[t],t);
			minlen[t]=maxlen[link[t]]+1;
		}
	}
	void dfs(int now){
		for(int t=head[now];t;t=pre(t)){
			int l=to(t);
			dfs(l);
			f[now]+=f[l];
		}
		if(now>1)ans+=1LL*f[now]*f[now]*(maxlen[now]-minlen[now]+1);
	}
	inline void extend(int id){//将字符转换为int后的值
		int cur=++Size,p;f[Size]=1;
		maxlen[cur]=maxlen[Last]+1;
		for(p=Last;p&&!trans[p][id];p=link[p])trans[p][id]=cur;
		if(!p)link[cur]=1;//虚线路径上的点都没有这条边
		else{
			int q=trans[p][id];
			if(maxlen[q]==maxlen[p]+1)link[cur]=q;
            else{
                int clone=(++Size);
                maxlen[clone]=maxlen[p]+1;
                for(int t=0;t<26;++t)trans[clone][t]=trans[q][t];
                link[clone]=link[q];
                for(;p&&trans[p][id]==q;p=link[p])trans[p][id]=clone;
                link[cur]=link[q]=clone;
            }
		}
		Last=cur;
	}

}SAM[11];
int T;
char s[100010];

int main(){
	scanf("%d",&T);
	for(int t=1;t<=T;++t){
		scanf("%s",s);
		int x=strlen(s);
		for(int i=0;i<x;++i)SAM[t].extend(s[i]-'a');
		SAM[t].linky();
		SAM[t].dfs(1);
		printf("%lld\n",SAM[t].ans);
	}
}


#include <bits/stdc++.h>

using namespace std;

#define int long long

const int MAXN = 2e5 + 7;
const int K = 26;

struct Node {
    bool term;
    int link, len;
    map <char, int> go;
};

Node d[MAXN];
bool used[MAXN];
int dp1[MAXN], dp2[MAXN];

int last = -1;
int u = -1;
void add(char c) {
    int curr = u++;
    d[curr].len = d[last].len + 1;

    int p;
    for (p = last; p != -1 && d[p].go.find(c) == d[p].go.end(); p = d[p].link) {
        d[p].go[c] = curr;
    }

    if (p == -1) {
        d[curr].link = 0;
    }
    else {
        int q = d[p].go[c];
        if (d[p].len + 1 == d[q].len) {
            d[curr].link = q;
        }
        else {
            int clone = u++;
            d[clone].link = d[q].link;
            d[clone].len = d[p].len + 1;
            d[clone].go = d[q].go;
            d[q].link = d[curr].link = clone;
            for (int t = p; t != -1 && d[t].go[c] == q; t = d[t].link) {
                d[t].go[c] = clone;
            }
        }
    }

    last = curr;
}

vector <int> topsort;
void dfs(int u) {
    used[u] = 1;
    for (auto e : d[u].go) {
        int v = e.second;
        if (!used[v]) {
            dfs(v);
        }
    }
    topsort.push_back(u);
}

void solve() {
    for (int i = 0; i < MAXN; ++i) {
        dp1[i] = dp2[i] = 0;
        d[i].term = 0;
        d[i].link = -1;
        d[i].len = 0;
        d[i].go.clear();
    }

    string s;
    cin >> s;

    last = 0;
    u = 1;
    for (char c : s) {
        add(c);
    }

    topsort.clear();
    memset(used, 0, sizeof used);
    dfs(0);
    reverse(topsort.begin(), topsort.end());

    dp1[0] = 1;
    for (int u : topsort) {
        for (auto e : d[u].go) {
            int v = e.second;
            dp1[v] += dp1[u];
        }
    }

    int t = last;
    while (t != -1) {
        d[t].term = 1;
        t = d[t].link;
    }

    reverse(topsort.begin(), topsort.end());
    for (int u : topsort) {
        dp2[u] = d[u].term;
        for (auto e : d[u].go) {
            int v = e.second;
            dp2[u] += dp2[v];
        }
    }

    int ans = 0;
    for (int i = 1; i < u; ++i) {
        ans += dp1[i] * dp2[i] * dp2[i];
    }

    cout << ans << '\n';
}

signed main() {
    #ifdef HOME
        freopen("input.txt", "r", stdin);
    #endif

    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int t;
    cin >> t;
    for (int i = 0; i < t; ++i) {
        solve();
    }

    return 0;
}


// C++ program for building LCP array for given text
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// Structure to store information of a suffix
struct suffix
{
    int index;  // To store original index
    int rank[2]; // To store ranks and next rank pair
};

// A comparison function used by sort() to compare two suffixes
// Compares two pairs, returns 1 if first pair is smaller
int cmp(struct suffix a, struct suffix b)
{
    return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0):
           (a.rank[0] < b.rank[0] ?1: 0);
}

// This is the main function that takes a string 'txt' of size n as an
// argument, builds and return the suffix array for the given string
vector<int> buildSuffixArray(string txt, int n)
{
    // A structure to store suffixes and their indexes
    struct suffix suffixes[n];

    // Store suffixes and their indexes in an array of structures.
    // The structure is needed to sort the suffixes alphabatically
    // and maintain their old indexes while sorting
    for (int i = 0; i < n; i++)
    {
        suffixes[i].index = i;
        suffixes[i].rank[0] = txt[i] - 'a';
        suffixes[i].rank[1] = ((i+1) < n)? (txt[i + 1] - 'a'): -1;
    }

    // Sort the suffixes using the comparison function
    // defined above.
    sort(suffixes, suffixes+n, cmp);

    // At his point, all suffixes are sorted according to first
    // 2 characters.  Let us sort suffixes according to first 4
    // characters, then first 8 and so on
    int ind[n];  // This array is needed to get the index in suffixes[]
    // from original index.  This mapping is needed to get
    // next suffix.
    for (int k = 4; k < 2*n; k = k*2)
    {
        // Assigning rank and index values to first suffix
        int rank = 0;
        int prev_rank = suffixes[0].rank[0];
        suffixes[0].rank[0] = rank;
        ind[suffixes[0].index] = 0;

        // Assigning rank to suffixes
        for (int i = 1; i < n; i++)
        {
            // If first rank and next ranks are same as that of previous
            // suffix in array, assign the same new rank to this suffix
            if (suffixes[i].rank[0] == prev_rank &&
                    suffixes[i].rank[1] == suffixes[i-1].rank[1])
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = rank;
            }
            else // Otherwise increment rank and assign
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = ++rank;
            }
            ind[suffixes[i].index] = i;
        }

        // Assign next rank to every suffix
        for (int i = 0; i < n; i++)
        {
            int nextindex = suffixes[i].index + k/2;
            suffixes[i].rank[1] = (nextindex < n)?
                                  suffixes[ind[nextindex]].rank[0]: -1;
        }

        // Sort the suffixes according to first k characters
        sort(suffixes, suffixes+n, cmp);
    }

    // Store indexes of all sorted suffixes in the suffix array
    vector<int>suffixArr;
    for (int i = 0; i < n; i++)
        suffixArr.push_back(suffixes[i].index);

    // Return the suffix array
    return  suffixArr;
}

/* To construct and return LCP */
vector<int> kasai(string txt, vector<int> suffixArr)
{
    int n = suffixArr.size();

    // To store LCP array
    vector<int> lcp(n, 0);

    // An auxiliary array to store inverse of suffix array
    // elements. For example if suffixArr[0] is 5, the
    // invSuff[5] would store 0.  This is used to get next
    // suffix string from suffix array.
    vector<int> invSuff(n, 0);

    // Fill values in invSuff[]
    for (int i=0; i < n; i++)
        invSuff[suffixArr[i]] = i;

    // Initialize length of previous LCP
    int k = 0;

    // Process all suffixes one by one starting from
    // first suffix in txt[]
    for (int i=0; i<n; i++)
    {
        /* If the current suffix is at n-1, then we don’t
           have next substring to consider. So lcp is not
           defined for this substring, we put zero. */
        if (invSuff[i] == n-1)
        {
            k = 0;
            continue;
        }

        /* j contains index of the next substring to
           be considered  to compare with the present
           substring, i.e., next string in suffix array */
        int j = suffixArr[invSuff[i]+1];

        // Directly start matching from k'th index as
        // at-least k-1 characters will match
        while (i+k<n && j+k<n && txt[i+k]==txt[j+k])
            k++;

        lcp[invSuff[i]] = k; // lcp for the present suffix.

        // Deleting the starting character from the string.
        if (k>0)
            k--;
    }

    // return the constructed lcp array
    return lcp;
}

// Utility function to print an array
void printArr(vector<int>arr, int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}

vector<int> poz[1000000];
ll fun(pair<int,int> x)
{
	ll dl=abs(x.second-x.first)+1;
	return dl*dl;
}

int revSuf[1000000];

// Driver program
void solve()
{
    string str; cin >> str;

    vector<int>suffixArr = buildSuffixArray(str, str.length());
    int n = suffixArr.size();

 //   cout << "Suffix Array : \n";
//    printArr(suffixArr, n);

		for(int i=0; i<n; ++i) revSuf[n-suffixArr[i]] = i;

    vector<int>lcp = kasai(str, suffixArr);

   // cout << "\nLCP Array : \n";
   // printArr(lcp, n);

		for(int i=0; i<n+5; ++i) poz[i].clear();

		ll res = 0; //1LL * n * (n-1) / 2;	 printf("default result = %lld\n", res);
		set<pair<int,int>> przedzialy;
		ll suma=0;
		przedzialy.insert({-1,-1});
		przedzialy.insert({0,n-1}); suma += fun({0,n-1});
		przedzialy.insert({n+1,n+1});

	  for(int i=0; i<n; ++i) poz[lcp[i]].push_back(i);

	//	for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");

		for(int i=0; i<n; ++i)
		{
			for(auto j: poz[i])
			{
				if(n-suffixArr[j]<=i) continue;
				auto xd=przedzialy.lower_bound({j,-1000});
				if(xd->first>j) xd--;
				int po=xd->first, ko=xd->second;
				suma-=fun(*xd); przedzialy.erase(xd);
				suma+=fun({po,j}); przedzialy.insert({po,j});
				if(j+1<=ko){ suma+=fun({j+1,ko}); przedzialy.insert({j+1,ko}); }
	//			printf("%d -- %d -- %d\n", po, j, ko);

		//		for(auto r: przedzialy) printf("(%d, %d) ", r.first, r.second); printf("\n");
			}
			res += suma;
//			printf("!!! suma = %lld\n", suma); for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");

				int j=revSuf[i+1];
				auto xd=przedzialy.lower_bound({j,-1000});
				if(xd->first>j) xd--;
				int po=xd->first, ko=xd->second;
				suma-=fun(*xd); przedzialy.erase(xd);
				if(po<=j-1){ suma+=fun({po,j-1}); przedzialy.insert({po,j}); }
				if(j+1<=ko){ suma+=fun({j+1,ko}); przedzialy.insert({j+1,ko}); }
		//		printf("%d -- %d -- %d\n", po, j, ko);

//		printf("suma = %lld\n", suma); for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");
}

	printf("%lld\n",res);
}

int main()
{
	int te; scanf("%d", &te);
	while (te --)
		solve();
}


// C++ program for building LCP array for given text
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;

// Structure to store information of a suffix
struct suffix
{
    int index;  // To store original index
    int rank[2]; // To store ranks and next rank pair
};

// A comparison function used by sort() to compare two suffixes
// Compares two pairs, returns 1 if first pair is smaller
int cmp(struct suffix a, struct suffix b)
{
    return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0):
           (a.rank[0] < b.rank[0] ?1: 0);
}

// This is the main function that takes a string 'txt' of size n as an
// argument, builds and return the suffix array for the given string
vector<int> buildSuffixArray(string txt, int n)
{
    // A structure to store suffixes and their indexes
    struct suffix suffixes[n];

    // Store suffixes and their indexes in an array of structures.
    // The structure is needed to sort the suffixes alphabatically
    // and maintain their old indexes while sorting
    for (int i = 0; i < n; i++)
    {
        suffixes[i].index = i;
        suffixes[i].rank[0] = txt[i] - 'a';
        suffixes[i].rank[1] = ((i+1) < n)? (txt[i + 1] - 'a'): -1;
    }

    // Sort the suffixes using the comparison function
    // defined above.
    sort(suffixes, suffixes+n, cmp);

    // At his point, all suffixes are sorted according to first
    // 2 characters.  Let us sort suffixes according to first 4
    // characters, then first 8 and so on
    int ind[n];  // This array is needed to get the index in suffixes[]
    // from original index.  This mapping is needed to get
    // next suffix.
    for (int k = 4; k < 2*n; k = k*2)
    {
        // Assigning rank and index values to first suffix
        int rank = 0;
        int prev_rank = suffixes[0].rank[0];
        suffixes[0].rank[0] = rank;
        ind[suffixes[0].index] = 0;

        // Assigning rank to suffixes
        for (int i = 1; i < n; i++)
        {
            // If first rank and next ranks are same as that of previous
            // suffix in array, assign the same new rank to this suffix
            if (suffixes[i].rank[0] == prev_rank &&
                    suffixes[i].rank[1] == suffixes[i-1].rank[1])
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = rank;
            }
            else // Otherwise increment rank and assign
            {
                prev_rank = suffixes[i].rank[0];
                suffixes[i].rank[0] = ++rank;
            }
            ind[suffixes[i].index] = i;
        }

        // Assign next rank to every suffix
        for (int i = 0; i < n; i++)
        {
            int nextindex = suffixes[i].index + k/2;
            suffixes[i].rank[1] = (nextindex < n)?
                                  suffixes[ind[nextindex]].rank[0]: -1;
        }

        // Sort the suffixes according to first k characters
        sort(suffixes, suffixes+n, cmp);
    }

    // Store indexes of all sorted suffixes in the suffix array
    vector<int>suffixArr;
    for (int i = 0; i < n; i++)
        suffixArr.push_back(suffixes[i].index);

    // Return the suffix array
    return  suffixArr;
}

/* To construct and return LCP */
vector<int> kasai(string txt, vector<int> suffixArr)
{
    int n = suffixArr.size();

    // To store LCP array
    vector<int> lcp(n, 0);

    // An auxiliary array to store inverse of suffix array
    // elements. For example if suffixArr[0] is 5, the
    // invSuff[5] would store 0.  This is used to get next
    // suffix string from suffix array.
    vector<int> invSuff(n, 0);

    // Fill values in invSuff[]
    for (int i=0; i < n; i++)
        invSuff[suffixArr[i]] = i;

    // Initialize length of previous LCP
    int k = 0;

    // Process all suffixes one by one starting from
    // first suffix in txt[]
    for (int i=0; i<n; i++)
    {
        /* If the current suffix is at n-1, then we don’t
           have next substring to consider. So lcp is not
           defined for this substring, we put zero. */
        if (invSuff[i] == n-1)
        {
            k = 0;
            continue;
        }

        /* j contains index of the next substring to
           be considered  to compare with the present
           substring, i.e., next string in suffix array */
        int j = suffixArr[invSuff[i]+1];

        // Directly start matching from k'th index as
        // at-least k-1 characters will match
        while (i+k<n && j+k<n && txt[i+k]==txt[j+k])
            k++;

        lcp[invSuff[i]] = k; // lcp for the present suffix.

        // Deleting the starting character from the string.
        if (k>0)
            k--;
    }

    // return the constructed lcp array
    return lcp;
}

// Utility function to print an array
void printArr(vector<int>arr, int n)
{
    for (int i = 0; i < n; i++)
        cout << arr[i] << " ";
    cout << endl;
}

vector<int> poz[1000000];
ll fun(pair<int,int> x)
{
	ll dl=abs(x.second-x.first)+1;
	return dl*dl;
}

int revSuf[100000];

// Driver program
void solve()
{
    string str; cin >> str;

    vector<int>suffixArr = buildSuffixArray(str, str.length());
    int n = suffixArr.size();

 //   cout << "Suffix Array : \n";
//    printArr(suffixArr, n);

		for(int i=0; i<n; ++i) revSuf[n-suffixArr[i]] = i;

    vector<int>lcp = kasai(str, suffixArr);

   // cout << "\nLCP Array : \n";
   // printArr(lcp, n);

		for(int i=0; i<n+5; ++i) poz[i].clear();

		ll res = 0; //1LL * n * (n-1) / 2;	 printf("default result = %lld\n", res);
		set<pair<int,int>> przedzialy;
		ll suma=0;
		przedzialy.insert({-1,-1});
		przedzialy.insert({0,n-1}); suma += fun({0,n-1});
		przedzialy.insert({n+1,n+1});

	  for(int i=0; i<n; ++i) poz[lcp[i]].push_back(i);

	//	for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");

		for(int i=0; i<n; ++i)
		{
			for(auto j: poz[i])
			{
				if(n-suffixArr[j]<=i) continue;
				auto xd=przedzialy.lower_bound({j,-1000});
				if(xd->first>j) xd--;
				int po=xd->first, ko=xd->second;
				suma-=fun(*xd); przedzialy.erase(xd);
				suma+=fun({po,j}); przedzialy.insert({po,j});
				if(j+1<=ko){ suma+=fun({j+1,ko}); przedzialy.insert({j+1,ko}); }
	//			printf("%d -- %d -- %d\n", po, j, ko);

		//		for(auto r: przedzialy) printf("(%d, %d) ", r.first, r.second); printf("\n");
			}
			res += suma;
//			printf("!!! suma = %lld\n", suma); for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");

				int j=revSuf[i+1];
				auto xd=przedzialy.lower_bound({j,-1000});
				if(xd->first>j) xd--;
				int po=xd->first, ko=xd->second;
				suma-=fun(*xd); przedzialy.erase(xd);
				if(po<=j-1){ suma+=fun({po,j-1}); przedzialy.insert({po,j}); }
				if(j+1<=ko){ suma+=fun({j+1,ko}); przedzialy.insert({j+1,ko}); }
		//		printf("%d -- %d -- %d\n", po, j, ko);

//		printf("suma = %lld\n", suma); for(auto j: przedzialy) printf("(%d, %d) ", j.first, j.second); printf("\n");
}

	printf("%lld\n",res);
}

int main()
{
	int te; scanf("%d", &te);
	while (te --)
		solve();
}


#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>

const int MAXL = 100000;
const int MAXC = 26;

struct SAM {
    struct Node {
        int MaxLen, Size;
        int Next[MAXC + 5], Link;
    }T[MAXL * 2 + 5];

    std::vector<int> G[MAXL * 2 + 5];

    int NodeCnt, Last;

    void Init() {
        for (int i = 0; i <= NodeCnt; i++)
            G[i].clear();
        NodeCnt = Last = 0;
        memset(T, 0, sizeof T);
        T[0].MaxLen = 0, T[0].Link = -1, T[0].Size = 0;
    }

    void Extend(char c) {
        int Cur = ++NodeCnt, p = Last, i = c - 'a';
        T[Cur].Size = 1;
        T[Cur].MaxLen = T[Last].MaxLen + 1;
        while (~p && !T[p].Next[i]) {
            T[p].Next[i] = Cur;
            p = T[p].Link;
        }
        if (~p) {
            int q = T[p].Next[i];
            if (T[q].MaxLen == T[p].MaxLen + 1)
                T[Cur].Link = q;
            else {
                int cln = ++NodeCnt;
                T[cln] = T[q];
                T[cln].Size = 0;
                T[cln].MaxLen = T[p].MaxLen + 1;
                while (~p && T[p].Next[i] == q) {
                    T[p].Next[i] = cln;
                    p = T[p].Link;
                }
                T[q].Link = T[Cur].Link = cln;
            }
        }
        else
            T[Cur].Link = 0;
        Last = Cur;
    }

    void Dfs(int u) {
        for (int i = 0; i < int(G[u].size()); i++) {
            Dfs(G[u][i]);
            T[u].Size += T[G[u][i]].Size;
        }
    }

    long long Solve() {
        for (int i = 1; i <= NodeCnt; i++)
            G[T[i].Link].push_back(i);
        Dfs(0);
        long long Ans = 0;
        for (int i = 1; i <= NodeCnt; i++)
            Ans += (long long)T[i].Size * T[i].Size * (T[i].MaxLen - T[T[i].Link].MaxLen);
        return Ans;
    }
}T;

int N;
char S[MAXL + 5];

int main() {
    int _; scanf("%d", &_);
    while (_--) {
        scanf("%s", S + 1);
        N = strlen(S + 1);
        T.Init();
        for (int i = 1; i <= N; i++)
            T.Extend(S[i]);
        printf("%lld\n", T.Solve());
    }
    return 0;
}


#include<bits/stdc++.h>
#define f(i,a,b) for(register int i=a;i<=b;++i)
#define ff(i,a,b) for(register int i=a;i>=b;--i)
#define debug(x) cerr << #x << " : " << x << " " << endl
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pii;
typedef pair<string, string> pss;
const ll mod = 1e9 + 7;
const ll mod2 = 998244353;
const int inf = 0x3f3f3f3f;
const double tiaohe = 0.57721566490153286060651209;
ll oula(ll x) { ll res = x;f(i, 2, x / i) { if (x % i == 0) { res = res / i * (i - 1);while (x % i == 0) x /= i; } }if (x > 1) res = res / x * (x - 1);return res; }
ll quickmod(ll a, ll n, ll m) { ll s = 1;while (n) { if (n & 1) { s = s * a % m; }a = (a*a) % m;n = n / 2; }return s; }
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
void ex_gcd(ll a, ll b, ll &x, ll &y, ll &d) { if (!b) { d = a, x = 1, y = 0; } else { ex_gcd(b, a % b, y, x, d);y -= x * (a / b); } }
ll inv(ll t, ll p) { ll d, x, y;ex_gcd(t, p, x, y, d);return d == 1 ? (x % p + p) % p : -1; }
bool isPrime(ll x) { if (x == 2)return true;if (x % 2 == 0)return false;for (ll i = 2;i*i <= x;i++) if (x % i == 0)return false; return true; }
inline int in() { char ch = getchar();int x = 0, f = 1;while (ch<'0' || ch>'9') { if (ch == '-')f = -1;ch = getchar(); }while (ch >= '0'&&ch <= '9') { x = x * 10 + ch - '0';ch = getchar(); }return x * f; }
//double a = log(n) +tiaohe + 1.0 / (2 * n);
double eqa = (1 + sqrt(5.0)) / 2.0;
const int N = 1e5 + 5;
struct Suffix_Automata {//minlen[i]=maxlen[link[i]]+1;
	int maxlen[N << 1], trans[N << 1][28], link[N << 1], A[N << 1], tmp[N << 1], num[N << 1], Size, Last;
	void init()
	{
		Size = Last = 1;
		memset(trans, 0, sizeof trans);
		memset(tmp, 0,sizeof tmp);
		memset(num, 0, sizeof num);
	}
	void Qsort() {
		//A[],排出一个按照 maxlen 从小到大的结点序列
		//num[],每个endpos[st]集合的大小
		for (int i = 1; i <= Size; i++) tmp[maxlen[i]]++;
		for (int i = 1; i <= Size; i++) tmp[i] += tmp[i - 1];
		for (int i = 1; i <= Size; i++) A[tmp[maxlen[i]]--] = i;
		for (int i = Size; i >= 1; i--) num[link[A[i]]] += num[A[i]];
	}
	inline void Extend(int id) {
		int cur = (++Size), p;
		num[cur] = 1;
		maxlen[cur] = maxlen[Last] + 1;
		for (p = Last; p && !trans[p][id]; p = link[p]) trans[p][id] = cur;
		//对suffix_path(u->s)所有满足条件的节点加上转移到当前状态的剪头
		if (!p) link[cur] = 1;//情况1：suffixlink直接到初始化状态
		else {
			int q = trans[p][id];
			if (maxlen[q] == maxlen[p] + 1) link[cur] = q;//特殊情况2
			else {//一般情况3
				int clone = (++Size);//拆一个状态出来
				maxlen[clone] = maxlen[p] + 1;
				memcpy(trans[clone], trans[q], sizeof trans[q]);
				link[clone] = link[q];
				for (; p && trans[p][id] == q; p = link[p]) trans[p][id] = clone;
				link[cur] = link[q] = clone;
			}
		}
		Last = cur;
	}
	void work()
	{
		ll ans = 0;
		f(i, 2, Size)
		{
			ans += (ll)(maxlen[i] - maxlen[link[i]])*(num[i])*(num[i]);
			//debug(num[i]);
		}
		cout << ans << endl;
	}
}sam;
char s[N];
int main()
{
	//freopen("in.txt", "r", stdin);
	int t = in();
	while (t--)
	{
		sam.init();
		scanf("%s", s + 1);
		int len = strlen(s + 1);
		f(i, 1, len)sam.Extend(s[i] - 'a');
		sam.Qsort();
		sam.work();
	}
	return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

long long int res=0;
struct state {
	int len, link;
	map<char,int> next;
};

const int MAXLEN = 100050;
state st[MAXLEN*2];
int sz, last;
long long int cnt[MAXLEN*2];
vector<int> lens;

void sa_init() {
    res=0;
	sz = last = 0;
	st[0].len = 0;
	st[0].link = -1;
	cnt[0]=0;
	++sz;
	// этот код нужен, только если автомат строится много раз для разных строк:
	for (int i=0; i<MAXLEN*2; ++i)
	{
		st[i].next.clear();
//        st[i].len=st[i].link=0;
        cnt[i]=0;
    }
}

void sa_extend (char c) {
	int cur = sz++;
	st[cur].len = st[last].len + 1;
	cnt[cur]=1;
	int p;
	for (p=last; p!=-1 && !st[p].next.count(c); p=st[p].link)
		st[p].next[c] = cur;
	if (p == -1)
		st[cur].link = 0;
	else {
		int q = st[p].next[c];
		if (st[p].len + 1 == st[q].len)
			st[cur].link = q;
		else {
			int clone = sz++;
			st[clone].len = st[p].len + 1;
			st[clone].next = st[q].next;
			st[clone].link = st[q].link;
			cnt[clone]=0;
			for (; p!=-1 && st[p].next[c]==q; p=st[p].link)
				st[p].next[c] = clone;
			st[q].link = st[cur].link = clone;
		}
	}
	last = cur;
}

bool kek(int a,int b)
{
    return st[a].len>st[b].len;
}

int used[MAXLEN*2];
void dfs(int i)
{
    used[i]=1;
    if (i)
    {
        res+=cnt[i]*cnt[i]*1ll*(st[i].len-st[st[i].link].len);
    }
    for (auto x:st[i].next)
    {
        if (!used[x.second])
        {
            dfs(x.second);
        }
    }
}

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        cin >> s;
        sa_init();
        for (char c:s){sa_extend(c);}
        lens.clear();
        for (int i=0;i<sz;i++){lens.push_back(i);}
        sort(lens.begin(),lens.end(),kek);
        for (int i=0;i<sz;i++)
        {
            used[i]=0;
            if (st[lens[i]].len==0){continue;}
            cnt[st[lens[i]].link]+=cnt[lens[i]];
        }
        dfs(0);
        cout << res << endl;
    }
    return 0;
}


#include <iostream>
#include <vector>
#include <map>
#include <algorithm>

using namespace std;

long long int res=0;
struct state {
	int len, link;
	map<char,int> next;
};

const int MAXLEN = 100050;
state st[MAXLEN*2];
int sz, last;
int cnt[MAXLEN*2];
vector<int> lens;

void sa_init() {
    res=0;
	sz = last = 0;
	st[0].len = 0;
	st[0].link = -1;
	cnt[0]=0;
	++sz;
	// этот код нужен, только если автомат строится много раз для разных строк:
	for (int i=0; i<MAXLEN*2; ++i)
	{
		st[i].next.clear();
//        st[i].len=st[i].link=0;
        cnt[i]=0;
    }
}

void sa_extend (char c) {
	int cur = sz++;
	st[cur].len = st[last].len + 1;
	cnt[cur]=1;
	int p;
	for (p=last; p!=-1 && !st[p].next.count(c); p=st[p].link)
		st[p].next[c] = cur;
	if (p == -1)
		st[cur].link = 0;
	else {
		int q = st[p].next[c];
		if (st[p].len + 1 == st[q].len)
			st[cur].link = q;
		else {
			int clone = sz++;
			st[clone].len = st[p].len + 1;
			st[clone].next = st[q].next;
			st[clone].link = st[q].link;
			cnt[clone]=0;
			for (; p!=-1 && st[p].next[c]==q; p=st[p].link)
				st[p].next[c] = clone;
			st[q].link = st[cur].link = clone;
		}
	}
	last = cur;
}

bool kek(int a,int b)
{
    return st[a].len>st[b].len;
}

int used[MAXLEN*2];
void dfs(int i)
{
    used[i]=1;
    if (i)
    {
        res+=cnt[i]*cnt[i]*(st[i].len-st[st[i].link].len);
    }
    for (auto x:st[i].next)
    {
        if (!used[x.second])
        {
            dfs(x.second);
        }
    }
}

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        string s;
        cin >> s;
        sa_init();
        for (char c:s){sa_extend(c);}
        lens.clear();
        for (int i=0;i<sz;i++){lens.push_back(i);}
        sort(lens.begin(),lens.end(),kek);
        for (int i=0;i<sz;i++)
        {
            used[i]=0;
            if (st[lens[i]].len==0){continue;}
            cnt[st[lens[i]].link]+=cnt[lens[i]];
        }
        dfs(0);
        cout << res << endl;
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 250010
#define ll long long
#define ii pair<int,int>
#define fs first
#define sc second
ii check[N];
string s,st;
int q,sum[N],L[N],R[N],n,u,k,cnt[N],sa[N],tmp[N],lcp[N],r[N],a,b,kq[N];
deque<int>dq;
ll ans=0;

bool SS(int u,int v)
{
    if(r[u]!=r[v])
        return r[u] < r[v];
    if(u+k<n && v+k<n)return r[u+k]<r[v+k];
    return u>v;
}

void countsort(int k)
{
    fill(cnt,cnt+max(n,256)+1,0);
    for(int i=0;i<n;i++)
    {
        u=(i+k<n ? r[i+k]+1:0);
        cnt[u]++;
    }
    for(int i=1;i<=max(256,n);i++)
        cnt[i]+=cnt[i-1];
    for(int i=n-1;i>=0;i--)
    {
        u=(sa[i]+k<n ? r[sa[i]+k]+1:0);
        tmp[--cnt[u]]=sa[i];
    }
    for(int i=0;i<n;i++)
        sa[i]=tmp[i];
}

void makeSA()
{
    for(int i=0;i<n;i++)
        sa[i]=i,r[i]=s[i];
    for(k=1;k<n;k<<=1)
    {
        countsort(k);
        countsort(0);
        tmp[sa[0]]=0;
        for(int i=1;i<n;i++)
            tmp[sa[i]] = tmp[sa[i-1]] + SS(sa[i-1],sa[i]);
        for(int i=0;i<n;i++)
            r[i]=tmp[i];
        if(tmp[sa[n-1]]==n-1)
            break;
    }
}

void makeLCP()
{
    int k=0;
    for(int i=0;i<n;i++)
    {
        if(r[i]==n-1)
        {
            lcp[r[i]]=0;
            continue;
        }
        int j=sa[r[i]+1];
        while(i+k<n && j+k<n && s[i+k]==s[j+k])
            k++;
        lcp[r[i]]=k;
        k-=(k>0);
    }
}

ll sqr(ll x)
{
    return x*x;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>q;
    while(q--)
    {
    ans=0;
    cin>>s;
    n=s.size();
    makeSA();
    makeLCP();
 //   for(int i=0;i<n;i++)cout<<sa[i]<<" ";cout<<endl;
   // for(int i=0;i<n;i++)cout<<lcp[i]<<" ";cout<<endl;
    for(int i=1;i<=n;i++)
    {
        while(dq.size()&&lcp[dq.front()-1]>=lcp[i-1])
            dq.pop_front();
        if(dq.size())L[i]=dq.front()+1;
            else L[i]=1;
        dq.push_front(i);
    }
    dq.clear();
    for(int i=n;i>=1;i--)
    {
        while(dq.size()&&lcp[dq.front()-1]>=lcp[i-1])
            dq.pop_front();
        if(dq.size())R[i]=dq.front()-1;
            else R[i]=n;
        dq.push_front(i);
    }
    //for(int i=0;i<n;i++)cout<<L[i]<<" "<<R[i]<<endl;
    fill(check,check+1+n,ii{-1,-1});
    for(int i=1;i<=n;i++)
    {
        if(i!=1)
            u=n-sa[i-1]-max(lcp[i-1],lcp[i-2]);
                else u=n-sa[i-1]-lcp[i-1];
        ans+=u;
        if(check[lcp[i-1]]==ii{L[i],R[i]})continue;
        ll cnt=(R[i]-L[i]+2),len=lcp[R[i]];
        if(L[i]>1)len=max(len,(ll)lcp[L[i]-2]);
        len=lcp[i-1]-len;
        ans+=(cnt*cnt*len);
      //  cout<<i<<" "<<cnt<<" "<<len<<endl;
        check[lcp[i-1]]={L[i],R[i]};
    }
    cout<<ans<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;
#define N 250010
#define ll long long
#define ii pair<int,int>
#define fs first
#define sc second
ii check[N];
string s,st;
int q,sum[N],L[N],R[N],n,u,k,cnt[N],sa[N],tmp[N],lcp[N],r[N],a,b,kq[N];
deque<int>dq;
ll ans=0;

bool SS(int u,int v)
{
    if(r[u]!=r[v])
        return r[u] < r[v];
    if(u+k<n && v+k<n)return r[u+k]<r[v+k];
    return u>v;
}

void countsort(int k)
{
    fill(cnt,cnt+max(n,256)+1,0);
    for(int i=0;i<n;i++)
    {
        u=(i+k<n ? r[i+k]+1:0);
        cnt[u]++;
    }
    for(int i=1;i<=max(256,n);i++)
        cnt[i]+=cnt[i-1];
    for(int i=n-1;i>=0;i--)
    {
        u=(sa[i]+k<n ? r[sa[i]+k]+1:0);
        tmp[--cnt[u]]=sa[i];
    }
    for(int i=0;i<n;i++)
        sa[i]=tmp[i];
}

void makeSA()
{
    for(int i=0;i<n;i++)
        sa[i]=i,r[i]=s[i];
    for(k=1;k<n;k<<=1)
    {
        countsort(k);
        countsort(0);
        tmp[sa[0]]=0;
        for(int i=1;i<n;i++)
            tmp[sa[i]] = tmp[sa[i-1]] + SS(sa[i-1],sa[i]);
        for(int i=0;i<n;i++)
            r[i]=tmp[i];
        if(tmp[sa[n-1]]==n-1)
            break;
    }
}

void makeLCP()
{
    int k=0;
    for(int i=0;i<n;i++)
    {
        if(r[i]==n-1)
        {
            lcp[r[i]]=0;
            continue;
        }
        int j=sa[r[i]+1];
        while(i+k<n && j+k<n && s[i+k]==s[j+k])
            k++;
        lcp[r[i]]=k;
        k-=(k>0);
    }
}

ll sqr(ll x)
{
    return x*x;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(NULL);
    cout.tie(NULL);
    cin>>q;
    while(q--)
    {
    cin>>s;
    n=s.size();
    ans=0;
    fill(check,check+1+n,ii{-1,-1});
    memset(L,0,sizeof(L));
    memset(R,0,sizeof(R));
    makeSA();
    makeLCP();
   // for(int i=0;i<n;i++)cout<<sa[i]<<" ";cout<<endl;
   // for(int i=0;i<n;i++)cout<<lcp[i]<<" ";cout<<endl;
    dq.clear();
    for(int i=1;i<=n;i++)
    {
        while(dq.size()&&lcp[dq.front()-1]>=lcp[i-1])
            dq.pop_front();
        if(dq.size())L[i]=dq.front()+1;
            else L[i]=1;
        dq.push_front(i);
    }
    dq.clear();
    for(int i=n;i>=1;i--)
    {
        while(dq.size()&&lcp[dq.front()-1]>=lcp[i-1])
            dq.pop_front();
        if(dq.size())R[i]=dq.front()-1;
            else R[i]=n;
        dq.push_front(i);
    }
    //for(int i=0;i<n;i++)cout<<L[i]<<" "<<R[i]<<endl;
    for(int i=1;i<=n;i++)
    {
        if(i!=1)
            u=n-sa[i-1]-max(lcp[i-1],lcp[i-2]);
                else u=n-sa[i-1]-lcp[i-1];
        ans+=u;
        if(check[lcp[i-1]]==ii{L[i],R[i]})continue;
        ll cnt=(R[i]-L[i]+2),len=lcp[R[i]];
        if(L[i]>1)len=max(len,(ll)lcp[L[i]-2]);
        len=lcp[i-1]-len;
        ans+=(cnt*cnt*len);
      //  cout<<i<<" "<<cnt<<" "<<len<<endl;
        check[lcp[i-1]]={L[i],R[i]};
    }
    cout<<ans<<"\n";
    }
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
namespace Sakurajima_Mai{
	//#pragma GCC optimize(2)
    //#pragma G++ optimize(2)
	#define ms(a) memset(a,0,sizeof(a))
	#define reg register
	#define repi(i,a,b) for(reg int i=a,bbb=b;i<=bbb;++i)//attention reg int or reg ll ?
	#define repd(i,a,b) for(reg int i=a,bbb=b;i>=bbb;--i)
	#define reps(s) for(reg int i=head[s],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
	#define ce(i,r) i==r?'\n':' '
	#define pb push_back
	#define all(x) x.begin(),x.end()
	#define gmn(a,b) a=min(a,b)
	#define gmx(a,b) a=max(a,b)
	#define fi first
	#define se second
	typedef long long ll;
	typedef unsigned long long ull;
	typedef double db;
	const int infi=2e9;
	const ll infl=4e18;
	inline ll ceil_div(ll a,ll b){ return (a+b-1)/b; }
	//std::mt19937 rnd(time(0));//std::mt19937_64 rnd(time(0));
}
using namespace Sakurajima_Mai;
namespace Fast_Read{
	inline int qi(){
	    int f=0,fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline ll ql(){
		ll f=0;int fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline db qd(){
	    char c=getchar();int flag=1;double ans=0;
	    while((!(c>='0'&&c<='9'))&&c!='-') c=getchar();
	    if(c=='-') flag=-1,c=getchar();
	    while(c>='0'&&c<='9') ans=ans*10+(c^48),c=getchar();
	    if(c=='.'){c=getchar();for(register int Bit=10;c>='0'&&c<='9';Bit=(Bit<<3)+(Bit<<1)) ans+=(double)(c^48)*1.0/Bit,c=getchar();}
	    return ans*flag;
	}
}
namespace Read{
	#define si(a) scanf("%d",&a)
	#define sl(a) scanf("%lld",&a)
	#define sd(a) scanf("%lf",&a)
	#define ss(a) scanf("%s",a)
	#define rai(x,a,b) repi(i,a,b) x[i]=qi()
	#define ral(x,a,b) repi(i,a,b) x[i]=ql()
}
namespace Out{
	#define pi(x) printf("%d",x)
	#define pl(x) printf("%lld",x)
	#define ps(x) printf("%s",x)
	#define pc(x) printf("%c",x)
}
namespace DeBug{
	#define pr(x) cout<<#x<<": "<<x<<endl
	#define pra(x,a,b) cout<<#x<<": "<<endl; \
			repi(i,a,b) cout<<x[i]<<" ";	 \
			puts("");
	#define FR(a) freopen(a,"r",stdin)
	#define FO(a) freopen(a,"w",stdout)
}
using namespace Fast_Read;
using namespace Read;
using namespace Out;
using namespace DeBug;
/*
root=1Îª¸ù£¬½Úµã1~siz¡£Ã¿¸ö½Úµã±íÊ¾µÄ²»Í¬×Ó´®¸öÊý=µ±Ç°½Úµãml-¸¸½Úµãml
Ïà¹ØÊý×éË«±¶´óÐ¡£¬ÍØÆËÐòºóRight¼´Îª¸Ã´®ÀàÖÐËùÓÐ´®³öÏÖ´ÎÊý
*/
const int MAX_N=1e5+5;
struct SAM{
	int root,last,siz;
	int nxt[MAX_N<<1][26],fa[MAX_N<<1],ml[MAX_N<<1];
	int Right[MAX_N<<1],cnt[MAX_N<<1],id[MAX_N<<1];
	void init()
	{
		root=last=siz=1;
		ml[root]=fa[root]=Right[root]=0;
		ms(nxt[root]);
	}
	void add(int c)
	{
		int p=last,np=++siz; ms(nxt[np]);
		last=np,ml[np]=ml[p]+1,Right[np]=1;
		for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=np;
		if(!p) fa[np]=root;
		else{
			int q=nxt[p][c];
			if(ml[p]+1==ml[q]) fa[np]=q;
			else{
				int nq=++siz;
				ml[nq]=ml[p]+1,Right[nq]=0;
				memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
				fa[nq]=fa[q],fa[q]=fa[np]=nq;
				for(;p&&nxt[p][c]==q;p=fa[p]) nxt[p][c]=nq;
			}
		}
	}
	void build(char *s)
	{
		init();
		int len=strlen(s+1);
		repi(i,1,len) add(s[i]-'a');
	}
	void toposort()
	{
		int ML=0;
		repi(i,1,siz) cnt[i]=0;
		repi(i,1,siz) cnt[ml[i]]++,gmx(ML,ml[i]);
		repi(i,1,ML) cnt[i]+=cnt[i-1];
		repi(i,1,siz) id[cnt[ml[i]]--]=i;
		repd(i,siz,1) Right[fa[id[i]]]+=Right[id[i]];
	}
	ll cal()
	{
		ll ans=0;
		repi(i,2,siz){
			ans+=Right[i]*Right[i]*(ml[i]-ml[fa[i]]);
		}
		return ans;
	}
}sam;
char s[MAX_N];
int main()
{
	int T=qi();
	while(T--)
	{
		 ss(s+1); sam.build(s),sam.toposort();
		 pl(sam.cal()),pc('\n');
	}
}


#include<bits/stdc++.h>
using namespace std;
namespace Sakurajima_Mai{
	//#pragma GCC optimize(2)
    //#pragma G++ optimize(2)
	#define ms(a) memset(a,0,sizeof(a))
	#define reg register
	#define repi(i,a,b) for(reg int i=a,bbb=b;i<=bbb;++i)//attention reg int or reg ll ?
	#define repd(i,a,b) for(reg int i=a,bbb=b;i>=bbb;--i)
	#define reps(s) for(reg int i=head[s],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
	#define ce(i,r) i==r?'\n':' '
	#define pb push_back
	#define all(x) x.begin(),x.end()
	#define gmn(a,b) a=min(a,b)
	#define gmx(a,b) a=max(a,b)
	#define fi first
	#define se second
	typedef long long ll;
	typedef unsigned long long ull;
	typedef double db;
	const int infi=2e9;
	const ll infl=4e18;
	inline ll ceil_div(ll a,ll b){ return (a+b-1)/b; }
	//std::mt19937 rnd(time(0));//std::mt19937_64 rnd(time(0));
}
using namespace Sakurajima_Mai;
namespace Fast_Read{
	inline int qi(){
	    int f=0,fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline ll ql(){
		ll f=0;int fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline db qd(){
	    char c=getchar();int flag=1;double ans=0;
	    while((!(c>='0'&&c<='9'))&&c!='-') c=getchar();
	    if(c=='-') flag=-1,c=getchar();
	    while(c>='0'&&c<='9') ans=ans*10+(c^48),c=getchar();
	    if(c=='.'){c=getchar();for(register int Bit=10;c>='0'&&c<='9';Bit=(Bit<<3)+(Bit<<1)) ans+=(double)(c^48)*1.0/Bit,c=getchar();}
	    return ans*flag;
	}
}
namespace Read{
	#define si(a) scanf("%d",&a)
	#define sl(a) scanf("%lld",&a)
	#define sd(a) scanf("%lf",&a)
	#define ss(a) scanf("%s",a)
	#define rai(x,a,b) repi(i,a,b) x[i]=qi()
	#define ral(x,a,b) repi(i,a,b) x[i]=ql()
}
namespace Out{
	#define pi(x) printf("%d",x)
	#define pl(x) printf("%lld",x)
	#define ps(x) printf("%s",x)
	#define pc(x) printf("%c",x)
}
namespace DeBug{
	#define pr(x) cout<<#x<<": "<<x<<endl
	#define pra(x,a,b) cout<<#x<<": "<<endl; \
			repi(i,a,b) cout<<x[i]<<" ";	 \
			puts("");
	#define FR(a) freopen(a,"r",stdin)
	#define FO(a) freopen(a,"w",stdout)
}
using namespace Fast_Read;
using namespace Read;
using namespace Out;
using namespace DeBug;
/*
root=1Îª¸ù£¬½Úµã1~siz¡£Ã¿¸ö½Úµã±íÊ¾µÄ²»Í¬×Ó´®¸öÊý=µ±Ç°½Úµãml-¸¸½Úµãml
Ïà¹ØÊý×éË«±¶´óÐ¡£¬ÍØÆËÐòºóRight¼´Îª¸Ã´®ÀàÖÐËùÓÐ´®³öÏÖ´ÎÊý
*/
const int MAX_N=1e5+5;
struct SAM{
	int root,last,siz;
	int nxt[MAX_N<<1][26],fa[MAX_N<<1],ml[MAX_N<<1];
	int Right[MAX_N<<1],cnt[MAX_N<<1],id[MAX_N<<1];
	void init()
	{
		root=last=siz=1;
		ml[root]=fa[root]=Right[root]=0;
		ms(nxt[root]);
	}
	void add(int c)
	{
		int p=last,np=++siz; ms(nxt[np]);
		last=np,ml[np]=ml[p]+1,Right[np]=1;
		for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=np;
		if(!p) fa[np]=root;
		else{
			int q=nxt[p][c];
			if(ml[p]+1==ml[q]) fa[np]=q;
			else{
				int nq=++siz;
				ml[nq]=ml[p]+1,Right[nq]=0;
				memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
				fa[nq]=fa[q],fa[q]=fa[np]=nq;
				for(;p&&nxt[p][c]==q;p=fa[p]) nxt[p][c]=nq;
			}
		}
	}
	void build(char *s)
	{
		init();
		int len=strlen(s+1);
		repi(i,1,len) add(s[i]-'a');
	}
	void toposort()
	{
		int ML=0;
		repi(i,1,siz) cnt[i]=0;
		repi(i,1,siz) cnt[ml[i]]++,gmx(ML,ml[i]);
		repi(i,1,ML) cnt[i]+=cnt[i-1];
		repi(i,1,siz) id[cnt[ml[i]]--]=i;
		repd(i,siz,1) Right[fa[id[i]]]+=Right[id[i]];
	}
	ll cal()
	{
		ll ans=0;
		repi(i,2,siz){
			ans+=1ll*Right[i]*Right[i]*(ml[i]-ml[fa[i]]);
		}
		return ans;
	}
}sam;
char s[MAX_N];
int main()
{
	int T=qi();
	while(T--)
	{
		 ss(s+1); sam.build(s),sam.toposort();
		 pl(sam.cal()),pc('\n');
	}
}


#include<bits/stdc++.h>
using namespace std;
namespace Sakurajima_Mai{
	//#pragma GCC optimize(2)
    //#pragma G++ optimize(2)
	#define ms(a) memset(a,0,sizeof(a))
	#define reg register
	#define repi(i,a,b) for(reg int i=a,bbb=b;i<=bbb;++i)//attention reg int or reg ll ?
	#define repd(i,a,b) for(reg int i=a,bbb=b;i>=bbb;--i)
	#define reps(s) for(reg int i=head[s],v=e[i].to;i;i=e[i].nxt,v=e[i].to)
	#define ce(i,r) i==r?'\n':' '
	#define pb push_back
	#define all(x) x.begin(),x.end()
	#define gmn(a,b) a=min(a,b)
	#define gmx(a,b) a=max(a,b)
	#define fi first
	#define se second
	typedef long long ll;
	typedef unsigned long long ull;
	typedef double db;
	const int infi=2e9;
	const ll infl=4e18;
	inline ll ceil_div(ll a,ll b){ return (a+b-1)/b; }
	//std::mt19937 rnd(time(0));//std::mt19937_64 rnd(time(0));
}
using namespace Sakurajima_Mai;
namespace Fast_Read{
	inline int qi(){
	    int f=0,fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline ll ql(){
		ll f=0;int fu=1; char c=getchar();
	    while(c<'0'||c>'9'){ if(c=='-')fu=-1; c=getchar(); }
	    while(c>='0'&&c<='9'){ f=(f<<3)+(f<<1)+c-48; c=getchar(); }
	    return f*fu;
	}
	inline db qd(){
	    char c=getchar();int flag=1;double ans=0;
	    while((!(c>='0'&&c<='9'))&&c!='-') c=getchar();
	    if(c=='-') flag=-1,c=getchar();
	    while(c>='0'&&c<='9') ans=ans*10+(c^48),c=getchar();
	    if(c=='.'){c=getchar();for(register int Bit=10;c>='0'&&c<='9';Bit=(Bit<<3)+(Bit<<1)) ans+=(double)(c^48)*1.0/Bit,c=getchar();}
	    return ans*flag;
	}
}
namespace Read{
	#define si(a) scanf("%d",&a)
	#define sl(a) scanf("%lld",&a)
	#define sd(a) scanf("%lf",&a)
	#define ss(a) scanf("%s",a)
	#define rai(x,a,b) repi(i,a,b) x[i]=qi()
	#define ral(x,a,b) repi(i,a,b) x[i]=ql()
}
namespace Out{
	#define pi(x) printf("%d",x)
	#define pl(x) printf("%lld",x)
	#define ps(x) printf("%s",x)
	#define pc(x) printf("%c",x)
}
namespace DeBug{
	#define pr(x) cout<<#x<<": "<<x<<endl
	#define pra(x,a,b) cout<<#x<<": "<<endl; \
			repi(i,a,b) cout<<x[i]<<" ";	 \
			puts("");
	#define FR(a) freopen(a,"r",stdin)
	#define FO(a) freopen(a,"w",stdout)
}
using namespace Fast_Read;
using namespace Read;
using namespace Out;
using namespace DeBug;
/*
root=1Îª¸ù£¬½Úµã1~siz¡£Ã¿¸ö½Úµã±íÊ¾µÄ²»Í¬×Ó´®¸öÊý=µ±Ç°½Úµãml-¸¸½Úµãml
Ïà¹ØÊý×éË«±¶´óÐ¡£¬ÍØÆËÐòºóRight¼´Îª¸Ã´®ÀàÖÐËùÓÐ´®³öÏÖ´ÎÊý
*/
const int MAX_N=1e5+5;
struct SAM{
	int root,last,siz;
	int nxt[MAX_N<<1][26],fa[MAX_N<<1],ml[MAX_N<<1];
	int Right[MAX_N<<1],cnt[MAX_N<<1],id[MAX_N<<1];
	void init()
	{
		root=last=siz=1;
		ml[root]=fa[root]=Right[root]=0;
		ms(nxt[root]);
	}
	void add(int c)
	{
		int p=last,np=++siz; ms(nxt[np]);
		last=np,ml[np]=ml[p]+1,Right[np]=1;
		for(;p&&!nxt[p][c];p=fa[p]) nxt[p][c]=np;
		if(!p) fa[np]=root;
		else{
			int q=nxt[p][c];
			if(ml[p]+1==ml[q]) fa[np]=q;
			else{
				int nq=++siz;
				ml[nq]=ml[p]+1,Right[nq]=0;
				memcpy(nxt[nq],nxt[q],sizeof(nxt[q]));
				fa[nq]=fa[q],fa[q]=fa[np]=nq;
				for(;p&&nxt[p][c]==q;p=fa[p]) nxt[p][c]=nq;
			}
		}
	}
	void build(char *s)
	{
		init();
		int len=strlen(s+1);
		repi(i,1,len) add(s[i]-'a');
	}
	void toposort()
	{
		int ML=0;
		repi(i,1,siz) cnt[i]=0,;
		repi(i,1,siz) cnt[ml[i]]++,gmx(ML,ml[i]);
		repi(i,1,ML) cnt[i]+=cnt[i-1];
		repi(i,1,siz) id[cnt[ml[i]]--]=i;
		repd(i,siz,1) Right[fa[id[i]]]+=Right[id[i]];
	}
	ll cal()
	{
		ll ans=0;
		repi(i,2,siz){
			ans+=1ll*Right[i]*Right[i]*(ml[i]-ml[fa[i]]);
		}
		return ans;
	}
}sam;
char s[MAX_N];
int main()
{
	int T=qi();
	while(T--)
	{
		 ss(s+1); sam.build(s),sam.toposort();
		 pl(sam.cal()),pc('\n');
	}
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <stdio.h>
#include <sstream>
#include <string>
#include <map>
#include <set>
#include <stdlib.h>
#include <cmath>
#include <math.h>
#include <fstream>
#include <bitset>
#include <time.h>
#define int long long
using namespace std;
int counter;
int go[200001][26];
int last;
int suf[200001], len[200001], ans[200001];
bool clodne[200001];
int reb;
map<int, int> num;
string id = "abcdefghijklmnopqrstuvwxyz";
void add(int number){
    int newlast = counter; len[newlast] = len[last] + 1; int p = last; counter++;
    while (p!=-1 && go[p][number] == -1){
        go[p][number] = newlast;
        reb ++;
        p = suf[p];
    }
    if (p == -1){
        suf[newlast] = 0;
    }
    else{
        int q = go[p][number];
        if (len[q] == len[p] + 1){
            suf[newlast] = q;
        }
        else{
            int r = counter; counter ++;
            clodne[r] = true;
            for (int i=0;i<26;i++){
                go[r][i] = go[q][i];
                if (go[r][i] != -1) reb++;
            }
            suf[r] = suf[q];
            suf[q] = r;
            suf[newlast] = r;
            len[r] = len[p] + 1;
            while (p!=-1 && go[p][number] == q){
                go[p][number] = r;
                p = suf[p];
            }
        }
    }
    last = newlast;
}
int32_t main()
{
    int m;
    cin >> m;
    for (int i=0;i<m;i++){
        string s;
        cin >> s;
        for (int j=0;j<200001;j++){
            clodne[j] = false;
            ans[j] = 1;
            suf[j] = -1;
            len[j] = -1;
            for (int k=0;k<26;k++){
                go[j][k] = -1;
            }
        }
        len[0] = 0;
        counter = 1;
        last = 0;
        for (int j=0;j<s.size();j++){
            for (int k=0;k<26;k++){
                if (id[k] == s[j]) add(k);
            }
        }
        reb = 0;
        vector<vector<int> > ll;
        for (int i=1;i<counter;i++){
            if (clodne[i]){
                ans[i] = 0;
            }
        }
        for (int i=1;i<counter;i++){
            vector<int> help; help.push_back(len[i]); help.push_back(i);
            ll.push_back(help);
        }
        sort(ll.begin(), ll.end(), greater<vector<int> > ());
        for (int i=0;i<ll.size();i++){
            int v = ll[i][1];
            ans[suf[v]] += ans[v];
        }
        vector<int> in;
        vector<int> zero, sz;
        for (int i=0;i<counter;i++){
            in.push_back(0);
            sz.push_back(0);
        }
        sz[0] = 1;
        zero.push_back(0);
        for (int i=0;i<counter;i++){
            for (int j=0;j<26;j++){
                if (go[i][j] != -1) in[go[i][j]] ++;
            }
        }
        while (zero.size() > 0){
            int v = zero.back();
            if (v != 0) reb += ans[v] * ans[v] * sz[v];
            zero.pop_back();
            for (int i=0;i<26;i++){
                if (go[v][i] != -1) {
                in[go[v][i]] --;
                sz[go[v][i]] += sz[v];
                if (in[go[v][i]] == 0){
                    zero.push_back(go[v][i]);
                }
                }
            }
        }
        cout << reb << endl;
    }
    return 0;
}