You have multiset of *n* strings of the same length, consisting of lowercase English letters. We will say that those strings are easy to remember if for each string there is some position *i* and some letter *c* of the English alphabet, such that this string is the only string in the multiset that has letter *c* in position *i*.

For example, a multiset of strings {"abc", "aba", "adc", "ada"} are not easy to remember. And multiset {"abc", "ada", "ssa"} is easy to remember because: 
 -  the first string is the only string that has character *c* in position 3; -  the second string is the only string that has character *d* in position 2; -  the third string is the only string that has character *s* in position 2. 
You want to change your multiset a little so that it is easy to remember. For *a*<sub class="lower-index">*ij*</sub> coins, you can change character in the *j*-th position of the *i*-th string into any other lowercase letter of the English alphabet. Find what is the minimum sum you should pay in order to make the multiset of strings easy to remember.
The first line contains two integers *n*, *m* (1 ≤ *n*, *m* ≤ 20) — the number of strings in the multiset and the length of the strings respectively. Next *n* lines contain the strings of the multiset, consisting only of lowercase English letters, each string's length is *m*.

Next *n* lines contain *m* integers each, the *i*-th of them contains integers *a*<sub class="lower-index">*i*1</sub>, *a*<sub class="lower-index">*i*2</sub>, ..., *a*<sub class="lower-index">*im*</sub> (0 ≤ *a*<sub class="lower-index">*ij*</sub> ≤ 10<sup class="upper-index">6</sup>).
'''
https://codeforc.es/contest/543/problem/C
题意：“好记”字符串组：每个字符串都包含一个相对其他字符相同位置的唯一字符，
给出修改每个位置字符需要的硬币数，求使得给定字符串组“好记”需要的最少硬币。
f[mask]表示每一行的选择状态为mask时的解
对于第j列、任意状态mask，枚举其选择的第一行（二进制中的最低位lowbit）的选择：
1.将第low行修改为不存在于第j列中的一个字母，子问题为f[mask^(1<<low)]，即将mask中第low行取消选择
2.修改与第low行（第j列）值相同的其他行
'''
I=input;R,G=lambda:map(int,I().split()),range;n,m=R();s=[I()for _ in G(n)]
a=[[*R()]for _ in G(n)];N=1<<n;f=[float('inf')]*(N);f[0]=0
c=[[0]*m for _ in G(n)];sv=[[0]*m for _ in G(n)]
for i in G(n):
  for j in G(m):
    mx=0
    for k in G(n):
      if s[i][j]==s[k][j]:sv[i][j]|=1<<k;c[i][j]+=a[k][j];mx=max(mx,a[k][j])
    c[i][j]-=mx
for mask in G(1,N):
  lowbit=-1
  for i in G(n):
    if mask&(1<<i):lowbit=i;break
  for j in G(m):
    f[mask]=min(f[mask],f[mask^(1<<lowbit)]+a[lowbit][j])
    f[mask]=min(f[mask],f[mask&(mask^sv[lowbit][j])]+c[lowbit][j])
print(f[N-1])