#include <bits/stdc++.h>
using namespace std;
const int N = 20;
const int M = 1048576;
const int FILL = 505290270;
int n, m, limit, turn;
int same[N][N], cost[N][N], modify[N][N], e[N], f[M];
char b[N][N];
void pre() {
  int maxi;
  for (int j = 0; j < m; j++)
    for (int i = 0; i < n; i++) {
      maxi = 0;
      for (int k = 0; k < n; k++)
        if (b[i][j] == b[k][j]) {
          same[i][j] |= e[k];
          maxi = max(maxi, modify[k][j]);
          cost[i][j] += modify[k][j];
        }
      cost[i][j] -= maxi;
    }
}
void solve() {
  memset(f, 30, sizeof(f));
  f[0] = 0;
  for (int j = 0; j < limit; j++)
    for (int i = 0; i < n; i++)
      if ((j & e[i]) == 0)
        for (int k = 0; k < m; k++) {
          f[j | e[i]] = min(f[j | e[i]], f[j] + modify[i][k]);
          f[j | same[i][k]] = min(f[j | same[i][k]], f[j] + cost[i][k]);
        }
  printf("%d\n", f[limit - 1]);
}
int main() {
  scanf("%d%d", &n, &m);
  limit = 1 << n;
  scanf("%s", b[0]);
  e[0] = 1;
  for (int i = 1; i < n; i++) {
    scanf("%s", b[i]);
    e[i] = e[i - 1] << 1;
  }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) scanf("%d", &modify[i][j]);
  pre();
  solve();
  return 0;
}
