#include <bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair <int, int>
#define fi first
#define se second
using namespace std;
const int N = 4e5+5, B = 200, inf = 0x3f3f3f3f;
int n, m, ls[N], rs[N], bg[N], rv[N], lv[N], id[N];
string a[N], b[N];
int r[N];
int gmax (string s) {
int res = 1;
r[0] = 1;
for (int i = 1, j = 0, mr = 0;i < s.size();i++) {
r[i] = 0;
if (mr >= i) r[i] = min(r[j+j-i], mr-i+1);
while (i-r[i] >= 0 && i+r[i] < s.size() && s[i-r[i]] == s[i+r[i]]) r[i]++;
if (i+r[i]-1 > mr) mr = i+r[i]-1, j = i;
res = max(res, r[i]);
}
return res;
}
struct _SA {
int rk[N], sa[N], cnt[N], ts[N], tk[N], ht[N], id[N], st[25][N];
void SA (int *s, int n) {
int m = 0;
for (int i = 1;i <= n;i++) m = max(m, s[i]);
memset(cnt, 0, m+1<<2);
for (int i = 1;i <= n;i++) cnt[rk[i] = s[i]]++;
for (int i = 1;i <= m;i++) cnt[i] += cnt[i-1];
for (int i = 1;i <= n;i++) sa[cnt[rk[i]]--] = i;
// for (int i = 1;i <= n;i++) cout << sa[i] << " "; cout << endl;
for (int p = 0, t = 1; ;t <<= 1, m = p, p = 0) {
for (int i = n-t+1;i <= n;i++) ts[++p] = i;
for (int i = 1;i <= n;i++) if (sa[i] > t) ts[++p] = sa[i]-t;
// cout << "P:" <<p <<" " << n << " " << t << endl;
// for (int i = 1;i <= p;i++) cout << ts[i] << " "; cout << endl;
memset(cnt, 0, m+1<<2); memcpy(tk, rk, n+1<<2);
for (int i = 1;i <= p;i++) cnt[rk[ts[i]]]++;
for (int i = 1;i <= m;i++) cnt[i] += cnt[i-1];
for (int i = 1;i <= p;i++) sa[cnt[rk[ts[i]]]--] = ts[i];
// for (int i = 1;i <= n;i++) cout << sa[i] << " "; cout << endl;
rk[sa[1]] = p = 1;
for (int i = 2;i <= n;i++) rk[sa[i]] = tk[sa[i-1]] == tk[sa[i]] && tk[sa[i-1]+t] == tk[sa[i]+t] ? p : ++p;
// cout <<p <<" " <<n<<endl;
if (p == n) break;
}
int k = 0;
for (int i = 1;i <= n;i++) {
if (k) k--;
if (rk[i] == 1) continue;
whlie (i+k <= n && sa[rk[i]-1]+k <= n && s[i+k] == s[sa[rk[i]-1]+k]) k++;
ht[rk[i]] = k;
}
// for (int i = 1;i <= n;i++) cout << ht[i] << " "; cout << endl;
for (int i = 1;i <= n;i++) st[0][i] = ht[i];
for (int i = 1;i < 25;i++) {
for (int j = 1;j+(1<<i)-1 <= n;j++) st[i][j] = min(st[i-1][j], st[i-1][j+(1<<i-1)]);
}
}
inline int LCP (int x, int y) {
x = rk[x]; y = rk[y];
if (x > y) swap(x, y);
int k = __lg(y-x);
return min(st[k][x+1], st[k][y-(1<<k)+1]);
}
}sa;
struct sgt {
int o[N<<2], s[N<<2];
inline void push_up (int p, int sz) {
s[p] = o[p] ? sz : (sz > 1 ? s[p<<1]+s[p<<1|1] : 0);
}
void build (int p, int l, int r) {
o[p] = 0;
if (l == r) return s[p] = 0, void();
int mid = l+r>>1;
build(p<<1, l, mid); build(p<<1|1, mid+1, r);
push_up(p, r-l+1);
}
void uadd (int p, int l, int r, int tl, int tr, int k) {
if (tl <= l && r <= tr) {
o[p] += k; push_up(p, r-l+1);
return;
}
int mid = l+r>>1;
if (tl <= mid) uadd(p<<1, l, mid, tl, tr, k);
if (tr > mid) uadd(p<<1|1, mid+1, r, tl, tr, k);
push_up(p, r-l+1);
}
}tr;
struct node {
int l, r, v;
};
vector <node> ad[N];
ll solve (int k) {
for (int i = 1;i <= n;i++) ad[i].clear();
for (int I = 1;I <= n;I++) {
int i = ls[I];
int d = gmax(a[i]);
if (d < k)
for (int j = 0;j < a[i].size();j++) {
if (r[j] <= j) continue;
int s = sa.rk[bg[i]+j+r[j]];
int x = lower_bound(rv+1, rv+1+m, s)-rv;
int tl = 1, tr = x;
while (tl < tr) {
int mid = tl+tr>>1;
if (sa.LCP(id[rs[mid]], bg[i]+j+r[j]) >= k-r[j]) tr = mid;
else tl = mid+1;
}
int sl = tl;
tl = x-1, tr = m;
while (tl < tr) {
int mid = tl+tr+1>>1;
if (sa.LCP(id[rs[mid]], bg[i]+j+r[j]) >= k-r[j]) tl = mid;
else tr = mid-1;
}
int sr = tr;
if (sl <= sr) ad[I].pb((node){sl, sr, 1}), ad[I+1].pb((node){sl, sr, -1});
}
else {
ad[I].pb((node){1, m, 1}); ad[I+1].pb((node){1, m, -1});
}
}
for (int I = 1;I <= m;I++) {
int i = rs[I];
int d = gmax(b[i]);
if (d < k)
for (int j = 0;j < b[i].size();j++) {
if (r[j] <= j) continue;
int s = sa.rk[id[i]+j+r[j]];
// cout << "CHK:" << i << " " << r[j] << " " << j << " " << sb.rk[id[i]+j+r[j]] << endl;
int x = lower_bound(lv+1, lv+1+n, s)-lv;
// cout << bg[ls[3]] << " " << id[i]+j+r[j] << " " << sb.LCP(bg[ls[3]], id[i]+j+r[j]) << endl;
int tl = 1, tr = x;
while (tl < tr) {
int mid = tl+tr>>1;
if (sa.LCP(bg[ls[mid]], id[i]+j+r[j]) >= k-r[j]) tr = mid;
else tl = mid+1;
}
int sl = tl;
tl = x-1, tr = n;
while (tl < tr) {
int mid = tl+tr+1>>1;
if (sa.LCP(bg[ls[mid]], id[i]+j+r[j]) >= k-r[j]) tl = mid;
else tr = mid-1;
}
int sr = tr;
if (sl <= sr) ad[sl].pb((node){I, I, 1}), ad[sr+1].pb((node){I, I, -1});
}
else {
ad[1].pb((node){I, I, 1});
}
// cout << "B:" << I << " " << sl << " " << sr << endl;
}
tr.build(1, 1, m);
ll res = 0;
for (int i = 1;i <= n;i++) {
for (auto j : ad[i]) tr.uadd(1, 1, m, j.l, j.r, j.v);
res += tr.s[1];
}
// cout << k << " " << res << endl;
return res;
}
int ds[N], al, am[N], bm[N];
int main () {
cin >> n >> m;
for (int i = 1;i <= n;i++) cin >> a[i];
for (int i = 1;i <= m;i++) cin >> b[i];
ll ans = 0;
for (int i = 1;i <= n;i++) {
bg[i] = al+1;
reverse(a[i].begin(), a[i].end());
for (auto j : a[i]) ds[++al] = j; ds[++al] = i+'z';
}
for (int i = 1;i <= m;i++) {
string ns = b[i];
id[i] = al+1;
for (auto j : b[i]) ds[++al] = j; ds[++al] = i+n+'z';
}
sa.SA(ds, al);
for (int i = 1;i <= m;i++) rs[i] = i;
sort(rs+1, rs+1+m, [&](int x, int y){ return sa.rk[id[x]] < sa.rk[id[y]]; });
for (int i = 1;i <= m;i++) rv[i] = sa.rk[id[rs[i]]];
for (int i = 1;i <= n;i++) ls[i] = i;
sort(ls+1, ls+1+m, [&](int x, int y){ return sa.rk[bg[x]] < sa.rk[bg[y]]; });
for (int i = 1;i <= n;i++) lv[i] = sa.rk[bg[ls[i]]];
for (int i = 1;i <= 10000;i++) ans += solve(i);
for (int i = 1;i <= n;i++) am[i] = gmax(a[i]);
for (int i = 1;i <= m;i++) bm[i] = gmax(b[i]);
cout << ans;
return 0;
}