#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
// using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

// template <class T1, class T2, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
//template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
// template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 2e5 + 1;
const int L = 26;
int n, q;
int cur;
ll ans;

int beg[N];
int fin[N];

struct Trie {
    int nxt[N][L];
    int gon[N][L];
    int link[N];
    int par[N];
    int chr[N];
    int cnt[N];
    int fin[N];
} trie;

string t;
string p[N];

int get_link(int);
int get_go(int, int);

void input() {
    cin >> t;
    cin >> q;
    n = len(t);
    for(int i = 0; i < q; ++i) {
        cin >> p[i];
    }
}

void insert(string &s) {
    int node = 0;
    for(char c: s) {
        int j = v(c);
        if(!trie.nxt[node][j]) {
            trie.nxt[node][j] = ++cur;
            trie.par[cur] = node;
            trie.chr[cur] = j;
        }
        node = trie.nxt[node][j];
    }
    trie.fin[node]++;
}

int get_link(int node) {
    if(trie.link[node] == -1) {
        if(!node || !trie.par[node]) {
            trie.link[node] = 0;
            trie.cnt[node] = trie.fin[node];
        }
        else {
            trie.link[node] = get_go(get_link(trie.par[node]), trie.chr[node]);
            get_link(trie.link[node]);
            trie.cnt[node] = trie.fin[node] + trie.cnt[trie.link[node]];
        }
    }
    return trie.link[node];
}

int get_go(int node, int c) {
    if(trie.gon[node][c] == -1) {
        if(trie.nxt[node][c]) {
            trie.gon[node][c] =
            trie.nxt[node][c];
        }
        else {
            trie.gon[node][c] = node? get_go(get_link(node), c): 0;
        }
    }
    return trie.gon[node][c];
}

void aho_corasick(int arr[]) {
    fill(trie.gon[0], trie.gon[N], -1);
    fill(trie.link, trie.link + N, -1);
    fill(trie.fin, trie.fin + N, 0);
    for(int i = 0; i < q; ++i) {
        insert(p[i]);
    }
    int node = 0;
    for(int i = 0; i < n; ++i) {
        node = get_go(node, v(t[i]));
        get_link(node);
        arr[i] = trie.cnt[node];
    }
}

void reverse_all() {
    reverse(all(t));
    for(int i = 0; i < q; ++i) {
        reverse(all(p[i]));
    }
}

void solve() {
    aho_corasick(beg);
    reverse_all();
    aho_corasick(fin);
    reverse(fin, fin + n);
    for(int i = 0; i < n - 1; ++i) {
        ans += 1ll * beg[i] * fin[i + 1];
    }
    cout << ans << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/priority_queue.hpp>
//#pragma GCC optimize("O3")
//#pragma GCC target("sse4")
//#pragma GCC target("avx2")

#define deb(x) cout << #x << " = " << x << "\n"
#define all(x) (x).begin(), (x).end()
#define len(x) (int) x.size()
#define lsb(x) (x) & -(x)
#define l(x) (x << 1) + 1
#define r(x) (x << 1) + 2
#define v(x) (int)(x - 'a')

#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound

using namespace std;
// using namespace __gnu_pbds;
typedef long long ll;
typedef long double ld;
typedef pair <int, int> pii;
typedef pair <ld, ld> pld;
typedef pair <ll, ll> pll;

// template <class T1, class T2, class T3 = less <T1>> using pb_map = tree <T1, T2, T3, rb_tree_tag, tree_order_statistics_node_update>;
//template <class T1, class T2 = less <T1>> using pb_heap = __gnu_pbds::priority_queue <T1, T2, binary_heap_tag>;
// template <class T1, class T2 = null_type, class T3 = hash <T1>> using pb_umap = gp_hash_table <T1, T2, T3>;
template <class T1, class T2, class T3 = hash <T1>> using umap = unordered_map <T1, T2, T3>;
template <class T> using uset = unordered_set <T>;
template <class T> using vec = vector <T>;

const ll infll = numeric_limits <ll>::max() >> 1;
const int inf = numeric_limits <int>::max() >> 1;
const int N = 2e5 + 1;
const int L = 26;
int n, q;
int cur;
ll ans;

int beg[N];
int fin[N];

struct Trie {
    int nxt[N][L];
    int gon[N][L];
    int link[N];
    int par[N];
    int chr[N];
    int cnt[N];
    int fin[N];
} trie;

string t;
string p[N];

int get_link(int);
int get_go(int, int);

void input() {
    cin >> t;
    cin >> q;
    n = len(t);
    for(int i = 0; i < q; ++i) {
        cin >> p[i];
    }
}

void insert(string &s) {
    int node = 0;
    for(char c: s) {
        int j = v(c);
        if(!trie.nxt[node][j]) {
            trie.nxt[node][j] = ++cur;
            trie.par[cur] = node;
            trie.chr[cur] = j;
        }
        node = trie.nxt[node][j];
    }
    trie.fin[node]++;
}

int get_link(int node) {
    if(trie.link[node] == -1) {
        if(!node || !trie.par[node]) {
            trie.link[node] = 0;
            trie.cnt[node] = trie.fin[node];
        }
        else {
            trie.link[node] = get_go(get_link(trie.par[node]), trie.chr[node]);
            get_link(trie.link[node]);
            trie.cnt[node] = trie.fin[node] + trie.cnt[trie.link[node]];
        }
    }
    return trie.link[node];
}

int get_go(int node, int c) {
    if(trie.gon[node][c] == -1) {
        if(trie.nxt[node][c]) {
            trie.gon[node][c] =
            trie.nxt[node][c];
        }
        else {
            trie.gon[node][c] = node? get_go(get_link(node), c): 0;
        }
    }
    return trie.gon[node][c];
}

void aho_corasick(int arr[]) {
    fill(trie.nxt[0], trie.nxt[N], 0);
    fill(trie.gon[0], trie.gon[N], -1);
    fill(trie.link, trie.link + N, -1);
    fill(trie.fin, trie.fin + N, 0);
    cur = 0;
    for(int i = 0; i < q; ++i) {
        insert(p[i]);
    }
    int node = 0;
    for(int i = 0; i < n; ++i) {
        node = get_go(node, v(t[i]));
        get_link(node);
        arr[i] = trie.cnt[node];
    }
}

void reverse_all() {
    reverse(all(t));
    for(int i = 0; i < q; ++i) {
        reverse(all(p[i]));
    }
}

void solve() {
    aho_corasick(beg);
    reverse_all();
    aho_corasick(fin);
    reverse(fin, fin + n);
    for(int i = 0; i < n - 1; ++i) {
        ans += 1ll * beg[i] * fin[i + 1];
    }
    cout << ans << "\n";
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0), cout.tie(0);
    input();
    solve();
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <deque>
#define ll long long
#define db double
using namespace std;
inline int read(){
    int SUM=0,ff=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
      if(ch=='-')
        ff=-1;
      ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
      SUM=(SUM<<3)+(SUM<<1)+(ch^48);
      ch=getchar();
    }
    return SUM*ff;
}
const int N=2000010;
char S[N],T[N];
int n;
ll res[2][N];
struct Aho_Corasick_Automaton{
    struct Trie_tree{
	    int son[26];
	    int fail;
	    int val;
	    int size;
	}trie[2][N];
	int tot;
	inline void insert(char *s,int op){
	    int len=strlen(s),rt=0;
	    for(int i=0;i<len;i++){
		   int u=s[i]-'a';
		   if(!trie[op][rt].son[u]) trie[op][rt].son[u]=++tot;
		   rt=trie[op][rt].son[u];
		}
		trie[op][rt].size++;
	}
	inline void getfail(){
	    queue <int> q;
        for(int op=0;op<=1;op++){
		   for(int i=0;i<26;i++)
              if(trie[op][0].son[i])
                q.push(trie[op][0].son[i]);
           while(!q.empty()){
              int u=q.front();
              q.pop();
              for(int i=0;i<26;i++){
                 if(trie[op][u].son[i]){
                   trie[op][trie[op][u].son[i]].fail=trie[op][trie[op][u].fail].son[i];
                   trie[op][trie[op][u].son[i]].size+=trie[op][trie[op][trie[op][u].fail].son[i]].size;
				   q.push(trie[op][u].son[i]);
                 }
                 else{
                   trie[op][u].son[i]=trie[op][trie[op][u].fail].son[i];
                 }
              }
           }
        }
	}
	inline void query(char *s,int op){
	    int len=strlen(s),rt=0;
	    for(int i=0;i<len;i++){
	       int u=s[i]-'a';
		   rt=trie[op][rt].son[u];
		   res[op][i]=trie[op][rt].size;
		}
	}
}AC;
int main(){
    //freopen("CF1202E You Are Given Some Strings.in","r",stdin);
    //freopen("CF1202E You Are Given Some Strings.out","w",stdout);
    scanf("%s",S);
    n=read();
    for(int i=1;i<=n;i++){
	   scanf("%s",T);
	   int len=strlen(T);
	   AC.insert(T,1);
	   reverse(T,T+len);
	   AC.insert(T,0);
	}
	AC.getfail();
	int len=strlen(S);
	AC.query(S,1);
	reverse(S,S+len);
	AC.query(S,0);
	ll ans=0;
	for(int i=0;i<len;i++)
	   ans+=1ll*res[1][i]*res[0][len-i-2];
	printf("%lld\n",ans);
    return 0;
}


#include <cstdio>
#include <cmath>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <stack>
#include <deque>
#define ll long long
#define db double
using namespace std;
inline int read(){
    int SUM=0,ff=1;
    char ch=getchar();
    while(ch<'0'||ch>'9'){
      if(ch=='-')
        ff=-1;
      ch=getchar();
    }
    while(ch>='0'&&ch<='9'){
      SUM=(SUM<<3)+(SUM<<1)+(ch^48);
      ch=getchar();
    }
    return SUM*ff;
}
const int N=400010;
char S[N],T[N];
int n;
ll res[2][N];
struct Aho_Corasick_Automaton{
    struct Trie_tree{
	    int son[26];
	    int fail;
	    int val;
	    int size;
	}trie[2][N];
	int tot;
	inline void insert(char *s,int op){
	    int len=strlen(s),rt=0;
	    for(int i=0;i<len;i++){
		   int u=s[i]-'a';
		   if(!trie[op][rt].son[u]) trie[op][rt].son[u]=++tot;
		   rt=trie[op][rt].son[u];
		}
		trie[op][rt].size++;
	}
	inline void getfail(){
	    queue <int> q;
        for(int op=0;op<=1;op++){
		   for(int i=0;i<26;i++)
              if(trie[op][0].son[i])
                q.push(trie[op][0].son[i]);
           while(!q.empty()){
              int u=q.front();
              q.pop();
              for(int i=0;i<26;i++){
                 if(trie[op][u].son[i]){
                   trie[op][trie[op][u].son[i]].fail=trie[op][trie[op][u].fail].son[i];
                   trie[op][trie[op][u].son[i]].size+=trie[op][trie[op][trie[op][u].fail].son[i]].size;
				   q.push(trie[op][u].son[i]);
                 }
                 else{
                   trie[op][u].son[i]=trie[op][trie[op][u].fail].son[i];
                 }
              }
           }
        }
	}
	inline void query(char *s,int op){
	    int len=strlen(s),rt=0;
	    for(int i=0;i<len;i++){
	       int u=s[i]-'a';
		   rt=trie[op][rt].son[u];
		   res[op][i]=trie[op][rt].size;
		}
	}
}AC;
int main(){
    //freopen("CF1202E You Are Given Some Strings.in","r",stdin);
    //freopen("CF1202E You Are Given Some Strings.out","w",stdout);
    scanf("%s",S);
    n=read();
    for(int i=1;i<=n;i++){
	   scanf("%s",T);
	   int len=strlen(T);
	   AC.insert(T,1);
	   reverse(T,T+len);
	   AC.insert(T,0);
	}
	AC.getfail();
	int len=strlen(S);
	AC.query(S,1);
	reverse(S,S+len);
	AC.query(S,0);
	ll ans=0;
	for(int i=0;i<len;i++)
	   ans+=1ll*res[1][i]*res[0][len-i-2];
	printf("%lld\n",ans);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[26],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,4)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot=trie[v].sum+trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN],ans;

struct jc{
	struct node{
		LL ch[26],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s,RE int len)
	{
		RE LL cur=0;
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].tot++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,25) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,25)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot+=trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0;
		FOR(i,0,m-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s);
		RE LL l=strlen(s);
		a.insert(s,l);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2,l);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 210000
#define MAXM 210000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[26],fail,sum;
	}trie[MAXN];

	LL tot=0;

	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}

	IL void build()
	{
		queue<LL>q;
		FOR(i,0,25) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,25)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'];
			for(RE LL j=cur;j;j=trie[j].fail) sum[i]+=trie[j].sum;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 210000
#define MAXM 210000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[5],fail,sum;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,4)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'];
			for(RE LL j=cur;j;j=trie[j].fail) sum[i]+=trie[j].sum;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN],ans;

struct jc{
	struct node{
		LL ch[26],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,25) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,25)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot=trie[v].sum+trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0;
		FOR(i,0,m-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[26],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,25) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,25)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot=trie[v].sum+trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[5],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,4)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot=trie[v].sum+trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[5],fail,sum;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,4)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'];
			for(RE LL j=cur;j;j=trie[j].fail) sum[i]+=trie[j].sum;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[26],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,25)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
			trie[v].tot=trie[v].sum+trie[trie[v].fail].tot;
		}
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


#include <bits/stdc++.h>

using namespace std;

#define LL long long
#define IL inline
#define RE register
#define DB double
#define RT return
#define MAXN 510000
#define MAXM 510000
#define INF 1e9+10
#define mod LL(1e9)
#define FOR(i,a,b) for(RE LL i=a; i<=b; i++)
#define FOR2(i,a,b) for(RE LL i=(a); i>=(b); i--)
#define pq priority_queue
#define reset(a) memset(a,0,sizeof(a))
#define reset2(a) memset(a,100,sizeof(a))

IL LL read()
{
	RE LL x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0'&&c<='9'){x=x*10+(c-'0');c=getchar();}
	RT x*f;
}

char s[MAXN],c[MAXN],s2[MAXN];

LL n,m,sum[MAXN],sum2[MAXN];

struct jc{
	struct node{
		LL ch[5],fail,sum,tot;
	}trie[MAXN];
	LL tot=0;
	IL void insert(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			RE LL son=s[i]-'a';
			if(!trie[cur].ch[son]) trie[cur].ch[son]=++tot;
			cur=trie[cur].ch[son];
		}
		trie[cur].sum++;
	}
	IL void build()
	{
		queue<LL>q;
		FOR(i,0,4) if(trie[0].ch[i]) trie[trie[0].ch[i]].fail=0,q.push(trie[0].ch[i]);
		while(!q.empty())
		{
			RE LL v=q.front();
			q.pop();
			FOR(i,0,4)
			if(trie[v].ch[i]) trie[trie[v].ch[i]].fail=trie[trie[v].fail].ch[i],q.push(trie[v].ch[i]);
			else trie[v].ch[i]=trie[trie[v].fail].ch[i];
		}
		FOR(i,0,tot) for(RE LL j=i;j;j=trie[j].fail) trie[i].tot+=trie[j].sum;
	}
	IL void query(char *s)
	{
		RE LL cur=0,len=strlen(s);
		FOR(i,0,len-1)
		{
			cur=trie[cur].ch[s[i]-'a'],sum[i]=trie[cur].tot;
		}
	}
}a,b;

int main()
{
	scanf("%s",c);
	RE LL n=read(),m=strlen(c),ans=0;
	FOR(i,1,n)
	{
		scanf("%s",s),a.insert(s);
		RE LL l=strlen(s);
		FOR(i,0,l-1) s2[i]=s[l-1-i];
		b.insert(s2);
	}
	a.build(),b.build();
	a.query(c);
	FOR(i,0,m-1) sum2[i]=sum[i],sum[i]=0;
	FOR(i,0,m-1) s2[i]=c[m-1-i];
	b.query(s2);
	FOR(i,0,m-2) ans+=sum2[i]*sum[m-2-i];
	cout<<ans<<endl;
	RT 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(char c) {
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const char s[], int len) {
		int u = root;
		//for (; *s; s++) {
		for (int i = 0; i < len; ++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const char* s, int len, int id) {
		int u = root, tot = 0;
		for (; tot < len; tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';

		AC1.insert(t + 1,len);
		reverse(t + 1, t + len + 1);
		AC2.insert(t + 1,len);
	}

	AC1.build();
	AC1.query(s + 1, m, 0);
	reverse(s + 1, s + m + 1);
	AC2.build();
	AC2.query(s + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=int(b);++i)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int maxn = 2e5 + 10;
const int maxm = 26;
struct ACAM {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(maxm, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> Q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < maxm; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < maxm; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int res[]) {
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			res[i] = cnt[u];
		}
	}
};
ACAM ACS[2];
int cnt[2][maxn];

vector<int>S, TT;
#define endl '\n'
int main()
{
#ifndef endl
	freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
	cout << "************************************Local Test*********************************" << endl;
#endif // !endl
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	int T(1), cas(0);
	while (cas, T--)
	{
		ACS[0].init(); ACS[1].init();
		string str; cin >> str;
		for (auto &c : str)S.push_back(c - 'a');

		int n; cin >> n;
		F(i, 1, n)
		{
			cin >> str;
			TT.clear();

			for (auto &c : str)TT.push_back(c - 'a');
			ACS[0].insert(&TT[0],TT.size());
			reverse(TT.begin(), TT.end());
			ACS[1].insert(&TT[0],TT.size());
		}
		ACS[0].build(); ACS[1].build();
		ACS[0].query(&S[0], S.size(), cnt[0]);

		reverse(S.begin(), S.end());
		ACS[1].query(&S[0], S.size(), cnt[1]);

		ll ans(0);
		F(i, 0, S.size() - 2)
		{
			ans += 1ll * cnt[0][i] * cnt[1][(S.size() - 2) - i];
		}
		cout << ans << endl;
	}
	return 0;
}
//What to Debug
/*
-1.最好把全部warning都X掉,否则:https://vjudge.net/solution/19887176
0.看看自己是否有可能需要快读，禁endl
1.数组越界，爆int,浮点精度(查看精度是否达到题目要求,看有没有浮点数比较:eps)，取模操作，初始化数组，边缘数据,输出格式(cas),强制在线是否更新了las
2.通读代码，代码无逻辑错误
3.读题，找到题意理解失误或算法错误
4.放弃
*/


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int s[],int len) {
		int u = root;
		//for (; *s; s++) {
		for(int i=0;i<len;++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const int* s,int len, int id) {
		int u = root, tot = 0;
		for (; tot<len;  tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 0; i < m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);

		//AC1.insert(t + 1,len);
		//reverse(t + 1, t + len + 1);
		//AC2.insert(t + 1,len);
	}

	AC1.build();
	AC1.query(ss + 1,m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1,m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int s[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = s[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* s, int len, int id) {
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = s[i];
			u = nxt[u][c];
			rec[id][i] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);
	}

	AC1.build();
	AC1.query(ss + 1, m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> Q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < S; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int id) {
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			rec[id][i] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);
	}

	AC1.build();
	AC1.query(ss + 1, m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int s[], int len) {
		int u = root;
		//for (; *s; s++) {
		for (int i = 0; i < len; ++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const int* s, int len, int id) {
		int u = root, tot = 0;
		for (; tot < len; tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);

		//AC1.insert(t + 1,len);
		//reverse(t + 1, t + len + 1);
		//AC2.insert(t + 1,len);
	}

	AC1.build();
	AC1.query(ss + 1, m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=int(b);++i)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int maxn = 2e5 + 10;
const int maxm = 26;
struct ACAM {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	bool built;
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(maxm, 0));
		return ++sz;
	}
	void init() {
		sz = 0;
		built = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		built = 1;
		vector <int> Q;
		fail.resize(nxt.size()); fail[root] = root;
		for (int i = 0; i < maxm; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < maxm; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int res[]) {
		assert(built);
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			res[i] = cnt[u];
		}
	}
};
ACAM ACS[2];
int cnt[2][maxn];

vector<int>S, TT;
#define endl '\n'
int main()
{
#ifndef endl
	freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
	cout << "************************************Local Test*********************************" << endl;
#endif // !endl
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	int T(1), cas(0);
	while (cas, T--)
	{
		ACS[0].init(); ACS[1].init();
		string str; cin >> str;
		for (auto &c : str)S.push_back(c - 'a');

		int n; cin >> n;
		F(i, 1, n)
		{
			cin >> str;
			TT.clear();

			for (auto &c : str)TT.push_back(c - 'a');
			ACS[0].insert(&TT[0],TT.size());
			reverse(TT.begin(), TT.end());
			ACS[1].insert(&TT[0],TT.size());
		}
		ACS[0].build(); ACS[1].build();
		ACS[0].query(&S[0], S.size(), cnt[0]);

		reverse(S.begin(), S.end());
		ACS[1].query(&S[0], S.size(), cnt[1]);

		ll ans(0);
		F(i, 0, S.size() - 2)
		{
			ans += 1ll * cnt[0][i] * cnt[1][(S.size() - 2) - i];
		}
		cout << ans << endl;
	}
	return 0;
}
//What to Debug
/*
-1.最好把全部warning都X掉,否则:https://vjudge.net/solution/19887176
0.看看自己是否有可能需要快读，禁endl
1.数组越界，爆int,浮点精度(查看精度是否达到题目要求,看有没有浮点数比较:eps)，取模操作，初始化数组，边缘数据,输出格式(cas),强制在线是否更新了las
2.通读代码，代码无逻辑错误
3.读题，找到题意理解失误或算法错误
4.放弃
*/


 Due to the website downtime, open hacks for ECR 70 have been extended by 24 hours. ��

Educational Codeforces Round 70 (Rated for Div. 2)
Finished
Practice
 Add to favourites

�� Virtual participation
Virtual contest is a way to take part in past contest, as close as possible to participation on time. It is supported only ACM-ICPC mode for virtual contests. If you've seen these problems, a virtual contest is not for you - solve these problems in the archive. If you just want to solve some problem from a contest, a virtual contest is not for you - solve this problem in the archive. Never use someone else's code, read the tutorials or communicate with other person during a virtual contest.

�� Practice
You are registered for practice. You can solve problems unofficially. Results can be found in the contest status and in the bottom of standings.

�� Clone Contest to Mashup
You can clone this contest to a mashup.

�� Contest materials
Announcement #1 (en)
Announcement #2 (ru)
PROBLEMSSUBMIT CODEMY SUBMISSIONSSTATUSHACKSSTANDINGSCUSTOM INVOCATION

My Submissions

#	When	Who	Problem	Lang	Verdict	Time	Memory
58475074	Aug/09/2019 10:42UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Accepted	93 ms	38500 KB
58475010	Aug/09/2019 10:40UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Wrong answer on test 29	93 ms	38600 KB
58474926	Aug/09/2019 10:37UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Wrong answer on test 29	78 ms	38600 KB
58474709	Aug/09/2019 10:31UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Accepted	93 ms	38600 KB
58474565	Aug/09/2019 10:27UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Compilation error	0 ms	0 KB
58461534	Aug/09/2019 00:49UTC+8	deepwarm	E - You Are Given Some Strings...	GNU C++11	Wrong answer on test 1	0 ms	3500 KB

My contest submissions

#	When	Who	Problem	Lang	Verdict	Time	Memory
58443410	Aug/07/2019 23:18UTC+8	deepwarm	B - You Are Given a Decimal String...	GNU C++11	Accepted	46 ms	3100 KB
58443380	Aug/07/2019 23:18UTC+8	deepwarm	B - You Are Given a Decimal String...	GNU C11	Compilation error	0 ms	0 KB
58437886	Aug/07/2019 22:43UTC+8	deepwarm	A - You Are Given Two Binary Strings...	GNU C++11	Accepted	15 ms	500 KB

Codeforces (c) Copyright 2010-2019 Mike Mirzayanov
The only programming contests Web 2.0 platform
Server time: Aug/09/2019 10:42:06UTC+8 (f3).
Desktop version, switch to mobile version.
Privacy Policy
Supported by
Telegram  ��������
By deepwarm, contest: Educational Codeforces Round 70 (Rated for Div. 2), problem: (E) You Are Given Some Strings..., Wrong answer on test 29, #
 ?#include <bits/stdc++.h>
using namespace std;

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int s[],int len) {
		int u = root;
		//for (; *s; s++) {
		for(int i=0;i<len;++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const int* s,int len, int id) {
		int u = root, tot = 0;
		for (; tot<len;  tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);

		//AC1.insert(t + 1,len);
		//reverse(t + 1, t + len + 1);
		//AC2.insert(t + 1,len);
	}

	AC1.build();
	AC1.query(ss + 1,m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1,m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=int(b);++i)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int maxn = 2e5 + 10;
const int maxm = 26;
struct ACAM {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	bool built;
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(maxm, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		built = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		built = 1;
		vector <int> Q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < maxm; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < maxm; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int res[]) {
		assert(built);
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			res[i] = cnt[u];
		}
	}
};
ACAM ACS[2];
int cnt[2][maxn];

vector<int>S, TT;
#define endl '\n'
int main()
{
#ifndef endl
	freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
	cout << "************************************Local Test*********************************" << endl;
#endif // !endl
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	int T(1), cas(0);
	while (cas, T--)
	{
		ACS[0].init(); ACS[1].init();
		string str; cin >> str;
		for (auto &c : str)S.push_back(c - 'a');

		int n; cin >> n;
		F(i, 1, n)
		{
			cin >> str;
			TT.clear();

			for (auto &c : str)TT.push_back(c - 'a');
			ACS[0].insert(&TT[0],TT.size());
			reverse(TT.begin(), TT.end());
			ACS[1].insert(&TT[0],TT.size());
		}
		ACS[0].build(); ACS[1].build();
		ACS[0].query(&S[0], S.size(), cnt[0]);

		reverse(S.begin(), S.end());
		ACS[1].query(&S[0], S.size(), cnt[1]);

		ll ans(0);
		F(i, 0, S.size() - 2)
		{
			ans += 1ll * cnt[0][i] * cnt[1][(S.size() - 2) - i];
		}
		cout << ans << endl;
	}
	return 0;
}
//What to Debug
/*
-1.最好把全部warning都X掉,否则:https://vjudge.net/solution/19887176
0.看看自己是否有可能需要快读，禁endl
1.数组越界，爆int,浮点精度(查看精度是否达到题目要求,看有没有浮点数比较:eps)，取模操作，初始化数组，边缘数据,输出格式(cas),强制在线是否更新了las
2.通读代码，代码无逻辑错误
3.读题，找到题意理解失误或算法错误
4.放弃
*/


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(char c) {
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const char s[],int len) {
		int u = root;
		//for (; *s; s++) {
		for(int i=0;i<len;++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const char* s,int len, int id) {
		int u = root, tot = 0;
		for (; tot<len;  tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';

		AC1.insert(t + 1,len);
		reverse(t + 1, t + len + 1);
		AC2.insert(t + 1,len);
	}

	AC1.build();
	AC1.query(s + 1,m, 0);
	reverse(s + 1, s + m + 1);
	AC2.build();
	AC2.query(s + 1,m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(char c) {
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const char s[],int len) {
		int u = root;
		//for (; *s; s++) {
		for(int i=0;i<len;++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const char* s,int len, int id) {
		int u = root, tot = 0;
		for (; tot<len;  tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';

		AC1.insert(t + 1);
		reverse(t + 1, t + len + 1);
		AC2.insert(t + 1);
	}

	AC1.build();
	AC1.query(s + 1,m, 0);
	reverse(s + 1, s + m + 1);
	AC2.build();
	AC2.query(s + 1,m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(S, 0));
		return ++sz;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> Q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < S; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int str[], int len, int id) {
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			rec[id][i] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);
	}

	AC1.build();
	AC1.query(ss + 1, m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nextt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nextt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nextt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int s[],int len) {
		int u = root;
		//for (; *s; s++) {
		for(int i=0;i<len;++i)
		{
			int c = idx(s[i]);
			int& v = nextt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> q;
		fail.resize(nextt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nextt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nextt[u][i];
				if (v) {
					fail[v] = nextt[fail[u]][i];
					cnt[v] += cnt[nextt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nextt[fail[u]][i];
			}
		}
	}
	void query(const int* s,int len, int id) {
		int u = root, tot = 0;
		for (; tot<len;  tot++) {
			int c = idx(s[tot]);
			u = nextt[u][c];
			rec[id][tot] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 0; i < m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		tt[len + 1] = 0;
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);

		//AC1.insert(t + 1,len);
		//reverse(t + 1, t + len + 1);
		//AC2.insert(t + 1,len);
	}

	ss[m + 1] = 0;
	AC1.build();
	AC1.query(ss + 1,m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1,m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


#include<bits/stdc++.h>
#define F(i,a,b) for(int i=(a);i<=int(b);++i)
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;

const int maxn = 2e5 + 10;
const int maxm = 26;
struct ACAM {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	bool built;
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(maxm, 0));
		return ++sz;
	}
	void init() {
		sz = -1;
		built = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		built = 1;
		vector <int> Q;
		fail.resize(nxt.size()); fail[root] = root;
		for (int i = 0; i < maxm; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < maxm; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int res[]) {
		assert(built);
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			res[i] = cnt[u];
		}
	}
};
ACAM ACS[2];
int cnt[2][maxn];

vector<int>S, TT;
#define endl '\n'
int main()
{
#ifndef endl
	freopen("C:\\Users\\VULCAN\\Desktop\\data.in", "r", stdin);
	cout << "************************************Local Test*********************************" << endl;
#endif // !endl
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);

	int T(1), cas(0);
	while (cas, T--)
	{
		ACS[0].init(); ACS[1].init();
		string str; cin >> str;
		for (auto &c : str)S.push_back(c - 'a');

		int n; cin >> n;
		F(i, 1, n)
		{
			cin >> str;
			TT.clear();

			for (auto &c : str)TT.push_back(c - 'a');
			ACS[0].insert(&TT[0],TT.size());
			reverse(TT.begin(), TT.end());
			ACS[1].insert(&TT[0],TT.size());
		}
		ACS[0].build(); ACS[1].build();
		ACS[0].query(&S[0], S.size(), cnt[0]);

		reverse(S.begin(), S.end());
		ACS[1].query(&S[0], S.size(), cnt[1]);

		ll ans(0);
		F(i, 0, S.size() - 2)
		{
			ans += 1ll * cnt[0][i] * cnt[1][(S.size() - 2) - i];
		}
		cout << ans << endl;
	}
	return 0;
}
//What to Debug
/*
-1.最好把全部warning都X掉,否则:https://vjudge.net/solution/19887176
0.看看自己是否有可能需要快读，禁endl
1.数组越界，爆int,浮点精度(查看精度是否达到题目要求,看有没有浮点数比较:eps)，取模操作，初始化数组，边缘数据,输出格式(cas),强制在线是否更新了las
2.通读代码，代码无逻辑错误
3.读题，找到题意理解失误或算法错误
4.放弃
*/


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

#define F(i,a,b) for(int i=(a);i<=int(b);++i)
const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

//原串对多模式串的匹配
//食用方法: 先init,然后insert掉所有的模式串(模式串处理为int,s[n]赋为0),然后build,然后query匹配串
struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(S, 0));
		return sz++;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(int s[],int len) {//
		int u = root;
		F(i,0,len-1)
		{
			int c = s[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;//u是表示s串的结点
	}
	void build() {
		vector <int> q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < q.size(); k++) {
			int u = q[k];
			for (int i = 0; i < S; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int s[],int len) {
		int u = root, i = 0;
		//for (; *s; s++, i++) {
		F(i,0,len-1)
		{
			int c = s[i];
			u = nxt[u][c];
			//rec[i] = cnt[u];
			//此时cnt[u]是s[?~i]与所有模式串的匹配个数
		}
	}
};
Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int s2[N],t2[N];
int main() {
	int m, n, len;
	long long ans;

	scanf("%s", s + 1);
	m = strlen(s + 1);
	F(i, 0, m - 1)s2[i] = s[i] - 'a';
	AC1.init();
	AC2.init();

	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);

		F(j, 0, len - 1)
			t2[j] = t[j] - 'a';
		AC1.insert(t2 + 1,len);
		reverse(t2 + 1, t2 + len + 1);
		AC2.insert(t2 + 1,len);
	}
	AC1.build();
	AC1.query(s2 + 1, 0);
	reverse(s2 + 1, s2 + m + 1);
	AC2.build();
	AC2.query(s2 + 1, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

const int N = 2e5 + 10;
const int S = 26;

int rec[2][N];

struct Aho_Corasick_Automaton {
	int sz, root;
	vector < vector <int> > nxt;
	vector <int> fail, cnt;
	inline int idx(int c) {
		return c;
		return c - 'a';
	}
	inline int newNode() {
		cnt.push_back(0);
		nxt.push_back(vector <int>(S, 0));
		return ++sz;
	}
	void init() {
		sz = 0;
		nxt.clear();
		cnt.clear();
		fail.clear();
		root = newNode();
	}
	void insert(const int str[], int len) {
		int u = root;
		for (int i = 0; i < len; ++i)
		{
			int c = str[i];
			int& v = nxt[u][c];
			if (!v) v = newNode();
			u = v;
		}
		cnt[u]++;
	}
	void build() {
		vector <int> Q;
		fail.resize(nxt.size());
		fail[root] = root;
		for (int i = 0; i < S; i++) {
			int& v = nxt[root][i];
			if (v) {
				fail[v] = root;
				Q.push_back(v);
			}
			else v = root;
		}
		for (int k = 0; k < Q.size(); k++) {
			int u = Q[k];
			for (int i = 0; i < S; i++) {
				int& v = nxt[u][i];
				if (v) {
					fail[v] = nxt[fail[u]][i];
					cnt[v] += cnt[nxt[fail[u]][i]];
					Q.push_back(v);
				}
				else v = nxt[fail[u]][i];
			}
		}
	}
	void query(const int* str, int len, int id) {
		int u = root;
		for (int i = 0; i < len; ++i) {
			int c = str[i];
			u = nxt[u][c];
			rec[id][i] = cnt[u];
		}
	}
};

Aho_Corasick_Automaton AC1, AC2;
char s[N], t[N];
int ss[N], tt[N];

int main() {
	int m, n, len;
	long long ans;
	scanf("%s", s + 1);
	m = strlen(s + 1);
	for (int i = 1; i <= m; ++i)ss[i] = s[i] - 'a';

	AC1.init();
	AC2.init();
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%s", t + 1);
		len = strlen(t + 1);
		for (int j = 1; j <= len; ++j)tt[j] = t[j] - 'a';
		AC1.insert(tt + 1, len);
		reverse(tt + 1, tt + len + 1);
		AC2.insert(tt + 1, len);
	}

	AC1.build();
	AC1.query(ss + 1, m, 0);
	reverse(ss + 1, ss + m + 1);
	AC2.build();
	AC2.query(ss + 1, m, 1);
	ans = 0;
	for (int i = 0; i < m - 1; i++)
		ans += 1LL * rec[0][i] * rec[1][m - 2 - i];
	printf("%I64d\n", ans);
	return 0;
}


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

struct Nod {
	int next[N][26],fail[N],end[N];
	vector<int> P[N];
	int root,L;
	long long ans[N];
	int newnode()
	{
		for (int i=0;i<26;i++) next[L][i]=-1;
		//end[L++]=0;
		L++;
		return L-1;
	}
	void init()
	{
		L=0;
		root=newnode();
	}
	void insert(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			if (next[now][buf[i]-'a']==-1) next[now][buf[i]-'a']=newnode();
			now=next[now][buf[i]-'a'];
		}
		end[now]++;
	}
	void build()
	{
		queue<int>Q;
		fail[root]=root;
		for (int i=0;i<26;i++)
			if (next[root][i]==-1) next[root][i]=root;
			else
			{
				fail[next[root][i]]=root;
				P[root].push_back(next[root][i]);
				Q.push(next[root][i]);
			}
		while (!Q.empty())
		{
			int now=Q.front();
			Q.pop();
			for (int i=0;i<26;i++)
				if (next[now][i]==-1)
					next[now][i]=next[fail[now]][i];
				else
				{
					fail[next[now][i]]=next[fail[now]][i];
					P[next[fail[now]][i]].push_back(next[now][i]);
					Q.push(next[now][i]);
				}
		}
	}
	void Dfs(int x)
	{
		for (auto v:P[x])
		{
			end[v]+=end[x];
			Dfs(v);
		}
	}
	void query(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			ans[i]=0;
			now=next[now][buf[i]-'a'];
			ans[i]+=end[now];
		}
	}
}ac1,ac2;

char S[N],s[N];
long long ans;
int n;

int main()
{
	ac1.init();
	ac2.init();
	scanf("%s",S);
	int Len=strlen(S);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s);
		int L=strlen(s);
		ac1.insert(s);
		reverse(s,s+L);
		ac2.insert(s);
	}
	ac1.build();
	ac2.build();
	ac1.Dfs(ac1.root);
	ac2.Dfs(ac2.root);
	ac1.query(S);
	reverse(S,S+Len);
	ac2.query(S);
	reverse(ac2.ans,ac2.ans+Len);
	for (int i=0;i<Len-1;i++) ans=ans+ac1.ans[i]*ac2.ans[i+1];
	printf("%lld",ans);
}


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

struct Nod {
	int next[N][26],fail[N],end[N];
	int root,L;
	long long ans[N];
	int newnode()
	{
		for (int i=0;i<26;i++) next[L][i]=-1;
		//end[L++]=0;
		L++;
		return L-1;
	}
	void init()
	{
		L=0;
		root=newnode();
	}
	void insert(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			if (next[now][buf[i]-'a']==-1) next[now][buf[i]-'a']=newnode();
			now=next[now][buf[i]-'a'];
		}
		end[now]++;
	}
	void build()
	{
		queue<int>Q;
		fail[root]=root;
		for (int i=0;i<26;i++)
			if (next[root][i]==-1) next[root][i]=root;
			else
			{
				fail[next[root][i]]=root;
				Q.push(next[root][i]);
			}
		while (!Q.empty())
		{
			int now=Q.front();
			Q.pop();
			for (int i=0;i<26;i++)
				if (next[now][i]==-1)
					next[now][i]=next[fail[now]][i];
				else
				{
					fail[next[now][i]]=next[fail[now]][i];
					Q.push(next[now][i]);
				}
		}
	}
	void query(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			ans[i]=0;
			now=next[now][buf[i]-'a'];
			int tmp=now;
			while (tmp!=root)
			{
				ans[i]+=end[tmp];
				tmp=fail[tmp];
			}
		}
	}
}ac1,ac2;

char S[N],s[N];
long long ans;
int n;

int main()
{
	ac1.init();
	ac2.init();
	scanf("%s",S);
	int Len=strlen(S);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s);
		int L=strlen(s);
		ac1.insert(s);
		reverse(s,s+L);
		ac2.insert(s);
	}
	ac1.build();
	ac2.build();
	ac1.query(S);
	reverse(S,S+Len);
	ac2.query(S);
	reverse(ac2.ans,ac2.ans+Len);
	for (int i=0;i<Len-1;i++) ans=ans+ac1.ans[i]*ac2.ans[i+1];
	printf("%lld",ans);
}


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

struct Nod {
	int next[N][26],fail[N],end[N];
	int root,L;
	long long ans[N];
	int newnode()
	{
		for (int i=0;i<26;i++) next[L][i]=-1;
		end[L++]=0;
		return L-1;
	}
	void init()
	{
		L=0;
		root=newnode();
	}
	void insert(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			if (next[now][buf[i]-'a']==-1) next[now][buf[i]-'a']=newnode();
			now=next[now][buf[i]-'a'];
		}
		end[now]++;
	}
	void build()
	{
		queue<int>Q;
		fail[root]=root;
		for (int i=0;i<26;i++)
			if (next[root][i]==-1) next[root][i]=root;
			else
			{
				fail[next[root][i]]=root;
				Q.push(next[root][i]);
			}
		while (!Q.empty())
		{
			int now=Q.front();
			Q.pop();
			for (int i=0;i<26;i++)
				if (next[now][i]==-1)
					next[now][i]=next[fail[now]][i];
				else
				{
					fail[next[now][i]]=next[fail[now]][i];
					Q.push(next[now][i]);
				}
		}
	}
	void query(char buf[])
	{
		int len=strlen(buf);
		int now=root;
		for (int i=0;i<len;i++)
		{
			ans[i]=0;
			now=next[now][buf[i]-'a'];
			int tmp=now;
			while (tmp!=root)
			{
				ans[i]+=end[tmp];
				tmp=fail[tmp];
			}
		}
	}
}ac1,ac2;

char S[N],s[N],n;
long long ans;

int main()
{
	ac1.init();
	ac2.init();
	scanf("%s",S);
	int Len=strlen(S);
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",s);
		int L=strlen(s);
		ac1.insert(s);
		reverse(s,s+L);
		ac2.insert(s);
	}
	ac1.build();
	ac2.build();
	ac1.query(S);
	reverse(S,S+Len);
	ac2.query(S);
	reverse(ac2.ans,ac2.ans+Len);
	for (int i=0;i<Len-1;i++) ans=ans+ac1.ans[i]*ac2.ans[i+1];
	printf("%lld",ans);
}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define LL long long
#define st first
#define nd second
#define endl '\n'
using namespace std;

const int MAXN = 200205;
int g[MAXN][26], fail[MAXN], out[MAXN], tme, sta[MAXN], ed[MAXN], n;
LL ans;
vector<string> v[MAXN];
string s, t;

void aho(vector<string> &a, int len) {
	memset(g,-1,sizeof g);
	memset(out, 0, sizeof out);
	tme = 0;
	for(int i=0;i<a.size();++i) {
		int cur=0,ch;
		for(int j=0;j<a[i].size();++j)  {
			ch=a[i][j]-'a';
			if(g[cur][ch]==-1)
				g[cur][ch]=++tme;
			cur=g[cur][ch];
		}
		out[cur]++;
	}
	for(int i=0;i<26;++i)
		if(g[0][i]==-1)
			g[0][i]=++tme;
	queue<int> q;
	q.push(0);
	while(!q.empty()) {
		int state=q.front(),nst;
		q.pop();
		for(int i=0;i<26;++i)
			if(g[state][i]!=-1) {
				nst=g[state][i];
				int ff=fail[state];
				while(g[ff][i]==-1)
					ff=fail[ff];
				if(state) fail[nst]=g[ff][i];
				else fail[nst]=0;
				out[nst] += out[fail[nst]];
				q.push(nst);
			}
	}
	int cur=0;
	for(int i=0;i<s.size();++i) {
		int ch=s[i]-'a';
		while(g[cur][ch]==-1)
			cur=fail[cur];
		cur=g[cur][ch];
		if(i >= len - 1)
			sta[i - len + 1] += out[cur];
		ed[i] += out[cur];
		//cout << len << " " << i << " " << cur << " " << out[cur]
	}
}

int main() {

	ios_base::sync_with_stdio(0);
	cin.tie(0);
    cin >> s;
    cin >> n;
    for(int i = 0; i < n; ++i) {
    	cin >> t;
    	v[t.size()].pb(t);
    }
    for(int i = 1; i < MAXN; ++i)
    	if(v[i].size()) {
    		aho(v[i], i);
    	}
    for(int i = 1; i < s.size(); ++i) {
    	//cout << i << " " << sta[i] << endl;
    	ans += 1LL * ed[i - 1] * sta[i];
    }
    cout << ans << endl;

}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define LL long long
#define st first
#define nd second
#define endl '\n'
using namespace std;

const int MAXN = 200205;
int g[MAXN][26], fail[MAXN], out[MAXN], tme, sta[MAXN], ed[MAXN], n;
LL ans;
vector<string> v[MAXN];
string s, t;

void aho(vector<string> &a, int len) {
	tme = 0;
	for(int i=0;i<a.size();++i) {
		int cur=0,ch;
		for(int j=0;j<a[i].size();++j)  {
			ch=a[i][j]-'a';
			if(g[cur][ch]==-1)
				g[cur][ch]=++tme;
			cur=g[cur][ch];
		}
		out[cur]++;
	}
	for(int i=0;i<26;++i)
		if(g[0][i]==-1)
			g[0][i]=++tme;
	queue<int> q;
	q.push(0);
	while(!q.empty()) {
		int state=q.front(),nst;
		q.pop();
		for(int i=0;i<26;++i)
			if(g[state][i]!=-1) {
				nst=g[state][i];
				int ff=fail[state];
				while(g[ff][i]==-1)
					ff=fail[ff];
				if(state) fail[nst]=g[ff][i];
				else fail[nst]=0;
				out[nst] += out[fail[nst]];
				q.push(nst);
			}
	}
	int cur=0;
	for(int i=0;i<s.size();++i) {
		int ch=s[i]-'a';
		while(g[cur][ch]==-1)
			cur=fail[cur];
		cur=g[cur][ch];
		if(i >= len - 1)
			sta[i - len + 1] += out[cur];
		ed[i] += out[cur];
		//cout << len << " " << i << " " << cur << " " << out[cur]
	}
	for(int i = 0; i <= tme; ++i) {
		for(int k = 0; k < 26; ++k)
			g[i][k] = -1;
		out[i] = 0;
	}
}

int main() {

	ios_base::sync_with_stdio(0);
	cin.tie(0);
    cin >> s;
    cin >> n;
    memset(g, -1, sizeof g);
    for(int i = 0; i < n; ++i) {
    	cin >> t;
    	v[t.size()].pb(t);
    }
    for(int i = 1; i < MAXN; ++i)
    	if(v[i].size()) {
    		aho(v[i], i);
    	}
    for(int i = 1; i < s.size(); ++i) {
    	//cout << i << " " << sta[i] << endl;
    	ans += 1LL * ed[i - 1] * sta[i];
    }
    cout << ans << endl;

}


#include <bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define pii pair<int,int>
#define LL long long
#define st first
#define nd second
#define endl '\n'
using namespace std;

const int MAXN = 200005;
int g[MAXN][26], fail[MAXN], out[MAXN], tme, sta[MAXN], ed[MAXN], n;
LL ans;
vector<string> v[MAXN];
string s, t;

void aho(vector<string> &a, int len) {
	memset(g,-1,sizeof g);
	memset(out, 0, sizeof out);
	tme = 0;
	for(int i=0;i<a.size();++i) {
		int cur=0,ch;
		for(int j=0;j<a[i].size();++j)  {
			ch=a[i][j]-'a';
			if(g[cur][ch]==-1)
				g[cur][ch]=++tme;
			cur=g[cur][ch];
		}
		out[cur]++;
	}
	for(int i=0;i<26;++i)
		if(g[0][i]==-1)
			g[0][i]=++tme;
	queue<int> q;
	q.push(0);
	while(!q.empty()) {
		int state=q.front(),nst;
		q.pop();
		for(int i=0;i<26;++i)
			if(g[state][i]!=-1) {
				nst=g[state][i];
				int ff=fail[state];
				while(g[ff][i]==-1)
					ff=fail[ff];
				if(state) fail[nst]=g[ff][i];
				else fail[nst]=0;
				out[nst] += out[fail[nst]];
				q.push(nst);
			}
	}
	int cur=0;
	for(int i=0;i<s.size();++i) {
		int ch=s[i]-'a';
		while(g[cur][ch]==-1)
			cur=fail[cur];
		cur=g[cur][ch];
		if(i >= len - 1)
			sta[i - len + 1] += out[cur];
		ed[i] += out[cur];
		//cout << len << " " << i << " " << cur << " " << out[cur]
	}
}

int main() {

	ios_base::sync_with_stdio(0);
	cin.tie(0);
    cin >> s;
    cin >> n;
    for(int i = 0; i < n; ++i) {
    	cin >> t;
    	v[t.size()].pb(t);
    }
    for(int i = 1; i < MAXN; ++i)
    	if(v[i].size()) {
    		aho(v[i], i);
    	}
    for(int i = 1; i < s.size(); ++i) {
    	//cout << i << " " << sta[i] << endl;
    	ans += 1LL * ed[i - 1] * sta[i];
    }
    cout << ans << endl;

}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<ll, ll> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

struct h{
  int operator()(const ii &a)const{
    return a.F^(a.S<<1);
  }
};

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  while(SZ(s) && SZ(s.back())>=SZ(t))
    s.pop_back();
  n=SZ(s);
  map<ii, ii> hs;
  std::vector<ll> ls;
  ll st=SZ(t);
  std::vector<ll> pa(st+1), pb(st+1), at(st+1), bt(st+1);
  pa[0]=pb[0]=1; at[0]=bt[0]=0;
  for(int i=0; i<st; i++){
    pa[i+1]=(pa[i]*A)%MOD;
    pb[i+1]=(pb[i]*B)%MOD;
    at[i+1]=(at[i]+(t[i]-'a'+1)*pa[i+1])%MOD;
    bt[i+1]=(bt[i]+(t[i]-'a'+1)*pb[i+1])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    std::vector<ll> a(SZ(s[i])+1), b(SZ(s[i])+1);
    a[0]=b[0]=0;
    if(!SZ(ls) || ls.back()!=SZ(s[i]))
      ls.PB(SZ(s[i]));
    for(int j=0; j<SZ(s[i]); j++){
      a[j+1]=(a[j]+(s[i][j]-'a'+1)*pa[j+1])%MOD;
      b[j+1]=(b[j]+(s[i][j]-'a'+1)*pb[j+1])%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    ii hi={(a.back()*pa[st-SZ(s[i])])%MOD,(b.back()*pb[st-SZ(s[i])])%MOD};
    if(!hs.count(hi)){
      for(int k=SZ(ls)-2; k>=0; k--){
        int l=ls[k];
        ii t={(a[l]*pa[st-l])%MOD, (b[l]*pb[st-l])%MOD};
        if(hs.count(t)){
          hs[hi].F+=hs[t].F;
          break;
        }
      }
      for(int k=SZ(ls)-2; k>=0; k--){
        int l=ls[k];
        ii t={((a.back()-a[SZ(s[i])-l]+MOD)*pa[st-SZ(s[i])])%MOD,
          ((b.back()-b[SZ(s[i])-l]+MOD)*pb[st-SZ(s[i])])%MOD};
        if(hs.count(t)){
          hs[hi].S+=hs[t].S;
          break;
        }
      }
    }
    hs[hi].F++;
    hs[hi].S++;
    // cerr << "evw\n";
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S.F<<" "<<x.S.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  reverse(ls.begin(), ls.end());
  for(int i=0; i<st; i++){
    for(auto l: ls){
      if(i+l>st)
        continue;
      ii hi={((at[i+l]-at[i]+MOD)*pa[st-l-i])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l])%MOD};
      if(!hs.count(hi))
        continue;
      b[i]+=hs[hi].F;
      break;
    }
    for(auto l: ls){
      if(i-l<0)
        continue;
      ii hi={((at[i]-at[i-l]+MOD)*pa[st-i])%MOD, ((bt[i]-bt[i-l]+MOD)*pb[st-i])%MOD};
      if(!hs.count(hi))
        continue;
      e[i]+=hs[hi].S;
      break;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<ll, ll> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  std::vector<char> ish(3e6, 0);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  while(SZ(s) && SZ(s.back())>=SZ(t))
    s.pop_back();
  n=SZ(s);
  map<ii, ii> hs;
  std::vector<std::vector<ll> > lsb(26), lse(26);
  ll st=SZ(t);
  std::vector<ll> pa(st+1), pb(st+1), at(st+1), bt(st+1);
  pa[0]=pb[0]=1; at[0]=bt[0]=0;
  for(int i=0; i<st; i++){
    pa[i+1]=(pa[i]*A)%MOD;
    pb[i+1]=(pb[i]*B)%MOD;
    at[i+1]=(at[i]+(t[i]-'a'+1)*pa[i+1])%MOD;
    bt[i+1]=(bt[i]+(t[i]-'a'+1)*pb[i+1])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    std::vector<ll> a(SZ(s[i])+1), b(SZ(s[i])+1);
    a[0]=b[0]=0;
    if(!SZ(lsb[s[i][0]-'a']) || lsb[s[i][0]-'a'].back()!=SZ(s[i]))
      lsb[s[i][0]-'a'].PB(SZ(s[i]));
    if(!SZ(lse[s[i][SZ(s[i])-1]-'a']) || lse[s[i][SZ(s[i])-1]-'a'].back()!=SZ(s[i]))
      lse[s[i][SZ(s[i])-1]-'a'].PB(SZ(s[i]));
    for(int j=0; j<SZ(s[i]); j++){
      a[j+1]=(a[j]+(s[i][j]-'a'+1)*pa[j+1])%MOD;
      b[j+1]=(b[j]+(s[i][j]-'a'+1)*pb[j+1])%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    ii hi={(a.back()*pa[st-SZ(s[i])])%MOD,(b.back()*pb[st-SZ(s[i])])%MOD};
    if(!hs.count(hi)){
      for(int k=SZ(lsb[s[i][0]-'a'])-2; k>=0; k--){
        int l=lsb[s[i][0]-'a'][k];
        ii t={(a[l]*pa[st-l])%MOD, (b[l]*pb[st-l])%MOD};
        if(hs.count(t)){
          hs[hi].F+=hs[t].F;
          break;
        }
      }
      for(int k=SZ(lse[s[i][SZ(s[i])-1]-'a'])-2; k>=0; k--){
        int l=lse[s[i][SZ(s[i])-1]-'a'][k];
        ii t={((a.back()-a[SZ(s[i])-l]+MOD)*pa[st-SZ(s[i])])%MOD,
          ((b.back()-b[SZ(s[i])-l]+MOD)*pb[st-SZ(s[i])])%MOD};
        if(hs.count(t)){
          hs[hi].S+=hs[t].S;
          break;
        }
      }
    }
    hs[hi].F++;
    hs[hi].S++;
    ish[hi.F%SZ(ish)]=1;
    // cerr << "evw\n";
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S.F<<" "<<x.S.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  for(int i=0; i<26; i++){
    reverse(lsb[i].begin(), lsb[i].end());
    reverse(lse[i].begin(), lse[i].end());
  }
  for(int i=0; i<st; i++){
    for(auto l: lsb[t[i]-'a']){
      if(i+l>st)
        continue;
      ii hi={((at[i+l]-at[i]+MOD)*pa[st-l-i])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l])%MOD};
      if(!ish[hi.F%SZ(ish)] || !hs.count(hi))
        continue;
      b[i]+=hs[hi].F;
      break;
    }
    for(auto l: lse[t[i]-'a']){
      if(i-l<0)
        continue;
      ii hi={((at[i]-at[i-l]+MOD)*pa[st-i])%MOD, ((bt[i]-bt[i-l]+MOD)*pb[st-i])%MOD};
      if(!ish[hi.F%SZ(ish)] || !hs.count(hi))
        continue;
      e[i]+=hs[hi].S;
      break;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<ll, ll> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

struct h{
  int operator()(const ii &a)const{
    return a.F^(a.S<<1);
  }
};

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  map<ii, ii> hs;
  std::vector<ll> ls;
  ll st=SZ(t);
  std::vector<ll> pa(st+1), pb(st+1), at(st+1), bt(st+1);
  pa[0]=pb[0]=1; at[0]=bt[0]=0;
  for(int i=0; i<st; i++){
    pa[i+1]=(pa[i]*A)%MOD;
    pb[i+1]=(pb[i]*B)%MOD;
    at[i+1]=(at[i]+(t[i]-'a'+1)*pa[i+1])%MOD;
    bt[i+1]=(bt[i]+(t[i]-'a'+1)*pb[i+1])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    std::vector<ll> a(SZ(s[i])+1), b(SZ(s[i])+1);
    a[0]=b[0]=0;
    if(!SZ(ls) || ls.back()!=SZ(s[i]))
      ls.PB(SZ(s[i]));
    for(int j=0; j<SZ(s[i]); j++){
      a[j+1]=(a[j]+(s[i][j]-'a'+1)*pa[j+1])%MOD;
      b[j+1]=(b[j]+(s[i][j]-'a'+1)*pb[j+1])%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    ii hi={(a.back()*pa[st-SZ(s[i])])%MOD,(b.back()*pb[st-SZ(s[i])])%MOD};
    if(!hs.count(hi))
      for(auto l: ls){
        if(l==SZ(s[i]))
          break;
        hs[hi].F+=hs[{(a[l]*pa[st-l])%MOD, (b[l]*pb[st-l])%MOD}].F;
        hs[hi].S+=hs[{((a.back()-a[SZ(s[i])-l]+MOD)*pa[st-SZ(s[i])])%MOD,
          ((b.back()-b[SZ(s[i])-l]+MOD)*pb[st-SZ(s[i])])%MOD}].S;
      }
    hs[hi].F++;
    hs[hi].S++;
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S.F<<" "<<x.S.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  reverse(ls.begin(), ls.end());
  for(int i=0; i<st; i++){
    for(auto l: ls){
      if(i+l>st)
        continue;
      ii hi={((at[i+l]-at[i]+MOD)*pa[st-l-i])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l])%MOD};
      if(!hs.count(hi))
        continue;
      b[i]+=hs[hi].F;
      break;
    }
    for(auto l: ls){
      if(i-l<0)
        continue;
      ii hi={((at[i]-at[i-l]+MOD)*pa[st-i])%MOD, ((bt[i]-bt[i-l]+MOD)*pb[st-i])%MOD};
      if(!hs.count(hi))
        continue;
      e[i]+=hs[hi].S;
      break;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<ll, ll> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  map<ii, ll> hs;
  std::vector<ll> ls;
  ll st=SZ(t);
  std::vector<ll> pa(st), pb(st), at(st), bt(st);
  pa[0]=pb[0]=1; at[0]=bt[0]=t[0]-'a'+1;
  for(int i=1; i<st; i++){
    pa[i]=(pa[i-1]*A)%MOD;
    pb[i]=(pb[i-1]*B)%MOD;
    at[i]=(at[i-1]+(t[i]-'a'+1)*pa[i])%MOD;
    bt[i]=(bt[i-1]+(t[i]-'a'+1)*pb[i])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    ll a=0, b=0;
    if(!SZ(ls) || ls.back()!=SZ(s[i]))
      ls.PB(SZ(s[i]));
    for(auto c: s[i]){
      a=(a*A+(c-'a'+1))%MOD;
      b=(b*B+(c-'a'+1))%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    hs[{(a*pa[st-SZ(s[i])])%MOD,(b*pb[st-SZ(s[i])])%MOD}]++;
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  for(auto l: ls){
    ll t=hs[{(at[l-1]*pa[st-l])%MOD, (bt[l-1]*pb[st-l])%MOD}];
    b[0]+=t;
    e[l]+=t;
    for(int i=0; i+l<st; i++){
      // cerr <<((at[i+l]-at[i]+MOD)*pa[st-l-i-1])%MOD<<" "<<((bt[i+l]-bt[i]+MOD)*pb[st-i-l-1])%MOD<<"\n";
      ll t=hs[{((at[i+l]-at[i]+MOD)*pa[st-l-i-1])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l-1])%MOD}];
      // cerr << l << " "<<i << " "<<t<<"\n";
      b[i+1]+=t;
      e[i+l+1]+=t;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<ll, ll> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  std::vector<char> ish(3e6, 0);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  while(SZ(s) && SZ(s.back())>=SZ(t))
    s.pop_back();
  n=SZ(s);
  map<ii, ii> hs;
  std::vector<ll> ls;
  ll st=SZ(t);
  std::vector<ll> pa(st+1), pb(st+1), at(st+1), bt(st+1);
  pa[0]=pb[0]=1; at[0]=bt[0]=0;
  for(int i=0; i<st; i++){
    pa[i+1]=(pa[i]*A)%MOD;
    pb[i+1]=(pb[i]*B)%MOD;
    at[i+1]=(at[i]+(t[i]-'a'+1)*pa[i+1])%MOD;
    bt[i+1]=(bt[i]+(t[i]-'a'+1)*pb[i+1])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    std::vector<ll> a(SZ(s[i])+1), b(SZ(s[i])+1);
    a[0]=b[0]=0;
    if(!SZ(ls) || ls.back()!=SZ(s[i]))
      ls.PB(SZ(s[i]));
    for(int j=0; j<SZ(s[i]); j++){
      a[j+1]=(a[j]+(s[i][j]-'a'+1)*pa[j+1])%MOD;
      b[j+1]=(b[j]+(s[i][j]-'a'+1)*pb[j+1])%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    ii hi={(a.back()*pa[st-SZ(s[i])])%MOD,(b.back()*pb[st-SZ(s[i])])%MOD};
    if(!hs.count(hi)){
      for(int k=SZ(ls)-2; k>=0; k--){
        int l=ls[k];
        ii t={(a[l]*pa[st-l])%MOD, (b[l]*pb[st-l])%MOD};
        if(hs.count(t)){
          hs[hi].F+=hs[t].F;
          break;
        }
      }
      for(int k=SZ(ls)-2; k>=0; k--){
        int l=ls[k];
        ii t={((a.back()-a[SZ(s[i])-l]+MOD)*pa[st-SZ(s[i])])%MOD,
          ((b.back()-b[SZ(s[i])-l]+MOD)*pb[st-SZ(s[i])])%MOD};
        if(hs.count(t)){
          hs[hi].S+=hs[t].S;
          break;
        }
      }
    }
    hs[hi].F++;
    hs[hi].S++;
    ish[hi.F%SZ(ish)]=1;
    // cerr << "evw\n";
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S.F<<" "<<x.S.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  reverse(ls.begin(), ls.end());
  for(int i=0; i<st; i++){
    for(auto l: ls){
      if(i+l>st)
        continue;
      ii hi={((at[i+l]-at[i]+MOD)*pa[st-l-i])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l])%MOD};
      if(!ish[hi.F%SZ(ish)] || !hs.count(hi))
        continue;
      b[i]+=hs[hi].F;
      break;
    }
    for(auto l: ls){
      if(i-l<0)
        continue;
      ii hi={((at[i]-at[i-l]+MOD)*pa[st-i])%MOD, ((bt[i]-bt[i-l]+MOD)*pb[st-i])%MOD};
      if(!ish[hi.F%SZ(ish)] || !hs.count(hi))
        continue;
      e[i]+=hs[hi].S;
      break;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MT make_tuple
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7)
#define A 13
#define B 11
#define C 17
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<int, int> ii;
typedef std::vector<ii> vii;
typedef std::map<ll, ll> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

template<class T>
void in(T &a){
  for(auto &x: a)
    cin >> x;
}

template<class T>
void out(T &a){
  for(auto x: a)
    cout << x << " ";
  cout << '\n';
}

template<class T>
void err(T &a){
  for(auto x: a)
    cerr << x << " ";
  cerr << '\n';
}

struct h{
  int operator()(const ii &a)const{
    return a.F^(a.S<<1);
  }
};

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  in(s);
  sort(s.begin(), s.end(), [](const string &a, const string &b){ return SZ(a)<SZ(b); });
  unordered_map<ii, ll, h> hs;
  std::vector<ll> ls;
  ll st=SZ(t);
  std::vector<ll> pa(st), pb(st), at(st), bt(st);
  pa[0]=pb[0]=1; at[0]=bt[0]=t[0]-'a'+1;
  for(int i=1; i<st; i++){
    pa[i]=(pa[i-1]*A)%MOD;
    pb[i]=(pb[i-1]*B)%MOD;
    at[i]=(at[i-1]+(t[i]-'a'+1)*pa[i])%MOD;
    bt[i]=(bt[i-1]+(t[i]-'a'+1)*pb[i])%MOD;
  }
  // cerr << "at: "; err(at);
  // cerr << "bt: "; err(bt);
  for(int i=0; i<n; i++){
    ll a=0, b=0;
    if(!SZ(ls) || ls.back()!=SZ(s[i]))
      ls.PB(SZ(s[i]));
    for(auto c: s[i]){
      a=(a*A+(c-'a'+1))%MOD;
      b=(b*B+(c-'a'+1))%MOD;
    }
    // cerr << s[i]<<" "<<a<<" "<<b<<"\n";
    hs[{(a*pa[st-SZ(s[i])])%MOD,(b*pb[st-SZ(s[i])])%MOD}]++;
  }
  // cerr << "hs:\n"; for(auto x: hs) cerr << x.F.F<<" "<<x.F.S<<">"<<x.S<<"\n";
  std::vector<ll> b(st), e(st+1);
  for(auto l: ls){
    ll t=hs[{(at[l-1]*pa[st-l])%MOD, (bt[l-1]*pb[st-l])%MOD}];
    b[0]+=t;
    e[l]+=t;
    for(int i=0; i+l<st; i++){
      // cerr <<((at[i+l]-at[i]+MOD)*pa[st-l-i-1])%MOD<<" "<<((bt[i+l]-bt[i]+MOD)*pb[st-i-l-1])%MOD<<"\n";
      ll t=hs[{((at[i+l]-at[i]+MOD)*pa[st-l-i-1])%MOD, ((bt[i+l]-bt[i]+MOD)*pb[st-i-l-1])%MOD}];
      // cerr << l << " "<<i << " "<<t<<"\n";
      b[i+1]+=t;
      e[i+l+1]+=t;
    }
  }
  // err(b);
  // err(e);
  ll res=0;
  for(int i=0; i<st; i++)
    res+=b[i]*e[i];
  cout << res << "\n";
}


#include <bits/stdc++.h>

//#pragma GCC optimize ("O3")
//#pragma GCC optimize ("Ofast")

#define F first
#define S second
#define MP make_pair
#define PB push_back
#define LBS 20
#define MOD ((long long)1e9+7) //1e9+9
#define MAX 1000000
#define LEFT(i) (2*(i))
#define RIGHT(i) (2*(i)+1)
#define PAR(i) ((i)/2)
#define SZ(a) ((int)(a).size())

using namespace std;

typedef long long ll;
typedef double rat;
typedef long long bi;
typedef pair<int, int> ii;
typedef std::vector<ii> vii;
typedef std::map<int, int> mii;
typedef bitset<LBS> bis;
typedef std::vector<bis> vbs;

void vin(std::vector<int> &a){
  for(auto &x: a)
    cin >> x;
}

void vout(std::vector<int> &a){
  for(auto x: a)
    cout << x << " ";
  cout << endl;
}

struct node{
  map<char,int> next;
  int back;
  int l;
  node(){
    back=l=-1;
  }
};

std::vector<node> trie;
std::vector<ll> b, e;

void tinsert(string &s){
  int n=0;
  for(auto c: s){
    if(!trie[n].next.count(c)){
      trie[n].next[c]=SZ(trie);
      trie.PB(node());
    }
    n=trie[n].next[c];
  }
  trie[n].l=SZ(s);
}

int main(){
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  string t; int n; cin >> t >> n;
  std::vector<string> s(n);
  b.resize(SZ(t), 0);
  e.resize(SZ(t), 0);
  for(int i=0; i<n; i++)
    cin >> s[i];
  trie.PB(node());
  for(auto &x: s)
    tinsert(x);
  deque<int> dq;
  trie[0].back=0;
  for(auto x: trie[0].next){
    trie[x.S].back=0;
    dq.push_back(x.S);
  }
  while(!dq.empty()) {
    int cur=dq.front(); dq.pop_front();
    int suf=cur;
    for(auto x: trie[cur].next) {
      while(!(trie[trie[suf].back].next.count(x.F)) && suf!=0)
        suf=trie[suf].back;
      if(!(trie[trie[suf].back].next.count(x.F)))
        trie[x.S].back=0;
      else
        trie[x.S].back=trie[trie[suf].back].next[x.F];
      dq.push_back(x.S);
    }
  }
  for(int i=0; i<SZ(trie); i++){
    cerr << i <<" ^ "<<trie[i].back<<":\n";
    for(auto x: trie[i].next)
      cerr << " "<<x.F<<"->"<<x.S<<"   ";
    cerr <<"\n";
  }
  int cur=0;
  for(int i=0; i<SZ(t); i++){
    auto c=t[i];
    if(trie[cur].next.count(c))
      n=trie[cur].next[c];
    else
      n=trie[cur].back;
    if(trie[cur].l!=-1){
      e[i]++;
      b[i-trie[cur].l+1]++;
    }
  }
  ll res=0;
  for(int i=0; i<SZ(t); i++)
    res+=e[i]*b[i];
  cout << res << "\n";
}