1 #include<cstdio> 2 #include<cstring> 3 #include<queue> 4 #define MAXN 60000 5 #define MAXL (1<<10) 6 #define MAXM 200 7 using namespace std; 8 struct Trie { 9 bool virus; 10 int end, fail, next[2]; 11 void Init() { 12 virus = false; 13 end = fail = next[0] = next[1] = 0; 14 } 15 }; 16 Trie tree[MAXN]; 17 char str[MAXN]; 18 int size, cnt; 19 int pos[MAXM], dis[MAXN], G[MAXM][MAXM], dp[MAXL][MAXM]; 20 void Insert(char *s, int id) { 21 int now, t; 22 for (now = 0; *s; s++) { 23 t = *s - '0'; 24 if (!tree[now].next[t]) { 25 tree[++size].Init(); 26 tree[now].next[t] = size; 27 } 28 now = tree[now].next[t]; 29 } 30 if (id >= 0) 31 tree[now].end = 1 << id; 32 else 33 tree[now].virus = true; 34 } 35 void BFS() { 36 int now, i, p; 37 queue<int> q; 38 q.push(0); 39 while (!q.empty()) { 40 now = q.front(); 41 q.pop(); 42 for (i = 0; i < 2; i++) { 43 if (tree[now].next[i]) { 44 p = tree[now].next[i]; 45 q.push(p); 46 if (now) 47 tree[p].fail = tree[tree[now].fail].next[i]; 48 tree[p].end |= tree[tree[p].fail].end; 49 tree[p].virus |= tree[tree[p].fail].virus; 50 } else 51 tree[now].next[i] = tree[tree[now].fail].next[i]; 52 } 53 } 54 } 55 void Path(int k) { 56 int now, i, p; 57 queue<int> q; 58 q.push(pos[k]); 59 memset(dis, -1, sizeof(dis)); 60 dis[pos[k]] = 0; 61 while (!q.empty()) { 62 now = q.front(); 63 q.pop(); 64 for (i = 0; i < 2; i++) { 65 p = tree[now].next[i]; 66 if (dis[p] < 0 && !tree[p].virus) { 67 dis[p] = dis[now] + 1; 68 q.push(p); 69 } 70 } 71 } 72 for (i = 0; i < cnt; i++) 73 G[k][i] = dis[pos[i]]; 74 } 75 inline int MIN(int x, int y) { 76 if (x < 0 || y < 0) 77 return x > y ? x : y; 78 return x > y ? y : x; 79 } 80 void DoIt(int n) { 81 int i, j, k, t, ans; 82 memset(dp, -1, sizeof(dp)); 83 dp[0][0] = 0; 84 for (i = 0; i < (1 << n); i++) { 85 for (j = 0; j < cnt; j++) { 86 if (dp[i][j] < 0) 87 continue; 88 for (k = 0; k < cnt; k++) { 89 if (G[j][k] < 0) 90 continue; 91 t = i | tree[pos[k]].end; 92 dp[t][k] = MIN(dp[t][k], dp[i][j] + G[j][k]); 93 } 94 } 95 } 96 t = (1 << n) - 1; 97 for (ans = -1, i = 0; i < cnt; i++) 98 ans = MIN(ans, dp[t][i]); 99 printf("%d\n", ans); 100 } 101 int main() { 102 int n, m, i; 103 while (scanf("%d%d", &n, &m), n) { 104 tree[0].Init(); 105 for (size = i = 0; i < n; i++) { 106 scanf(" %s", str); 107 Insert(str, i); 108 } 109 while (m--) { 110 scanf(" %s", str); 111 Insert(str, -1); 112 } 113 BFS(); 114 pos[0] = 0; 115 for (cnt = 1, i = 0; i <= size; i++) { 116 if (tree[i].end) 117 pos[cnt++] = i; 118 } 119 for (i = 0; i < cnt; i++) 120 Path(i); 121 DoIt(n); 122 } 123 return 0; 124 }