#include <bits/stdc++.h>
using namespace std;
const int MAXN = 10005;
template<size_t N>
struct Trie
{
struct Node
{
bool flag;
unordered_map<string, Node*> next;
} pool[N], *alloc, *root;
Node* new_node(bool flag)
{
Node* res = alloc++;
res->flag = flag;
res->next.clear();
return res;
}
void init()
{
alloc = pool;
root = new_node(true);
}
void build(const vector<string>& v, bool flag)
{
Node* curr = root;
for (auto& s : v)
{
if (curr->next.find(s) == curr->next.end())
curr->next[s] = new_node(false);
curr = curr->next[s];
if (flag) curr->flag = true;
}
}
int dfs(Node* x)
{
int res = 0;
for (auto& i : x->next)
{
if (i.second->flag)
res += dfs(i.second);
else res++;
}
return res;
}
};
Trie<MAXN> trie;
int n, m;
char line[MAXN];
int main()
{
// freopen("input.in", "r", stdin);
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d%d", &n, &m);
// printf("%d %d\n", n, m);
trie.init();
for (int i = 1; i <= n; i ++)
{
scanf("%s", line);
vector<string> v;
string s;
for (int j = 0; line[j]; j ++)
{
char c = line[j];
if (islower(c)) s += c;
else
{
v.push_back(s);
s = "";
}
}
v.push_back(s);
trie.build(v, false);
}
for (int i = 1; i <= m; i ++)
{
scanf("%s", line);
vector<string> v;
string s;
for (int j = 0; line[j]; j ++)
{
char c = line[j];
if (islower(c)) s += c;
else
{
v.push_back(s);
s = "";
}
}
v.push_back(s);
trie.build(v, true);
}
int ans = trie.dfs(trie.root);
printf("%d\n", ans);
}
return 0;
}
/*
2
3 0
data/train
data/test
model
3 1
data/train
data/test
model
data/sample
*/
08-22
08-22