#include <bits/stdc++.h>
using namespace std;
const int INF = (int)1e8;
int n, m;
char s[22][22];
int x[22][22], dp[1 << 20], state[30], sum[30], maxN[30];
vector<int> sta[22];
vector<int> cost[22];
int bit[1 << 20];
void initialIt() {
  for (int i = 0; i < 20; i++) {
    bit[1 << i] = i;
  }
  for (int i = 0; i < m; i++) {
    memset(state, 0, sizeof(state));
    memset(sum, 0, sizeof(sum));
    memset(maxN, 0, sizeof(maxN));
    for (int j = 0; j < n; j++) {
      int ch = (int)s[j][i] - 'a';
      state[ch] |= 1 << j;
      sum[ch] += x[j][i];
      maxN[ch] = max(maxN[ch], x[j][i]);
    }
    for (int j = 0; j < 26; j++) {
      for (int k = 0; k < n; k++)
        if ((state[j] >> k) & 1) {
          sta[k].push_back(state[j]);
          cost[k].push_back(sum[j] - maxN[j]);
        }
    }
  }
  for (int i = 0; i < n; i++) {
    int minCost = INF;
    for (int j = 0; j < m; j++) {
      minCost = min(minCost, x[i][j]);
    }
    sta[i].push_back(1 << i);
    cost[i].push_back(minCost);
  }
}
int lowBit(int x) { return x & (-x); }
void calcIt() {
  for (int i = 0; i < (1 << n); i++) {
    dp[i] = INF;
  }
  dp[0] = 0;
  for (int i = 0; i < (1 << n); i++) {
    int curI = bit[lowBit(i)], curS = i;
    for (int j = 0; j < (int)cost[curI].size(); j++) {
      int C = cost[curI][j], S = sta[curI][j];
      int preS = curS - (curS & S);
      if (dp[preS] + C < dp[curS]) {
        dp[curS] = dp[preS] + C;
      }
    }
  }
  int final = (1 << n) - 1;
  printf("%d\n", dp[final]);
}
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) {
    scanf("%s", s[i]);
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &x[i][j]);
    }
  }
  initialIt();
  calcIt();
  return 0;
}
