ac自动机,状态dp
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <queue>
#include <map>
using namespace std;
const int MAX = 60005;
const int INF = 0x48484848;
struct node
{
int fail, next[2];
bool varu;
int type;
void init()
{
fail = 0;
next[0] = next[1] = 0;
varu = false;
type = 0;
}
} data[MAX];
int cnt, n, m, endSize;
int root, q[MAX];
char str[1005];
int pos[15];
int dis[MAX];
int G[15][15];
int dp[1<<10][15];
void inst(int k, bool c)
{
int p = 0;
char *tc = str;
for (; *tc; tc++)
{
if (data[p].next[*tc-'0'] == 0)
{
data[p].next[*tc-'0'] = ++cnt;
data[cnt].init();
}
p = data[p].next[*tc-'0'];
}
if (c)
data[p].varu |= 1;
else
data[p].type |= (1<<k);
}
void buildAC()
{
int head = 0, tail = 0;
q[tail++] = root;
int i;
while (head != tail)
{
int tp = q[head++];
data[tp].type |= data[data[tp].fail].type;
data[tp].varu |= data[data[tp].fail].varu;
for ( i = 0; i< 2; i++)
{
if (data[tp].next[i])
{
if (tp != root)
data[data[tp].next[i]].fail = data[data[tp].fail].next[i];
q[tail++] = data[tp].next[i];
}
else
{
if (tp != root)
data[tp].next[i] = data[data[tp].fail].next[i];
}
}
}
}
void bfs(int k)
{
int head = 0, tail = 0;
int now, p, i;
q[tail++] = pos[k];
memset(dis, -1, sizeof dis);
dis[pos[k]] = 0;
while (head != tail)
{
now = q[head++];
for ( i = 0; i< 2; i++)
{
p = data[now].next[i];
if (dis[p] < 0 && !data[p].varu)
{
dis[p] = dis[now]+1;
q[tail++] = p;
}
}
}
for ( i = 0; i<endSize; i++ )
{
G[k][i] = dis[pos[i]];
}
}
inline min(int a, int b)
{
return a<b?a:b;
}
int solve()
{
int full = (1<<n)-1;
int i, j, k;
memset(dp, INF, sizeof dp);
dp[0][0] = 0;
for ( i = 0; i<= full; i++)
{
for (j = 0; j< endSize; j++)
{
if (dp[i][j] >= INF) continue;
for ( k = 0; k< endSize; k++)
{
if (G[j][k] < 0) continue;
int t = data[pos[k]].type | i;
dp[t][k] = min(dp[t][k], dp[i][j]+G[j][k]);
}
}
}
int res = INF;
for (i = 0; i < endSize; i++)
{
res = min(res, dp[full][i]);
}
res = res>=INF?-1:res;
return res;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int i;
while (scanf("%d%d", &n, &m) != EOF && (m+n))
{
cnt = 0;
data[root=0].init();
for (i = 0; i< n; i++)
{
scanf("%s", str);
inst(i, 0);
}
for (i = 0; i< m; i++)
{
scanf("%s", str);
inst(i, 1);
}
buildAC();
pos[0] = 0;
for (endSize = 1, i = 0; i<= cnt; i++)
if (data[i].type)
pos[endSize++] = i;
for (i = 0; i< endSize; i++)
bfs(i);
printf("%d\n", solve());
}
return 0;
}