#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=100,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000){cout<<clock()<<'\n';return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_map<LL,int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=200,p;
LL ans=0,hs[N],P[N],IP[N];
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		++S[Hs];
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			p=S[Get(j,j+i)];
			f[j]+=p;g[j+i]+=p;
		}
	if (L>10){return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<LL> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=1,p;
LL ans=0,hs[N],P[N],IP[N];
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			p=S.count(Get(j,j+i));
			f[j]+=p;g[j+i]+=p;
		}
	if (L>10000){return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_map<LL,int> S;
unordered_set<LL> SS;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=250,p;
LL ans=0,hs[N],P[N],IP[N],x;
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		++S[Hs];SS.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			x=Get(j,j+i);if (!SS.count(x)) continue;
			p=S[Get(j,j+i)];f[j]+=p;g[j+i]+=p;
		}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=1ll*g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=400,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000) return 0;
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_map<LL,int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=400,p;
LL ans=0,hs[N],P[N],IP[N];
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		++S[Hs];
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			p=S[Get(j,j+i)];
			f[j]+=p;g[j+i]+=p;
		}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=1ll*g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=10,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	if (L>10000){cout<<clock()<<'\n';return 0;}
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000){cout<<clock()<<'\n';return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_map<LL,int> S;
unordered_set<LL> SS[205];
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=200,p;
LL ans=0,hs[N],P[N],IP[N],x;
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		++S[Hs];SS[l[i]].insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			x=Get(j,j+i);if (!SS[i+1].count(x)) continue;
			p=S[Get(j,j+i)];f[j]+=p;g[j+i]+=p;
		}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=1ll*g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=10,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000){cout<<clock()<<'\n';return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<LL> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=1,p;
LL ans=0,hs[N],P[N],IP[N];
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			p=S.count(Get(j,j+i));
			f[j]+=p;g[j+i]+=p;
		}
	if (L>10){return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_map<LL,int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=400,p;
LL ans=0,hs[N],P[N],IP[N];
inline LL Get(const int &l,const int &r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		++S[Hs];
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
			p=S[Get(j,j+i)];
			f[j]+=p;g[j+i]+=p;
		}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
			for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
			if (p<l[i]&&s[i][p+1]==t[j]) ++p;
			if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=350,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000) return 0;
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
#define N 200005
using namespace std;
typedef long long LL;
const LL mod=2147481811,k=233,inv=138249902;
template <typename T> void read(T &x){
	int f=1;x=0;char c=getchar();
	for (;!isdigit(c);c=getchar()) if (c=='-') f=-f;
	for (; isdigit(c);c=getchar()) x=x*10+c-'0';
	x*=f;
}
unordered_multiset<int> S;
string t,s[N];
int n,f[N],g[N],nxt[N],l[N],L,sz=1,p;
LL ans=0,hs[N],P[N],IP[N];
int Get(int l,int r){
	return IP[l-1]*(hs[r]-hs[l-1]+mod)%mod;
}
int main(){
	ios::sync_with_stdio(0);
	cin>>t;L=t.length();t='*'+t;cin>>n;
	P[0]=IP[0]=1;
	for (int i=1;i<=200000;++i)
		P[i]=P[i-1]*k%mod,IP[i]=IP[i-1]*inv%mod;
	for (int i=1;i<=n;++i) cin>>s[i],l[i]=s[i].length(),s[i]='*'+s[i];
	for (int i=1;i<=n;++i){
		if (l[i]>sz) continue;
		LL Hs=0;
		for (int j=1;j<=l[i];++j)
			Hs=(Hs+P[j-1]*s[i][j])%mod;
		S.insert(Hs);
	}
	for (int i=1;i<=L;++i) hs[i]=(hs[i-1]+P[i-1]*t[i])%mod;
	for (int i=0;i<sz;++i)
		for (int j=1;j+i<=L;++j){
		    p=S.count(Get(j,j+i));
		    f[j]+=p;g[j+i]+=p;
		}
	if (L>10000){cout<<clock()<<'\n';return 0;}
	for (int i=1;i<=n;++i){
		if (l[i]<=sz) continue;
		p=0;
		for (int j=2;j<=l[i];++j){
			for (;p&&s[i][p+1]!=s[i][j];p=nxt[p]);
			if (s[i][p+1]==s[i][j]) ++p; nxt[j]=p;
		}
		p=0;
		for (int j=1;j<=L;++j){
		    for (;p&&s[i][p+1]!=t[j];p=nxt[p]);
		    if (p<l[i]&&s[i][p+1]==t[j]) ++p;
		    if (p==l[i]) ++g[j],++f[j-l[i]+1];
		}
	}
	for (int i=1;i<L;++i) ans+=g[i]*f[i+1];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
LL cnt[N];
int ch[N][26],tot,fail[N];
LL ans;
vector<int>e[N];
// void clear(){
// 	tot=0;
// 	memset(cnt,0,sizeof(cnt));
// 	memset(ch,0,sizeof(ch));
// }
void insert(string str){
	int u=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c];
	}
	++cnt[u];
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
	for(int i=1;i<=tot;++i)e[fail[i]].pb(i);
}
void dfs(int u){
	for(int v:e[u])dfs(v),cnt[v]+=cnt[u];
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail(),dfs(0);
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// cout<<"fail:";for(int i=0;i<=tot;++i)cout<<fail[i]<<' ';cout<<'\n';
	// clear();
	// for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	// build_fail();
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
LL cnt[N];
int ch[N][26],tot,fail[N];
LL ans;
vector<int>e[N];
void clear(){
	for(int i=0;i<=tot;++i)e[i].clear();
	tot=0;
	memset(cnt,0,sizeof(cnt));
	memset(ch,0,sizeof(ch));
	memset(fail,0,sizeof(fail));
}
void insert(string str){
	int u=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c];
	}
	++cnt[u];
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
	for(int i=1;i<=tot;++i)e[fail[i]].pb(i);
}
void dfs(int u){
	for(int v:e[u])cnt[v]+=cnt[u],dfs(v);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail(),dfs(0);
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// cout<<"fail:";for(int i=0;i<=tot;++i)cout<<fail[i]<<' ';cout<<'\n';

	clear();
	for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	build_fail(),dfs(0);
	// for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];
	// cout<<"f:";for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// cout<<"g:";for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}
/*
abcdabcd
4
d
cd
a
ab

*/


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
int ch[N][26],tot,cnt[N],fail[N];
LL ans;
void clear(){
	tot=0;
	memset(cnt,0,sizeof(cnt));
	memset(ch,0,sizeof(ch));
}
void insert(string str){
	int u=0;LL sum=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c],sum+=cnt[u];
	}
	cnt[u]=sum+1;
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail();
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// clear();
	// for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	// build_fail();
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
int ch[N][26],tot,cnt[N],fail[N];
LL ans;
void clear(){
	tot=0;
	memset(cnt,0,sizeof(cnt));
	memset(ch,0,sizeof(ch));
}
void insert(string str){
	int u=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c];
	}
	++cnt[u];
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail();
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];

	clear();
	for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	build_fail();
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	printf("%lld\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
LL cntp[N];
int ch[N][26],tot,fail[N];
LL ans;
vector<int>e[N];
// void clear(){
// 	tot=0;
// 	memset(cnt,0,sizeof(cnt));
// 	memset(ch,0,sizeof(ch));
// }
void insert(string str){
	int u=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c];
	}
	++cnt[u];
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
	for(int i=1;i<=tot;++i)e[fail[i]].pb(i);
}
void dfs(int u){
	for(int v:e[u])cnt[v]+=cnt[u],dfs(v);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail(),dfs(0);
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// cout<<"fail:";for(int i=0;i<=tot;++i)cout<<fail[i]<<' ';cout<<'\n';
	// clear();
	// for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	// build_fail();
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
int rdc(){
	char ch=getchar();
	while(!isalpha(ch))ch=getchar();
	return ch-'a';
}
#define N 400005
int n,m,ch[N][26],ed[N],to[N],ln[N],rn[N],tmr,tr[N],tot,ans[N],fail[N],trie[N][26],cnt;
vector<int>e[N],q[N];
void insert(char*str,int id){
	int u=0;
	for(int i=0,len=strlen(str);i<len;++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++cnt;
		u=ch[u][c];
	}
	ed[id]=u;
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
	for(int i=1;i<=cnt;++i)e[fail[i]].pb(i);
}
void dfs1(int u){
	ln[u]=++tmr;
	for(int v:e[u])dfs1(v);
	rn[u]=tmr;
}
void add(int x,int d){if(!x)return;for(int i=x;i<=tmr;i+=i&-i)tr[i]+=d;}
int ask(int x){int res=0;for(int i=x;i>0;i-=i&-i)res+=tr[i];return res;}
void dfs2(int u1,int u2){
	// cerr<<"dfs2:"<<u1<<' '<<u2<<'\n';
	// cerr<<u2<<' '<<ln[u2]<<'\n';
	add(ln[u2],1);
	for(int i:q[u1])ans[i]=ask(rn[ed[i]])-ask(ln[ed[i]]-1);
	for(int i=0;i<26;++i)if(trie[u1][i])dfs2(trie[u1][i],ch[u2][i]);
	add(ln[u2],-1);
}
signed main(){
	n=read();
	for(int i=1;i<=n;++i){
		int op=read(),pre=0,x;
		if(op==2)pre=read();
		x=rdc();
		if(!trie[to[pre]][x])trie[to[pre]][x]=++tot;
		to[i]=trie[to[pre]][x];
	}
	m=read();
	for(int i=1;i<=m;++i){
		int x=read();static char str[N];
		scanf("%s",str);
		insert(str,i),q[to[x]].pb(i);
	}
	// cerr<<"qwq\n";
	build_fail(),dfs1(0),dfs2(0,0);
	for(int i=1;i<=m;++i)printf("%d\n",ans[i]);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
int ch[N][26],tot,cnt[N],fail[N];
LL ans;
void clear(){
	tot=0;
	memset(cnt,0,sizeof(cnt));
	memset(ch,0,sizeof(ch));
}
void insert(string str){
	int u=0,sum=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c],sum+=cnt[u];
	}
	cnt[u]=sum+1;
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail();
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// clear();
	// for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	// build_fail();
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef double db;
#define x first
#define y second
#define sz(v) (int)v.size()
#define pb(x) push_back(x)
#define mkp(x,y) make_pair(x,y)
inline int read(){
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)){if(c=='-')f=0;c=getchar();}
	while(isdigit(c))x=x*10+c-'0',c=getchar();
	return f?x:-x;
}
#define N 200005
string T,str[N];
int n,f[N],g[N];
LL cnt[N];
int ch[N][26],tot,fail[N];
LL ans;
vector<int>e[N];
// void clear(){
// 	tot=0;
// 	memset(cnt,0,sizeof(cnt));
// 	memset(ch,0,sizeof(ch));
// }
void insert(string str){
	int u=0;
	for(int i=0;i<sz(str);++i){
		int c=str[i]-'a';
		if(!ch[u][c])ch[u][c]=++tot;
		u=ch[u][c];
	}
	++cnt[u];
}
void build_fail(){
	queue<int>q;
	for(int i=0;i<26;++i)if(ch[0][i])q.push(ch[0][i]);
	while(!q.empty()){
		int u=q.front();q.pop();
		for(int i=0;i<26;++i)
			if(ch[u][i])fail[ch[u][i]]=ch[fail[u]][i],q.push(ch[u][i]);
			else ch[u][i]=ch[fail[u]][i];
	}
	for(int i=1;i<=tot;++i)e[fail[i]].pb(i);
}
void dfs(int u){
	for(int v:e[u])cnt[v]+=cnt[u],dfs(v);
}
signed main(){
	ios::sync_with_stdio(0);
	cin.tie(0),cout.tie(0);
	cin>>T>>n;
	for(int i=1;i<=n;++i)cin>>str[i];

	for(int i=1;i<=n;++i)insert(str[i]);
	build_fail(),dfs(0);
	for(int u=0,i=0;i<sz(T);++i)u=ch[u][T[i]-'a'],f[i]=cnt[u];
	// cout<<"cnt:";for(int i=0;i<=tot;++i)cout<<cnt[i]<<' ';cout<<'\n';
	// cout<<"fail:";for(int i=0;i<=tot;++i)cout<<fail[i]<<' ';cout<<'\n';
	// clear();
	// for(int i=1;i<=n;++i)reverse(str[i].begin(),str[i].end()),insert(str[i]);
	// build_fail();
	for(int u=0,i=sz(T)-1;~i;--i)u=ch[u][T[i]-'a'],g[i]=cnt[u];

	// for(int i=0;i<sz(T);++i)cout<<f[i]<<' ';cout<<'\n';
	// for(int i=0;i<sz(T);++i)cout<<g[i]<<' ';cout<<'\n';

	for(int i=1;i<sz(T);++i)ans+=1ll*f[i-1]*g[i];
	cout<<ans<<'\n';
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rg register
inline int read(){
	rg char ch=getchar();
	rg int x=0,f=0;
	while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
#define N 200010
int tr[2][N][26];
long long sum[2][N];
int cnt[2];
int fail[2][N];
char ss1[N],ss2[N];
char s1[N],s2[N];
long long ans1[N],ans2[N];
int n;
void insert(char *s,int k){
	int _n=strlen(s),p=0;
	for(int c,i=0;i<_n;++i){
		c=s[i]-'a';
		if(!tr[k][p][c]) tr[k][p][c]=++cnt[k];
		p=tr[k][p][c];
	}
	++sum[k][p];
}
void get_fail(int k){
	queue<int> q;
	for(int i=0;i<26;++i) if(tr[k][0][i]) q.push(tr[k][0][i]);
	while(!q.empty()){
		int p=q.front();q.pop();
		sum[k][p]+=sum[k][fail[k][p]];
		for(int i=0;i<26;++i){
			if(tr[k][p][i]){
				fail[k][tr[k][p][i]]=tr[k][fail[k][p]][i];
				q.push(tr[k][p][i]);
			}else tr[k][p][i]=tr[k][fail[k][p]][i];
		}
	}
}
inline void work(char *s,char *ss){
	int n=strlen(ss);
	int num=0;
	for(int i=n-1;~i;--i) s[num++]=ss[i];
}
int main(){
	ios::sync_with_stdio(0);
	scanf("%s",ss1);
	n=read();
	for(int i=1;i<=n;++i){
		scanf("%s",s1);
		insert(s1,0);
		work(s2,s1);
		insert(s2,1);
	}
	get_fail(0);get_fail(1);
	int p=0;
	int len=strlen(ss1);
	for(int i=0;i<len;++i){
		p=tr[0][p][ss1[i]-'a'];
		ans1[i]=sum[0][p];
	}
	p=0;
	for(int i=len-1;~i;--i){
		p=tr[1][p][ss1[i]-'a'];
		ans2[i]=sum[1][p];
	}
	//for(int i=0;i<len;++i) cout<<ans1[i]<<" "<<ans2[i]<<endl;
	long long totol=0;
	for(int i=0,il=len-1;i<il;++i){
		totol+=(ans1[i]*ans2[i+1]);
	}
	cout<<totol<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
inline int read()
{
	int x=0,f=1;
	char ch;
	for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
	if(ch=='-') f=0,ch=getchar();
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?x:-x;
}
char txt[200010],s[200010];
int n,len,tot[2];
long long ret;
struct node
{
	int size,son[26],fail;
}tire[200010][2];
int f[200010][2];
inline void build(int k,int len)
{
	int now=0;
	for(int i=0;i<len;++i)
	{
		if(!tire[now][k].son[s[i]-'a'])
			tire[now][k].son[s[i]-'a']=++tot[k];
		now=tire[now][k].son[s[i]-'a'];
	}
	++tire[now][k].size;
}
inline void get_fail(int k)
{
	queue<int> q;
	for(int i=0;i<26;++i)
	{
		if(tire[0][k].son[i])
		{
			tire[tire[0][k].son[i]][k].fail=0;
			q.push(tire[0][k].son[i]);
		}
	}
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=0;i<26;++i)
		{
			int t=tire[now][k].son[i];
			int f=tire[now][k].fail;
			if(tire[now][k].son[i])
			{
				tire[t][k].fail=tire[f][k].son[i];
				tire[t][k].size+=tire[tire[t][k].fail][k].size;
				q.push(t);
			}
			else tire[now][k].son[i]=tire[tire[now][k].fail][k].son[i];
		}
	}
}
inline void ackmp(int k)
{
	int now=0;
	for(int i=0;i<len;++i)
	{
		now=tire[now][k].son[txt[i]-'a'];
		f[i][k]=tire[now][k].size;
	}
}
signed main()
{
	cin>>txt;
	n=read();
	while(n--)
	{
		cin>>s;
		len=strlen(s);
		build(0,len);
		reverse(s,s+len);
		build(1,len);
	}
	get_fail(0);
	get_fail(1);
	memset(f,-1,sizeof(f));
	len=strlen(txt);
	ackmp(0);
	reverse(txt,txt+len);
	ackmp(1);
	for(int i=0;i<len;++i)
	{
		ret+=(1ll*f[i][0]*f[len-i-2][1]);
	}
	printf("%lld\n",ret);
return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long

inline int in{
	int s=0,f=1;char x;
	for(x=getchar();x<'0'||x>'9';x=getchar())	if(x=='-')	f=-1;
	for( ;x>='0'&&x<='9';x=getchar())	s=(s*10)+(x&15);
	return f==1?s:-s;
}

const int A=1e6+5;
int n;
struct ACM{
	char bk[A];
	char nw[A];
	int tr[A][26],tot;
	int val[A];
	int fail[A],last[A];
	int ans[A];
	inline void build(){
		int len=strlen(nw);
		int p=0;
		for(int i=0;i<len;i++){
			if(!tr[p][nw[i]-'a'])	tr[p][nw[i]-'a']=++tot;
			p=tr[p][nw[i]-'a'];
		}
		val[p]++;
		return;
	}
	inline void acm(){
		queue <int> q;
		int p=0;
		for(int i=0;i<26;i++){
			p=tr[0][i];
			if(!p)	continue;
			q.push(p);
			fail[p]=last[p]=0;
		}
		while(!q.empty()){
			int x=q.front();q.pop();
			for(int i=0;i<26;i++){
				p=tr[x][i];
				if(!p){
					tr[x][i]=tr[fail[x]][i];
					continue;
				}
				q.push(p);
				int w=fail[x];
				while(w&&!tr[w][i])	w=fail[w];
				fail[p]=tr[w][i];
				last[p]=val[fail[p]]?fail[p]:last[fail[p]];
			}
		}
		return;
	}
	inline void find(){
		int len=strlen(bk);
		int p=0;
		for(int i=0;i<len;i++){
			p=tr[p][bk[i]-'a'];
			int res=0;
			int w=val[p]?p:last[p];
			while(w){
				res+=val[w];
				w=last[w];
			}
			ans[i]=res;
		}
		return;
	}
}tr1,tr2;

int res=0;
inline void get_ans(){
	int len=strlen(tr1.bk);
	for(int i=0;i<len-1;i++)
		res+=tr1.ans[i]*tr2.ans[len-i-2];
	return;
}

signed main(){
	scanf("%s",tr1.bk);
	memcpy(tr2.bk,tr1.bk,sizeof(tr2.bk));
	reverse(tr2.bk,tr2.bk+strlen(tr2.bk));
//	cout<<tr2.bk<<'\n';
	n=in;
	for(int i=1;i<=n;i++){
		scanf("%s",tr1.nw);
		tr1.build();
		memcpy(tr2.nw,tr1.nw,sizeof(tr2.nw));
		reverse(tr2.nw,tr2.nw+strlen(tr2.nw));
		tr2.build();
	}
	tr1.acm();
	tr2.acm();
	tr1.find();
	tr2.find();
//	for(int i=0;i<strlen(tr1.bk);i++)
//		printf("%d %d\n",tr1.ans[i],tr2.ans[i]);
	get_ans();
	printf("%lld\n",res);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define rg register
inline int read(){
	rg char ch=getchar();
	rg int x=0,f=0;
	while(!isdigit(ch)) f|=(ch=='-'),ch=getchar();
	while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
	return f?-x:x;
}
#define N 200010
int tr[2][N][26];
long long sum[2][N];
int cnt[2];
int fail[2][N];
char ss1[N],ss2[N];
char s1[N],s2[N];
long long ans1[N],ans2[N];
int n;
void insert(char *s,int k){
	int _n=strlen(s),p=0;
	for(int c,i=0;i<_n;++i){
		c=s[i]-'a';
		if(!tr[k][p][c]) tr[k][p][c]=++cnt[k];
		p=tr[k][p][c];
	}
	++sum[k][p];
}
void get_fail(int k){
	queue<int> q;
	for(int i=0;i<26;++i) if(tr[k][0][i]) q.push(tr[k][0][i]);
	while(!q.empty()){
		int p=q.front();q.pop();
		//sum[k][p]+=sum[k][fail[k][p]];
		for(int i=0;i<26;++i){
			if(tr[k][p][i]){
				fail[k][tr[k][p][i]]=tr[k][fail[k][p]][i];
				sum[k][tr[k][p][i]]+=sum[k][tr[k][fail[k][p]][i]];
				q.push(tr[k][p][i]);
			}else tr[k][p][i]=tr[k][fail[k][p]][i];
		}
	}
}
inline void work(char *s,char *ss){
	int n=strlen(ss);
	int num=0;
	for(int i=n-1;~i;--i) s[num++]=ss[i];
}
int main(){
	ios::sync_with_stdio(0);
	scanf("%s",ss1);
	n=read();
	for(int i=1;i<=n;++i){
		scanf("%s",s1);
		insert(s1,0);
		work(s2,s1);
		insert(s2,1);
	}
	get_fail(0);get_fail(1);
	int p=0;
	int len=strlen(ss1);
	for(int i=0;i<len;++i){
		p=tr[0][p][ss1[i]-'a'];
		ans1[i]=sum[0][p];
	}
	p=0;
	for(int i=len-1;~i;--i){
		p=tr[1][p][ss1[i]-'a'];
		ans2[i]=sum[1][p];
	}
	//for(int i=0;i<len;++i) cout<<ans1[i]<<" "<<ans2[i]<<endl;
	long long totol=0;
	for(int i=0,il=len-1;i<il;++i){
		totol+=(ans1[i]*ans2[i+1]);
	}
	cout<<totol<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
	int x=0,f=1;
	char ch;
	for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
	if(ch=='-') f=0,ch=getchar();
	while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
	return f?x:-x;
}
char txt[200010],s[200010];
int n,len,tot[2],ret;
struct node
{
	int size,son[26],fail;
}tire[500010][2];
int f[500010][2];
inline void build(int k,int len)
{
	int now=0;
	for(int i=0;i<len;++i)
	{
		if(!tire[now][k].son[s[i]-'a'])
			tire[now][k].son[s[i]-'a']=++tot[k];
		now=tire[now][k].son[s[i]-'a'];
	}
	++tire[now][k].size;
}
inline void get_fail(int k)
{
	queue<int> q;
	for(int i=0;i<26;++i)
	{
		if(tire[0][k].son[i])
		{
			tire[tire[0][k].son[i]][k].fail=0;
			q.push(tire[0][k].son[i]);
		}
	}
	while(!q.empty())
	{
		int now=q.front();
		q.pop();
		for(int i=0;i<26;++i)
		{
			int t=tire[now][k].son[i];
			int f=tire[now][k].fail;
			if(tire[now][k].son[i])
			{
				tire[t][k].fail=tire[f][k].son[i];
				tire[t][k].size+=tire[tire[t][k].fail][k].size;
				q.push(t);
			}
			else tire[now][k].son[i]=tire[tire[now][k].fail][k].son[i];
		}
	}
}
inline void ackmp(int k)
{
	int now=0;
	for(int i=0;i<len;++i)
	{
		now=tire[now][k].son[txt[i]-'a'];
		f[i][k]=tire[now][k].size;
	}
}
signed main()
{
	cin>>txt;
	n=read();
	while(n--)
	{
		cin>>s;
		len=strlen(s);
		build(0,len);
		reverse(s,s+len);
		build(1,len);
	}
	get_fail(0);
	get_fail(1);
	memset(f,-1,sizeof(f));
	len=strlen(txt);
	ackmp(0);
	reverse(txt,txt+len);
	ackmp(1);
	for(int i=0;i<len;++i)
	{
		ret+=(f[i][0]*f[len-i-2][1]);
	}
	printf("%lld\n",ret);
return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define in Read()
#define int long long

inline int in{
	int s=0,f=1;char x;
	for(x=getchar();x<'0'||x>'9';x=getchar())	if(x=='-')	f=-1;
	for( ;x>='0'&&x<='9';x=getchar())	s=(s*10)+(x&15);
	return f==1?s:-s;
}

const int A=3e5+5;
int n;
struct ACM{
	char bk[A];
	char nw[A];
	int tr[A][26],tot;
	int val[A];
	int fail[A],last[A];
	int ans[A];
	inline void build(){
		int len=strlen(nw);
		int p=0;
		for(int i=0;i<len;i++){
			if(!tr[p][nw[i]-'a'])	tr[p][nw[i]-'a']=++tot;
			p=tr[p][nw[i]-'a'];
		}
		val[p]++;
		return;
	}
	inline void acm(){
		queue <int> q;
		int p=0;
		for(int i=0;i<26;i++){
			p=tr[0][i];
			if(!p)	continue;
			q.push(p);
			fail[p]=last[p]=0;
		}
		while(!q.empty()){
			int x=q.front();q.pop();
			for(int i=0;i<26;i++){
				p=tr[x][i];
				if(!p){
					tr[x][i]=tr[fail[x]][i];
					continue;
				}
				q.push(p);
				int w=fail[x];
				while(w&&!tr[w][i])	w=fail[w];
				fail[p]=tr[w][i];
				last[p]=val[fail[p]]?fail[p]:last[fail[p]];
			}
		}
		return;
	}
	inline void find(){
		int len=strlen(bk);
		int p=0;
		for(int i=0;i<len;i++){
			p=tr[p][bk[i]-'a'];
			int res=0;
			int w=val[p]?p:last[p];
			while(w){
				res+=val[w];
				w=last[w];
			}
			ans[i]=res;
		}
		return;
	}
}tr1,tr2;

int res=0;
inline void get_ans(){
	int len=strlen(tr1.bk);
	for(int i=0;i<len-1;i++)
		res+=tr1.ans[i]*tr2.ans[len-i-2];
	return;
}

signed main(){
	scanf("%s",tr1.bk);
	memcpy(tr2.bk,tr1.bk,sizeof(tr2.bk));
	reverse(tr2.bk,tr2.bk+strlen(tr2.bk));
	n=in;
	for(int i=1;i<=n;i++){
		scanf("%s",tr1.nw);
		tr1.build();
		memcpy(tr2.nw,tr1.nw,sizeof(tr2.nw));
		reverse(tr2.nw,tr2.nw+strlen(tr2.nw));
		tr2.build();
	}
	tr1.acm();
	tr2.acm();
	tr1.find();
	tr2.find();
	get_ans();
	printf("%lld\n",res);
	return 0;
}


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

const int MAX=2e5+5;
int n,len,top=0,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int f1[MAX],f2[MAX];
int64_t rs=0;
char S[MAX];
string s[MAX];
queue<int> Q;
vector<int> g[MAX];

void Add(int id,string str)
{
    int tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int u=Q.front();
        Q.pop();
        for(int i=0;i<26;i++)
            if(tree[u][i]!=0)
            {
                int v=tree[u][i];
                int tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
    for(int i=1;i<=top;i++)
        g[i].clear();
    for(int i=1;i<=top;i++)
        g[kmp[i]].push_back(i);
}

void DFS(int u,int high,int sum)
{
    sum+=stop[u];
    h[u]=sum;
    for(int v:g[u])
        DFS(v,high+1,sum);
}

void Process()
{
    for(int i=1;i<=top;i++)
    {
        stop[i]=0;
        for(int j=0;j<26;j++)
            tree[i][j]=0;
    }
    top=1;
    for(int i=1;i<=n;i++)
        Add(i,s[i]);
    BuildAho();
    BuildGraph();
    DFS(1,0,0);
    int tmp=1;
    for(int i=1;i<=len;i++)
    {
        if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    // freopen("E.inp","r",stdin);
    cin>>(S+1)>>n;
    len=strlen(S+1);
    for(int i=1;i<=n;i++)
        cin>>s[i];
    Process();
    for(int i=1;i<=len;i++)
        f1[i]=f2[i];
    reverse(S+1,S+len+1);
    for(int i=1;i<=n;i++)
        reverse(s[i].begin(),s[i].end());
    Process();
    reverse(f2+1,f2+len+1);
    for(int i=1;i<len;i++)
        rs+=int64_t(f1[i])*int64_t(f2[i+1]);
    cout<<rs;
}


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

const int64_t MAX=2e5+5;
int64_t n,len,top,rs=0,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int64_t f1[MAX],f2[MAX];
char S[MAX];
string s[MAX];
queue<int64_t> Q;
vector<int64_t> g[MAX];

void Add(int64_t id,string str)
{
    int64_t tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int64_t u=Q.front();
        Q.pop();
        for(int64_t i=0;i<26;i++)
            if(tree[u][i]!=0)
            {
                int64_t v=tree[u][i];
                int64_t tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
    for(int64_t i=1;i<=top;i++)
        g[i].clear();
    for(int64_t i=1;i<=top;i++)
        g[kmp[i]].push_back(i);
}

void DFS(int64_t u,int64_t high,int64_t sum)
{
    sum+=stop[u];
    h[u]=sum;
    for(int64_t v:g[u])
        DFS(v,high+1,sum);
}

void Process()
{
    top=1;
    for(int64_t i=1;i<=n;i++)
        Add(i,s[i]);
    BuildAho();
    BuildGraph();
    DFS(1,0,0);
    int64_t tmp=1;
    for(int64_t i=1;i<=len;i++)
    {
        if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    // freopen("E.inp","r",stdin);
    cin>>(S+1)>>n;
    len=strlen(S+1);
    for(int64_t i=1;i<=n;i++)
        cin>>s[i];
    Process();
    for(int64_t i=1;i<=len;i++)
        f1[i]=f2[i];
    reverse(S+1,S+len+1);
    for(int64_t i=1;i<=n;i++)
        reverse(s[i].begin(),s[i].end());
    Process();
    reverse(f2+1,f2+len+1);
    for(int64_t i=1;i<len;i++)
        rs+=f1[i]*f2[i+1];
    cout<<rs;
}


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

const int MAX=2e5+5;
int n,len,top,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int64_t rs=0;
int f1[MAX],f2[MAX];
char S[MAX];
string s[MAX];
queue<int> Q;
vector<int> g[MAX];

void Add(int id,string str)
{
    int tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int u=Q.front();
        Q.pop();
        for(int i=0;i<52;i++)
            if(tree[u][i]!=0)
            {
                int v=tree[u][i];
                int tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
	for(int i=1;i<=top;i++)
		g[i].clear();
	for(int i=1;i<=top;i++)
		g[kmp[i]].push_back(i);
}

void DFS(int u,int high,int sum)
{
	sum+=stop[u];
	h[u]=sum;
	for(int v:g[u])
		DFS(v,high+1,sum);
}

void Process()
{
	top=1;
	for(int i=1;i<=n;i++)
		Add(i,s[i]);
	BuildAho();
	BuildGraph();
	DFS(1,0,0);
	int tmp=1;
	for(int i=1;i<=len;i++)
	{
		if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	// freopen("E.inp","r",stdin);
	cin>>(S+1)>>n;
	len=strlen(S+1);
	for(int i=1;i<=n;i++)
		cin>>s[i];
	Process();
	for(int i=1;i<=len;i++)
		f1[i]=f2[i];
	reverse(S+1,S+len+1);
	for(int i=1;i<=n;i++)
		reverse(s[i].begin(),s[i].end());
	Process();
	reverse(f2+1,f2+len+1);
	for(int i=1;i<len;i++)
		rs+=int64_t(f1[i])*int64_t(f2[i+1]);
	cout<<rs;
}


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

const int64_t MAX=2e5+5;
int64_t n,len,top,rs=0,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int64_t f1[MAX],f2[MAX];
char S[MAX];
string s[MAX];
queue<int64_t> Q;
vector<int64_t> g[MAX];

void Add(int64_t id,string str)
{
    int64_t tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int64_t u=Q.front();
        Q.pop();
        for(int64_t i=0;i<52;i++)
            if(tree[u][i]!=0)
            {
                int64_t v=tree[u][i];
                int64_t tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
	for(int64_t i=1;i<=top;i++)
		g[i].clear();
	for(int64_t i=1;i<=top;i++)
		g[kmp[i]].push_back(i);
}

void DFS(int64_t u,int64_t high,int64_t sum)
{
	sum+=stop[u];
	h[u]=sum;
	for(int64_t v:g[u])
		DFS(v,high+1,sum);
}

void Process()
{
	top=1;
	for(int64_t i=1;i<=n;i++)
		Add(i,s[i]);
	BuildAho();
	BuildGraph();
	DFS(1,0,0);
	int64_t tmp=1;
	for(int64_t i=1;i<=len;i++)
	{
		if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	// freopen("E.inp","r",stdin);
	cin>>(S+1)>>n;
	len=strlen(S+1);
	for(int64_t i=1;i<=n;i++)
		cin>>s[i];
	Process();
	for(int64_t i=1;i<=len;i++)
		f1[i]=f2[i];
	reverse(S+1,S+len+1);
	for(int64_t i=1;i<=n;i++)
		reverse(s[i].begin(),s[i].end());
	Process();
	reverse(f2+1,f2+len+1);
	for(int64_t i=1;i<len;i++)
		rs+=f1[i]*f2[i+1];
	cout<<rs;
}


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

const int MAX=2e5+5;
int n,len,top,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int f1[MAX],f2[MAX];
int64_t rs=0;
char S[MAX];
string s[MAX];
queue<int> Q;
vector<int> g[MAX];

void Add(int id,string str)
{
    int tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int u=Q.front();
        Q.pop();
        for(int i=0;i<26;i++)
            if(tree[u][i]!=0)
            {
                int v=tree[u][i];
                int tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
    for(int i=1;i<=top;i++)
        g[i].clear();
    for(int i=1;i<=top;i++)
        g[kmp[i]].push_back(i);
}

void DFS(int u,int high,int sum)
{
    sum+=stop[u];
    h[u]=sum;
    for(int v:g[u])
        DFS(v,high+1,sum);
}

void Process()
{
    top=1;
    for(int i=1;i<=n;i++)
        Add(i,s[i]);
    BuildAho();
    BuildGraph();
    DFS(1,0,0);
    int tmp=1;
    for(int i=1;i<=len;i++)
    {
        if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    // freopen("E.inp","r",stdin);
    cin>>(S+1)>>n;
    len=strlen(S+1);
    for(int i=1;i<=n;i++)
        cin>>s[i];
    Process();
    for(int i=1;i<=len;i++)
        f1[i]=f2[i];
    reverse(S+1,S+len+1);
    for(int i=1;i<=n;i++)
        reverse(s[i].begin(),s[i].end());
    Process();
    reverse(f2+1,f2+len+1);
    for(int i=1;i<len;i++)
        rs+=int64_t(f1[i])*int64_t(f2[i+1]);
    cout<<rs;
}


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

const int64_t MAX=4e5+5;
int64_t n,len,top,rs=0,kmp[MAX],h[MAX],stop[MAX],tree[MAX][26];
int64_t f1[MAX],f2[MAX];
char S[MAX];
string s[MAX];
queue<int64_t> Q;
vector<int64_t> g[MAX];

void Add(int64_t id,string str)
{
    int64_t tmp=1;
    for(auto c:str)
    {
        if(tree[tmp][c-'a']==0)
            tree[tmp][c-'a']=++top;
        tmp=tree[tmp][c-'a'];
    }
    stop[tmp]++;
}

void BuildAho()
{
    Q.push(1);
    while(Q.size()>0)
    {
        int64_t u=Q.front();
        Q.pop();
        for(int64_t i=0;i<52;i++)
            if(tree[u][i]!=0)
            {
                int64_t v=tree[u][i];
                int64_t tmp=kmp[u];
                while(tmp!=0&&tree[tmp][i]==0)
                    tmp=kmp[tmp];
                if(tmp==0)
                    kmp[v]=1;
                else
                    kmp[v]=tree[tmp][i];
                Q.push(v);
            }
    }
}

void BuildGraph()
{
	for(int64_t i=1;i<=top;i++)
		g[i].clear();
	for(int64_t i=1;i<=top;i++)
		g[kmp[i]].push_back(i);
}

void DFS(int64_t u,int64_t high,int64_t sum)
{
	sum+=stop[u];
	h[u]=sum;
	for(int64_t v:g[u])
		DFS(v,high+1,sum);
}

void Process()
{
	top=1;
	for(int64_t i=1;i<=n;i++)
		Add(i,s[i]);
	BuildAho();
	BuildGraph();
	DFS(1,0,0);
	int64_t tmp=1;
	for(int64_t i=1;i<=len;i++)
	{
		if(tree[tmp][S[i]-'a']!=0)
            tmp=tree[tmp][S[i]-'a'];
        else
        {
            tmp=kmp[tmp];
            while(tmp!=0&&tree[tmp][S[i]-'a']==0)
                tmp=kmp[tmp];
            if(tmp==0)
                tmp=1;
            else
                tmp=tree[tmp][S[i]-'a'];
        }
        f2[i]=h[tmp];
	}
}

int main()
{
	ios_base::sync_with_stdio(false);
	// freopen("E.inp","r",stdin);
	cin>>(S+1)>>n;
	len=strlen(S+1);
	for(int64_t i=1;i<=n;i++)
		cin>>s[i];
	Process();
	for(int64_t i=1;i<=len;i++)
		f1[i]=f2[i];
	reverse(S+1,S+len+1);
	for(int64_t i=1;i<=n;i++)
		reverse(s[i].begin(),s[i].end());
	Process();
	reverse(f2+1,f2+len+1);
	for(int64_t i=1;i<len;i++)
		rs+=f1[i]*f2[i+1];
	cout<<rs;
}


#include <bits/stdc++.h>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	ll leafCount = 0;
	int children[26];

	trieNode()
	{
		fill( begin(children), end(children), -1 );
	}
};

vector<trieNode> t(1);

void trie_insert(string s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].children[c] == -1 )
		{
			t[v].children[c] = t.size();
			t.pb();
		}
		v = t[v].children[c];
	}
	t[v].leaf = true;
	t[v].leafCount = t[v].leafCount + 1;
}

string vs[200010];
ll occ[200010], sum[200010];
int z[2000010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int minSz = 550;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < minSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[ oriIdx ]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */
    n = s.size();
   	for (int i = 0; i < n; i++)
   	{
   		int v = 0;
   		for (int j = i; j < n; j++)
   		{
   			int c = s[j] - 'a';
   			v = t[v].children[c];
   			if (v == -1) break;
   			sum[i] += t[v].leafCount;
   			occ[j+1] += t[v].leafCount;
   		}
   	}

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;
using namespace __gnu_pbds;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	ll leafCount = 0;
	int children[26];

	trieNode()
	{
		fill( begin(children), end(children), -1 );
	}
};

vector<trieNode> t(1);

void trie_insert(string s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].children[c] == -1 )
		{
			t[v].children[c] = t.size();
			t.pb();
		}
		v = t[v].children[c];
	}
	t[v].leaf = true;
	t[v].leafCount++;
}

string vs[200010];
ll occ[200010], sum[200010];
int z[200010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int minSz = 550;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < minSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[ oriIdx ]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */
    n = s.size();
   	for (int i = 0; i < n; i++)
   	{
   		int v = 0;
   		for (int j = i; j < n; j++)
   		{
   			int c = s[j] - 'a';
   			v = t[v].children[c];
   			if (v == -1) break;
   			if (t[v].leaf)
   			{
   				sum[i] += t[v].leafCount;
   				occ[j+1] += t[v].leafCount;
   			}
   		}
   	}

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


#include <bits/stdc++.h>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	ll leafCount = 0;
	int children[26];

	trieNode()
	{
		fill( begin(children), end(children), -1 );
	}
};

vector<trieNode> t(1);

void trie_insert(string s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].children[c] == -1 )
		{
			t[v].children[c] = t.size();
			t.pb();
		}
		v = t[v].children[c];
	}
	t[v].leaf = true;
	t[v].leafCount = t[v].leafCount + 1;
}

string vs[200010];
ll occ[200010], sum[200010];
int z[200010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int minSz = 550;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < minSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[ oriIdx ]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */
    n = s.size();
   	for (int i = 0; i < n; i++)
   	{
   		int v = 0;
   		for (int j = i; j < n; j++)
   		{
   			int c = s[j] - 'a';
   			v = t[v].children[c];
   			if (v == -1) break;
   			sum[i] += t[v].leafCount;
   			occ[j+1] += t[v].leafCount;
   		}
   	}

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;
using namespace __gnu_pbds;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	ll leafCount = 0;
	int children[26];

	trieNode()
	{
		fill( begin(children), end(children), -1 );
	}
};

vector<trieNode> t(1);

void trie_insert(string s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].children[c] == -1 )
		{
			t[v].children[c] = t.size();
			t.pb();
		}
		v = t[v].children[c];
	}
	t[v].leaf = true;
	t[v].leafCount++;
}

string vs[200010];
ll occ[200010], sum[200010];
int z[200010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int minSz = 400;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < minSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[ oriIdx ]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */
    n = s.size();
   	for (int i = 0; i < n; i++)
   	{
   		int v = 0;
   		for (int j = i; j < n; j++)
   		{
   			int c = s[j] - 'a';
   			v = t[v].children[c];
   			if (v == -1) break;
   			if (t[v].leaf)
   			{
   				sum[i] += t[v].leafCount;
   				occ[j+1] += t[v].leafCount;
   			}
   		}
   	}

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;
using namespace __gnu_pbds;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	int leafCount = 0;
	int children[26];

	trieNode()
	{
		fill( begin(children), end(children), -1 );
	}
};

vector<trieNode> t(1);

void trie_insert(string s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].children[c] == -1 )
		{
			t[v].children[c] = t.size();
			t.pb();
		}
		v = t[v].children[c];
	}
	t[v].leaf = true;
	t[v].leafCount++;
}

string vs[200010];
int occ[200010], sum[200010];
int z[200010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int minSz = 550;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < minSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[oriIdx]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */
    n = s.size();
   	for (int i = 0; i < n; i++)
   	{
   		int v = 0;
   		for (int j = i; j < n; j++)
   		{
   			int c = s[j] - 'a';
   			v = t[v].children[c];
   			if (v == -1) break;
   			if (t[v].leaf)
   			{
   				sum[i] += t[v].leafCount;
   				occ[j+1] += t[v].leafCount;
   			}
   		}
   	}

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define PI                acos(-1)
#define pb                emplace_back
#define mp                make_pair
#define all(a)            (a).begin(), (a).end()
#define clr(a,h)          memset(a, (h), sizeof(a))
#define F first
#define S second
int faster_in(){int r=0,c;for(c=getchar();c<=32;c=getchar());if(c=='-') return -faster_in();for(;c>32;r=(r<<1)+(r<<3)+c-'0',c=getchar());return r;}

using namespace std;
using namespace __gnu_pbds;

typedef long long       ll;
typedef pair<int, int>  ii;
typedef vector<int>     vi;
typedef vector<ii>      vii;
typedef vector<ll>      vll;
typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;
const int INF = int(1e9 + 7);

struct trieNode
{
	bool leaf = false;
	int next[26];

	trieNode()
	{
		fill( begin(next), end(next), -1 );
	}
};

vector<trieNode> t;

void trie_insert(const string &s)
{
	int v = 0;
	for (char ch : s)
	{
		int c = ch - 'a';
		if ( t[v].next[c] == -1 )
		{
			t[v].next[c] = t.size();
			t.pb();
		}
		v = t[v].next[c];
	}
	t[v].leaf = true;
}

string vs[200010];
int occ[200010], sum[200010];
int z[200010];

int main()
{
    std::ios::sync_with_stdio(false); cin.tie(0);
    //freopen("","r",stdin);
    //freopen("","w",stdout);
    string s;
    cin >> s;
    int n = s.size(), m;
    cin >> m;
    int miinSz = 0;
    vector<int> longStrings;
    for (int i = 0; i < m; ++i)
    {
    	cin >> vs[i];
    	if ( vs[i].size() < miinSz )
    		trie_insert(vs[i]);
    	else
    		longStrings.pb(i);
    }
    ll res = 0;
    for (int idx : longStrings)
    {
    	string x = vs[idx] + "#" + s;
    	int L = 0, R = 0;
    	n = x.size();
    	z[0] = 0;
    	for (int i = 1; i < n; i++)
    	{
    		z[i] = 0;
    		if (i <= R)
    			z[i] = min( R-i+1, z[i-L] );
    		while (i + z[i] < n && x[ z[i] ] == x[i + z[i]])
    			z[i]++;
    		if (i + z[i] - 1 > R)
    		{
    			L = i;
    			R = i + z[i] - 1;
    		}
    		if (z[i] == vs[idx].size())
    		{
    			int oriIdx = i-vs[idx].size()-1;
    			sum[oriIdx]++;
    			occ[ oriIdx + vs[idx].size() ]++;
    		}
    	}
    }

    /*
    for (int i = 0; i < s.size(); i++)
    	cout << occ[i];
    cout << endl;
    for (int i = 0; i < s.size(); i++)
    	cout << sum[i];
    cout << endl;
    */

    for (int i = 0; i < s.size(); i++)
    {
    	res += ( sum[i] * occ[i] );
    }

    cout << res << '\n';
    return 0;
}
// PLUS ULTRA!


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

typedef long long ll;
struct aho{

    const static int MAXL = 200005;
    struct node{
        int dic[27], parent, link;
        ll l;
        node( int p )
        {
            parent = p;
            link = l = 0;
            for( int i = 0; i < 26; i++ )
                dic[i] = -1;
        }
    };
    typedef pair<int,int>par;
    queue<par>Q;
    vector<node>tree;

    aho(){
        tree.push_back( node(0) );
    }

    int f( char c ){
        return c-'a';
    }

    void add_word( char *W )
    {
        int l = strlen(W), nod = 0;
        for( int i = 0; i < l; i++ )
        {
            if( tree[nod].dic[f(W[i])] == -1 )
                tree[nod].dic[f(W[i])] = tree.size(), tree.push_back(node(nod));
            nod = tree[nod].dic[f(W[i])];
        }
        tree[nod].l++;
    }

    void links( )
    {
        Q.push(par(0,0));
        int nodo, car;
        while( !Q.empty() )
        {
            nodo = Q.front().first;
            car = Q.front().second;
            Q.pop();
            for( int i = 0; i < 26; i++ )
                if( tree[nodo].dic[i] != -1 )
                    Q.push(par(tree[nodo].dic[i],i));
            if( nodo == 0 || tree[0].dic[car] == nodo )continue;
            int &link = tree[nodo].link;
            link = tree[tree[nodo].parent].link;
            while( link && tree[link].dic[car] == -1 )
                link = tree[link].link;
            link = tree[link].dic[car];
            if( link == -1 )link++;
            tree[nodo].l += tree[link].l;
        }
    }

    int go( int nodo, int car )
    {
        if( tree[nodo].dic[car] != -1 )
            return tree[nodo].dic[car];
        int link = tree[nodo].link;
        while( link && tree[link].dic[car] == -1 )
            link = tree[link].link;
        link = tree[link].dic[car];
        if( link == -1 )link++;
        return link;
    }

}nor, rev;

const int maxn = 200005;
char s[maxn], a[maxn];
ll n, T[maxn], Tr[maxn];
int main()
{
    cin.tie(0);
    ios_base::sync_with_stdio(0);
    #ifdef acm
    freopen("a.in","r",stdin);
    #endif // acm

    cin >> s >> n;

    for( int i = 1; i <= n; i++ ){
        cin >> a;
        int l = strlen(a);
        nor.add_word(a);
        reverse(a, a+l);
        rev.add_word(a);
    }

    nor.links();
    rev.links();

    int l = strlen(s);
    int nod = 0;
    for( int i = 0; i < l; i++ ){
        nod = nor.go(nod, nor.f(s[i]));
        T[i] = nor.tree[nod].l;
    }

    nod = 0;
    for( int i = l-1; i >= 0; i-- ){
        nod = rev.go(nod, nor.f(s[i]) );
        Tr[i] = rev.tree[nod].l;
    }

    long long sol = 0;
    for( int i = 0; i < l-1; i++ )
        sol += T[i] * Tr[i+1];

    cout << sol << "\n";

    return 0;
}


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

struct aho{

    const static int MAXL = 200005;
    struct node{
        int dic[27], parent, link, l;
        node( int p )
        {
            parent = p;
            link = l = 0;
            for( int i = 0; i < 26; i++ )
                dic[i] = -1;
        }
    };
    typedef pair<int,int>par;
    queue<par>Q;
    vector<node>tree;

    aho(){
        tree.push_back( node(0) );
    }

    int f( char c ){
        return c-'a';
    }

    void add_word( char *W )
    {
        int l = strlen(W), nod = 0;
        for( int i = 0; i < l; i++ )
        {
            if( tree[nod].dic[f(W[i])] == -1 )
                tree[nod].dic[f(W[i])] = tree.size(), tree.push_back(node(nod));
            nod = tree[nod].dic[f(W[i])];
        }
        tree[nod].l++;
    }

    void links( )
    {
        Q.push(par(0,0));
        int nodo, car;
        while( !Q.empty() )
        {
            nodo = Q.front().first;
            car = Q.front().second;
            Q.pop();
            for( int i = 0; i < 26; i++ )
                if( tree[nodo].dic[i] != -1 )
                    Q.push(par(tree[nodo].dic[i],i));
            if( nodo == 0 || tree[0].dic[car] == nodo )continue;
            int &link = tree[nodo].link;
            link = tree[tree[nodo].parent].link;
            while( link && tree[link].dic[car] == -1 )
                link = tree[link].link;
            link = tree[link].dic[car];
            if( link == -1 )link++;
            tree[nodo].l += tree[link].l;
        }
    }

    int go( int nodo, int car )
    {
        if( tree[nodo].dic[car] != -1 )
            return tree[nodo].dic[car];
        int link = tree[nodo].link;
        while( link && tree[link].dic[car] == -1 )
            link = tree[link].link;
        link = tree[link].dic[car];
        if( link == -1 )link++;
        return link;
    }

}nor, rev;

const int maxn = 200005;
char s[maxn], a[maxn];
int n, T[maxn], Tr[maxn];
int main()
{
    cin.tie(0);
    ios_base::sync_with_stdio(0);
    #ifdef acm
    freopen("a.in","r",stdin);
    #endif // acm

    cin >> s >> n;

    for( int i = 1; i <= n; i++ ){
        cin >> a;
        int l = strlen(a);
        nor.add_word(a);
        reverse(a, a+l);
        rev.add_word(a);
    }

    nor.links();
    rev.links();

    int l = strlen(s);
    int nod = 0;
    for( int i = 0; i < l; i++ ){
        nod = nor.go(nod, nor.f(s[i]));
        T[i] = nor.tree[nod].l;
    }

    nod = 0;
    for( int i = l-1; i >= 0; i-- ){
        nod = rev.go(nod, nor.f(s[i]) );
        Tr[i] = rev.tree[nod].l;
    }

    long long sol = 0;
    for( int i = 0; i < l-1; i++ )
        sol += T[i] * Tr[i+1];

    cout << sol << "\n";

    return 0;
}


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

struct aho{

    const static int MAXL = 200005;
    struct node{
        int dic[27], parent, link, l;
        node( int p )
        {
            parent = p;
            link = l = 0;
            for( int i = 0; i < 26; i++ )
                dic[i] = -1;
        }
    };
    typedef pair<int,int>par;
    queue<par>Q;
    vector<node>tree;

    aho(){
        tree.push_back( node(0) );
    }

    int f( char c ){
        return c-'a';
    }

    void add_word( char *W )
    {
        int l = strlen(W), nod = 0;
        for( int i = 0; i < l; i++ )
        {
            if( tree[nod].dic[f(W[i])] == -1 )
                tree[nod].dic[f(W[i])] = tree.size(), tree.push_back(node(nod));
            nod = tree[nod].dic[f(W[i])];
        }
        tree[nod].l++;
    }

    void links( )
    {
        Q.push(par(0,0));
        int nodo, car;
        while( !Q.empty() )
        {
            nodo = Q.front().first;
            car = Q.front().second;
            Q.pop();
            for( int i = 0; i < 26; i++ )
                if( tree[nodo].dic[i] != -1 )
                    Q.push(par(tree[nodo].dic[i],i));
            if( nodo == 0 || tree[0].dic[car] == nodo )continue;
            int &link = tree[nodo].link;
            link = tree[tree[nodo].parent].link;
            while( link && tree[link].dic[car] == -1 )
                link = tree[link].link;
            link = tree[link].dic[car];
            if( link == -1 )link++;
            tree[nodo].l += tree[link].l;
        }
    }

    int autom[MAXL*5][28];
    bool OK[MAXL*5][28];

    int go( int nodo, int car )
    {

        if( OK[nodo][car] )
            return autom[nodo][car];
        OK[nodo][car] = 1;
        if( tree[nodo].dic[car] != -1 )
            return autom[nodo][car] = tree[nodo].dic[car];
        int link = tree[nodo].link;
        while( link && tree[link].dic[car] == -1 && !OK[link][car] )
            link = tree[link].link;
        if( OK[link][car] )
            return autom[nodo][car] = autom[link][car];
        link = tree[link].dic[car];
        if( link == -1 )link++;
        return autom[nodo][car] = link;
    }

}nor, rev;

const int maxn = 200005;
char s[maxn], a[maxn];
int n, T[maxn], Tr[maxn];
int main()
{
    cin.tie(0);
    ios_base::sync_with_stdio(0);
    #ifdef acm
    freopen("a.in","r",stdin);
    #endif // acm

    cin >> s >> n;

    for( int i = 1; i <= n; i++ ){
        cin >> a;
        int l = strlen(a);
        nor.add_word(a);
        reverse(a, a+l);
        rev.add_word(a);
    }

    nor.links();
    rev.links();

    int l = strlen(s);
    int nod = 0;
    for( int i = 0; i < l; i++ ){
        nod = nor.go(nod, nor.f(s[i]));
        T[i] = nor.tree[nod].l;
    }

    nod = 0;
    for( int i = l-1; i >= 0; i-- ){
        nod = rev.go(nod, nor.f(s[i]) );
        Tr[i] = rev.tree[nod].l;
    }

    long long sol = 0;
    for( int i = 0; i < l-1; i++ )
        sol += T[i] * Tr[i+1];

    cout << sol << "\n";

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define MAXNUM 222222
#define M 26
#define rep(i,s,t) for(int i=s;i<t;i++)
struct suffix {
    int tree[MAXNUM * 2][M], len[MAXNUM * 2], per[MAXNUM * 2],num[MAXNUM],isused[MAXNUM];
    int root, last, total;
    void init()
    {
        root = last = total = 1;
        memset(tree[1], 0, sizeof(tree[1]));
        len[1] = per[1] = 0;
    }
    void add(int c)
    {
        int now = last, nownode = ++total;
        memset(tree[total], 0, sizeof(tree[total]));
        len[total] = len[last] + 1;
        for (; now && !tree[now][c]; now = per[now])
            tree[now][c] = nownode;
        if (!now)
            per[nownode] = root;
        else
        {
            int q = tree[now][c];
            if (len[q] == len[now] + 1)
                per[nownode] = q;
            else
            {
                total++;
                for (int i = 0; i < M; i++)
                    tree[total][i] = tree[q][i];
                per[total] = per[q];
                len[total] = len[now] + 1;
                per[q] = total;
                per[nownode] = total;
                for (; now && tree[now][c] == q; now = per[now])
                    tree[now][c] = total;
            }
        }
        last = nownode;
    }
    void updper(int now)
    {
        if(isused[now])return;
        isused[now]=1;updper(per[now]);
        num[now]+=num[per[now]];
    }
    void upd()
    {
        rep(i,1,total+1)updper(i);
    }
}per,suf;
typedef long long ll;
char s[MAXNUM],tmps[MAXNUM];int ssize,pper[MAXNUM],psuf[MAXNUM];
int main()
{
    scanf("%s",s);ssize=strlen(s);
    int n;scanf("%d",&n);
    per.init(),suf.init();
    rep(i,0,ssize)per.add(s[i]-'a');
    for(int i=ssize-1;i>=0;i--)suf.add(s[i]-'a');
    int now=1,k=ssize;
    rep(i,0,ssize)now=per.tree[now][s[i]-'a'],pper[i]=now;
    now=1;
    for(int i=ssize-1;i>=0;i--)now=suf.tree[now][s[i]-'a'],psuf[i]=now;
    rep(i,1,n+1)
    {
        scanf("%s",tmps);ssize=strlen(tmps);
        now=1;
        rep(j,0,ssize)now=per.tree[now][tmps[j]-'a'];
        if(now)per.num[now]++;
        now=1;
        for(int j=ssize-1;j>=0;j--)now=suf.tree[now][tmps[j]-'a'];
        if(now)suf.num[now]++;
    }
    per.upd(),suf.upd();
    ll res=0;
    rep(i,0,k-1)res+=per.num[pper[i]]*1LL*suf.num[psuf[i+1]];
    printf("%I64d\n",res);
}


#include <bits/stdc++.h>
using namespace std;
#define MAXNUM 222222
#define M 26
#define rep(i,s,t) for(int i=s;i<t;i++)
struct suffix {
    int tree[MAXNUM * 2][M], len[MAXNUM * 2], per[MAXNUM * 2],num[MAXNUM*2],isused[MAXNUM*2];
    int root, last, total;
    void init()
    {
        root = last = total = 1;
        memset(tree[1], 0, sizeof(tree[1]));
        len[1] = per[1] = 0;
    }
    void add(int c)
    {
        int now = last, nownode = ++total;
        memset(tree[total], 0, sizeof(tree[total]));
        len[total] = len[last] + 1;
        for (; now && !tree[now][c]; now = per[now])
            tree[now][c] = nownode;
        if (!now)
            per[nownode] = root;
        else
        {
            int q = tree[now][c];
            if (len[q] == len[now] + 1)
                per[nownode] = q;
            else
            {
                total++;
                for (int i = 0; i < M; i++)
                    tree[total][i] = tree[q][i];
                per[total] = per[q];
                len[total] = len[now] + 1;
                per[q] = total;
                per[nownode] = total;
                for (; now && tree[now][c] == q; now = per[now])
                    tree[now][c] = total;
            }
        }
        last = nownode;
    }
    void updper(int now)
    {
        if(isused[now])return;
        isused[now]=1;updper(per[now]);
        num[now]+=num[per[now]];
    }
    void upd()
    {
        rep(i,1,total+1)updper(i);
    }
}per,suf;
typedef long long ll;
char s[MAXNUM],tmps[MAXNUM];int ssize,pper[MAXNUM],psuf[MAXNUM];
int main()
{
    scanf("%s",s);ssize=strlen(s);
    int n;scanf("%d",&n);
    per.init(),suf.init();
    rep(i,0,ssize)per.add(s[i]-'a');
    for(int i=ssize-1;i>=0;i--)suf.add(s[i]-'a');
    int now=1,k=ssize;
    rep(i,0,ssize)now=per.tree[now][s[i]-'a'],pper[i]=now;
    now=1;
    for(int i=ssize-1;i>=0;i--)now=suf.tree[now][s[i]-'a'],psuf[i]=now;
    rep(i,1,n+1)
    {
        scanf("%s",tmps);ssize=strlen(tmps);
        now=1;
        rep(j,0,ssize)now=per.tree[now][tmps[j]-'a'];
        if(now)per.num[now]++;
        now=1;
        for(int j=ssize-1;j>=0;j--)now=suf.tree[now][tmps[j]-'a'];
        if(now)suf.num[now]++;
    }
    per.upd(),suf.upd();
    ll res=0;
    rep(i,0,k-1)res+=per.num[pper[i]]*1LL*suf.num[psuf[i+1]];
    printf("%I64d\n",res);
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

namespace Primary
{

const int maxn = 2e5 + 10;
char t[maxn], s[maxn];
int n, latter[maxn], former[maxn];

class Trie
{
  private:
	int ch[maxn][26], fail[maxn], size[maxn], tot;

  public:
	inline void add(char *s)
	{
		int len = strlen(s), u = 0;
		for (int i = 0; i < len; ++i)
		{
			if (!ch[u][s[i] - 'a']) ch[u][s[i] - 'a'] = ++tot;
			u = ch[u][s[i] - 'a'];
		}
		++size[u];
	}

	inline void build()
	{
		queue<int> q;
		for (int i = 0; i < 26; ++i)
		{
			if (ch[0][i])
			{
				q.push(ch[0][i]);
				fail[ch[0][i]] = 0;
			}
		}
		while (!q.empty())
		{
			int u = q.front();
			q.pop();
			for (int i = 0; i < 26; ++i)
			{
				if (ch[u][i])
				{
					fail[ch[u][i]] = ch[fail[u]][i];
					size[ch[u][i]] += size[fail[ch[u][i]]];
					q.push(ch[u][i]);
				}
				else ch[u][i] = ch[fail[u]][i];
			}
		}
	}

	inline void calc(char *s, int *res)
	{
		int len = strlen(s), u = 0;
		for (int i = 0; i < len; ++i)
		{
			u = ch[u][s[i] - 'a'];
			res[i] = size[u];
		}
	}

}ord, rev;

void main()
{
	scanf("%s%d", t, &n);
	for (int i = 1; i <= n; ++i)
	{
		scanf("%s", s);
		ord.add(s);
		reverse(s, s + strlen(s));
		rev.add(s);
	}
	ord.build(), rev.build();
	int len = strlen(t);
	ord.calc(t, latter);
	reverse(t, t + len);
	rev.calc(t, former);
	long long ans = 0;
	for (int i = 0; i < len - 1; ++i)
		ans += 1ll * latter[i] * former[len - i - 2];
	printf("%I64d\n", ans);
}

}

int main()
{
	Primary::main();
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <queue>

using namespace std;

namespace Primary
{

const int maxn = 2e5 + 10;
char t[maxn], s[maxn];
int n, latter[maxn], former[maxn];

class Trie
{
  private:
	int ch[maxn][26], fail[maxn], size[maxn], tot;

  public:
	inline void add(char *s)
	{
		int len = strlen(s), u = 0;
		for (int i = 0; i < len; ++i)
		{
			if (!ch[u][s[i] - 'a']) ch[u][s[i] - 'a'] = ++tot;
			u = ch[u][s[i] - 'a'];
		}
		++size[u];
	}

	inline void build()
	{
		queue<int> q;
		for (int i = 0; i < 26; ++i)
		{
			if (ch[0][i])
			{
				q.push(ch[0][i]);
				fail[ch[0][i]] = 0;
			}
		}
		while (!q.empty())
		{
			int u = q.front();
			q.pop();
			for (int i = 0; i < 26; ++i)
			{
				if (ch[u][i])
				{
					fail[ch[u][i]] = ch[fail[u]][i];
					size[ch[u][i]] += size[fail[ch[u][i]]];
					q.push(ch[u][i]);
				}
				else ch[u][i] = ch[fail[u]][i];
			}
		}
	}

	inline void calc(char *s, int *res)
	{
		int len = strlen(s), u = 0;
		for (int i = 0; i < len; ++i)
		{
			u = ch[u][s[i] - 'a'];
			res[i] = size[u];
		}
	}

}ord, rev;

void main()
{
	scanf("%s%d", t, &n);
	for (int i = 1; i <= n; ++i)
	{
		scanf("%s", s);
		ord.add(s);
		reverse(s, s + strlen(s));
		rev.add(s);
	}
	ord.build(), rev.build();
	int len = strlen(t);
	ord.calc(t, latter);
	reverse(t, t + len);
	rev.calc(t, former);
	long long ans = 0;
	for (int i = 0; i < len; ++i)
		ans += 1ll * latter[i] * former[len - i - 2];
	printf("%I64d\n", ans);
}

}

int main()
{
	Primary::main();
	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
typedef double db;
typedef long long ll;
const db eps=1e-8;
const db pi = acos(-1.0);
const int INF=0x3f3f3f3f;
#define mm(x,b) memset((x),(b),sizeof(x))
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1,0};

template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

const int maxn = 2e5 + 10;

char t[maxn], s[maxn];

struct Tire{
	int tire[maxn * 2][26], e[maxn * 2];
	int fail[maxn * 2], idx = 1;
	ll ans[maxn];

	void add(char *s){
		int p = 0;
		for(int i = 0, val; s[i]; i++){
			val = s[i] - 'a';
			if(!tire[p][val]){
				tire[p][val] = idx++;
			}
			p = tire[p][val];
		}
		e[p]++;
	}

	void set_fail(){
		queue<int> q;
		for(int i = 0; i < 26; i++)
			if(tire[0][i]) q.push(tire[0][i]);

		while(q.size()){
			int p = q.front(); q.pop();
			for(int i = 0; i < 26; i++){
				if(tire[p][i]){
					fail[tire[p][i]] = tire[fail[p]][i];
					e[tire[p][i]] += e[tire[fail[p]][i]];
					q.push(tire[p][i]);
				}
				else tire[p][i] = tire[fail[p]][i];
			}
		}
	}

	void qry(char *s){
		int p = 0;
		for(int i = 0; s[i]; i++){
			p = tire[p][s[i] - 'a'];
			ll res = 0;
			for(int j = p; j; j = fail[j])
				res += e[j];
			ans[i] = res;
		}
	}

};

int n;
Tire a1, a2;

int main()
{
	scanf("%s", t);
	scanf("%d", &n);
	for(int i = 0, len; i < n; i++){
		scanf("%s", s); len = strlen(s);
		a1.add(s);
		reverse(s, s + len);
		a2.add(s);
	}

	int len = strlen(t);

	a1.set_fail(), a2.set_fail();

	int p = 0;
	for(int i = 0; t[i]; i++){
		p = a1.tire[p][t[i] - 'a'];
		a1.ans[i] = a1.e[p];
	}

	p = 0;
	for(int i = len - 1; t[i]; i--){
		p = a2.tire[p][t[i] - 'a'];
		a2.ans[i] = a2.e[p];
	}

	ll ans = 0;
	for(int i = 1; i < len; i++){
		ans += a1.ans[i - 1] * a2.ans[i];
	}
	printf("%I64d\n", ans);

	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
typedef double db;
typedef long long ll;
const db eps=1e-8;
const db pi = acos(-1.0);
const int INF=0x3f3f3f3f;
#define mm(x,b) memset((x),(b),sizeof(x))
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1,0};

template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

const int maxn = 2e5 + 10;

char t[maxn], s[maxn];

struct Tire{
	ll tire[maxn * 2][26], e[maxn * 2];
	ll fail[maxn * 2], idx = 1, ans[maxn];

	void add(char *s){
		int p = 0;
		for(int i = 0, val; s[i]; i++){
			val = s[i] - 'a';
			if(!tire[p][val]){
				tire[p][val] = idx++;
			}
			p = tire[p][val];
		}
		e[p]++;
	}

	void set_fail(){
		queue<int> q;
		for(int i = 0; i < 26; i++)
			if(tire[0][i]) q.push(tire[0][i]);

		while(q.size()){
			int p = q.front(); q.pop();
			for(int i = 0; i < 26; i++){
				if(tire[p][i]){
					fail[tire[p][i]] = tire[fail[p]][i];
					e[tire[p][i]] += e[tire[fail[p]][i]];
					q.push(tire[p][i]);
				}
				else tire[p][i] = tire[fail[p]][i];
			}
		}
	}

	void qry(char *s){
		int p = 0;
		for(int i = 0; s[i]; i++){
			p = tire[p][s[i] - 'a'];
			ll res = 0;
			for(int j = p; j; j = fail[j])
				res += e[j];
			ans[i] = res;
		}
	}

};

int n;
Tire a1, a2;

int main()
{
	scanf("%s", t);
	scanf("%d", &n);
	for(int i = 0, len; i < n; i++){
		scanf("%s", s); len = strlen(s);
		a1.add(s);
		reverse(s, s + len);
		a2.add(s);
	}

	int len = strlen(t);

	a1.set_fail(), a2.set_fail();

	int p = 0;
	for(int i = 0; t[i]; i++){
		p = a1.tire[p][t[i] - 'a'];
		a1.ans[i] = a1.e[p];
	}

	p = 0;
	for(int i = len - 1; t[i]; i--){
		p = a2.tire[p][t[i] - 'a'];
		a2.ans[i] = a2.e[p];
	}

	ll ans = 0;
	for(int i = 1; i < len; i++){
		ans += a1.ans[i - 1] * a2.ans[i];
	}
	printf("%I64d\n", ans);

	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
typedef double db;
typedef long long ll;
const db eps=1e-8;
const db pi = acos(-1.0);
const int INF=0x3f3f3f3f;
#define mm(x,b) memset((x),(b),sizeof(x))
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1,0};

template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

const int maxn = 2e5 + 10;

char t[maxn], s[maxn];

struct Tire{
	ll tire[maxn * 2][26], e[maxn * 2];
	ll fail[maxn * 2], idx = 1, ans[maxn];

	void add(char *s){
		int p = 0;
		for(int i = 0, val; s[i]; i++){
			val = s[i] - 'a';
			if(!tire[p][val]){
				tire[p][val] = idx++;
			}
			p = tire[p][val];
		}
		e[p]++;
	}

	void set_fail(){
		queue<int> q;
		for(int i = 0; i < 26; i++)
			if(tire[0][i]) q.push(tire[0][i]);

		while(q.size()){
			int p = q.front(); q.pop();
			for(int i = 0; i < 26; i++){
				if(tire[p][i]){
					fail[tire[p][i]] = tire[fail[p]][i];
					q.push(tire[p][i]);
				}
				else tire[p][i] = tire[fail[p]][i];
			}
		}
	}

	void qry(char *s){
		int p = 0;
		for(int i = 0; s[i]; i++){
			p = tire[p][s[i] - 'a'];
			ll res = 0;
			for(int j = p; j; j = fail[j])
				res += e[j];
			ans[i] = res;
		}
	}

};

int n;
Tire a1, a2;

int main()
{
	scanf("%s", t);
	scanf("%d", &n);
	for(int i = 0, len; i < n; i++){
		scanf("%s", s); len = strlen(s);
		a1.add(s);
		reverse(s, s + len);
		a2.add(s);
	}

	int len = strlen(t);

	a1.set_fail(), a2.set_fail();

	int p = 0;
	for(int i = 0; t[i]; i++){
		p = a1.tire[p][t[i] - 'a'];
		ll res = 0;
		for(int j = p; j; j = a1.fail[j])
			res += a1.e[j];
		a1.ans[i] = res;
	}

	p = 0;
	for(int i = len - 1; t[i]; i--){
		p = a2.tire[p][t[i] - 'a'];
		ll res = 0;
		for(int j = p; j; j = a2.fail[j])
			res += a2.e[j];
		a2.ans[i] = res;
	}

	ll ans = 0;
	for(int i = 1; i < len; i++){
		ans += a1.ans[i - 1] * a2.ans[i];
	}
	printf("%I64d\n", ans);

	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
typedef double db;
typedef long long ll;
const db eps=1e-8;
const db pi = acos(-1.0);
const int INF=0x3f3f3f3f;
#define mm(x,b) memset((x),(b),sizeof(x))
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1,0};

template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

const int maxn = 2e5 + 10;

char t[maxn], s[maxn];

struct Tire{
	int tire[maxn][26], e[maxn];
	int fail[maxn], idx = 1;
	ll ans[maxn];

	void add(char *s){
		int p = 0;
		for(int i = 0, val; s[i]; i++){
			val = s[i] - 'a';
			if(!tire[p][val]){
				tire[p][val] = idx++;
			}
			p = tire[p][val];
		}
		e[p]++;
	}

	void set_fail(){
		queue<int> q;
		for(int i = 0; i < 26; i++)
			if(tire[0][i]) q.push(tire[0][i]);

		while(q.size()){
			int p = q.front(); q.pop();
			for(int i = 0; i < 26; i++){
				if(tire[p][i]){
					fail[tire[p][i]] = tire[fail[p]][i];
					e[tire[p][i]] += e[tire[fail[p]][i]];
					q.push(tire[p][i]);
				}
				else tire[p][i] = tire[fail[p]][i];
			}
		}
	}

	void qry(char *s){
		int p = 0;
		for(int i = 0; s[i]; i++){
			p = tire[p][s[i] - 'a'];
			ll res = 0;
			for(int j = p; j; j = fail[j])
				res += e[j];
			ans[i] = res;
		}
	}

};

int n;
Tire a1, a2;

int main()
{
	scanf("%s", t);
	scanf("%d", &n);
	for(int i = 0, len; i < n; i++){
		scanf("%s", s); len = strlen(s);
		a1.add(s);
		reverse(s, s + len);
		a2.add(s);
	}

	int len = strlen(t);

	a1.set_fail(), a2.set_fail();

	int p = 0;
	for(int i = 0; t[i]; i++){
		p = a1.tire[p][t[i] - 'a'];
		a1.ans[i] = a1.e[p];
	}

	p = 0;
	for(int i = len - 1; t[i]; i--){
		p = a2.tire[p][t[i] - 'a'];
		a2.ans[i] = a2.e[p];
	}

	ll ans = 0;
	for(int i = 1; i < len; i++)
		ans += a1.ans[i - 1] * a2.ans[i];

	printf("%I64d\n", ans);

	return 0;
}


#include<bits/stdc++.h>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
typedef double db;
typedef long long ll;
const db eps=1e-8;
const db pi = acos(-1.0);
const int INF=0x3f3f3f3f;
#define mm(x,b) memset((x),(b),sizeof(x))
#define de(a) cout << #a << " = " << a << endl
#define dd(a) cout << #a << " = " << a << " "
int dx[] = {-1, 0, 0, 1}, dy[] = {0, -1, 1,0};

template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}

const int maxn = 2e5 + 10;

char t[maxn], s[maxn];

struct Tire{
	ll tire[maxn * 2][26], e[maxn * 2];
	ll fail[maxn * 2], idx = 1, ans[maxn];

	void add(char *s){
		int p = 0;
		for(int i = 0, val; s[i]; i++){
			val = s[i] - 'a';
			if(!tire[p][val]){
				tire[p][val] = idx++;
			}
			p = tire[p][val];
		}
		e[p]++;
	}

	void set_fail(){
		queue<int> q;
		for(int i = 0; i < 26; i++)
			if(tire[0][i]) q.push(tire[0][i]);

		while(q.size()){
			int p = q.front(); q.pop();
			for(int i = 0; i < 26; i++){
				if(tire[p][i]){
					fail[tire[p][i]] = tire[fail[p]][i];
					q.push(tire[p][i]);
				}
				else tire[p][i] = tire[fail[p]][i];
			}
		}
	}

	void qry(char *s){
		int p = 0;
		for(int i = 0; s[i]; i++){
			p = tire[p][s[i] - 'a'];
			ll res = 0;
			for(int j = p; j; j = fail[j])
				res += e[j];
			ans[i] = res;
		}
	}

};

int n;
Tire a1, a2;

int main()
{
	scanf("%s", t);
	scanf("%d", &n);
	for(int i = 0, len; i < n; i++){
		scanf("%s", s); len = strlen(s);
		a1.add(s);
		reverse(s, s + len);
		a2.add(s);
	}

	int len = strlen(t);

	a1.set_fail(), a2.set_fail();

	a1.qry(t);
	reverse(t, t + len);
	a2.qry(t);

	ll ans = 0;
	for(int i = 1; i < len; i++){
		ans += a1.ans[i - 1] * a2.ans[len - i - 1];
	}
	printf("%I64d\n", ans);

	return 0;
}