#include <iostream>#include <cstdio>#include <algorithm>#include <vector>#include <cstring>using namespace std;typedef long long LL;const int M = 100005;const int N = 1005;int n , m , cnt[26] , end[26];char a[N][N] , b[N][N];LL ans = 0;struct Trie { int tot; struct trie { trie *next[26]; }s[M] , *root; trie *newnode () { trie *p = &s[tot ++]; memset (p -> next , 0 , sizeof(p -> next)); return p; } void init () { memset (cnt , 0 , sizeof(cnt)); tot = 0; root = newnode (); } void insert (char *s) { trie *p = root; for (int i = 0 ; s[i] ; i ++) { int c = s[i] - 'a'; if (p -> next[c] == NULL) { p -> next[c] = newnode (); } p = p -> next[c]; } } void cal (trie *p) { for (int i = 0 ; i < 26 ; i ++) { if (p -> next[i]) { cnt[i] ++; cal (p -> next[i]); } } } void gao (trie *p) { for (int i = 0 ; i < 26 ; i ++) { if (p -> next[i] == NULL) { if (p != root) ans += cnt[i]; } else { if (p != root && end[i]) ans ++; gao (p -> next[i]); } } }}suffix , prefix;int main () { while (scanf ("%d %d" , &n , &m) != EOF && n + m) { prefix.init ();suffix.init (); ans = 0; memset (cnt , 0 , sizeof (cnt)); memset (end , 0 , sizeof (end)); for (int i = 0 ; i < n ; i ++) { scanf ("%s" , a[i]); prefix.insert (a[i]); } for (int i = 0 ; i < m ; i ++) { scanf ("%s" , b[i]); reverse (b[i] , b[i] + strlen(b[i])); end[b[i][0] - 'a'] = 1; suffix.insert (b[i]); } suffix.cal (suffix.root); prefix.gao (prefix.root); printf ("%lld\n" , ans); } return 0;}