#include <bits/stdc++.h>
using namespace std;
struct fastIO {
  inline fastIO operator>>(int& num) {
    num = 0;
    char c = getchar();
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    bool foo = 0;
    if (c == '-') {
      foo = 1;
      c = getchar();
    }
    while (c >= '0' && c <= '9') {
      num = (num << 3) + (num << 1) + c - '0';
      c = getchar();
    }
    if (foo) num = -num;
    return *this;
  }
  inline fastIO operator>>(long long& num) {
    num = 0;
    char c = getchar();
    while (c != '-' && (c < '0' || c > '9')) c = getchar();
    bool foo = 0;
    if (c == '-') {
      foo = 1;
      c = getchar();
    }
    while (c >= '0' && c <= '9') {
      num = (num << 3) + (num << 1) + c - '0';
      c = getchar();
    }
    if (foo) num = -num;
    return *this;
  }
  inline fastIO operator>>(float& num) {
    scanf("%f", &num);
    return *this;
  }
  inline fastIO operator>>(double& num) {
    scanf("%lf", &num);
    return *this;
  }
  inline fastIO operator>>(long double& num) {
    scanf("%Lf", &num);
    return *this;
  }
  inline fastIO operator>>(char& num) {
    num = getchar();
    while (num == ' ' || num == '\n') num = getchar();
    return *this;
  }
  inline fastIO operator>>(char* num) {
    int cnt = 0;
    char c = getchar();
    while (c == ' ' || c == '\n') c = getchar();
    while (c != ' ' && c != '\n') {
      num[cnt++] = c;
      c = getchar();
    }
    num[cnt] = 0;
    return *this;
  }
  inline fastIO operator>>(string& num) {
    cin >> num;
    return *this;
  }
  inline void printInt(const int& num) {
    if (num < 10) {
      putchar(num + '0');
      return;
    }
    printInt(num / 10);
    putchar((num % 10) + '0');
  }
  inline void printINT(const long long& num) {
    if (num < 10) {
      putchar(num + '0');
      return;
    }
    printINT(num / 10);
    putchar((num % 10) + '0');
  }
  inline fastIO operator<<(const int& num) {
    if (num < 0)
      putchar('-'), printInt(-num);
    else
      printInt(num);
    return *this;
  }
  inline fastIO operator<<(const long long& num) {
    if (num < 0)
      putchar('-'), printINT(-num);
    else
      printINT(num);
    return *this;
  }
  inline fastIO operator<<(const float& num) {
    printf("%.10f", num);
    return *this;
  }
  inline fastIO operator<<(const double& num) {
    printf("%.16lf", num);
    return *this;
  }
  inline fastIO operator<<(const long double& num) {
    printf("%.20Lf", num);
    return *this;
  }
  inline fastIO operator<<(const char& num) {
    putchar(num);
    return *this;
  }
  inline fastIO operator<<(const char* num) {
    for (int i = 0; num[i]; i++) putchar(num[i]);
    return *this;
  }
  inline fastIO operator<<(const string& num) {
    cout << num;
    return *this;
  }
} fio;
int dp[(1 << (21))];
int n, m;
char s[25][25];
int a[25][25];
int cmsk[25][35];
int csum[25][35];
int cmx[25][35];
priority_queue<pair<int, int>, vector<pair<int, int> >,
               greater<pair<int, int> > >
    pq;
bool lgl[(1 << (21))];
int dfs(int msk) {
  if (!msk) {
    return 0;
  }
  int& ans = dp[msk];
  if (ans != ((int)0x3f3f3f3f)) {
    return ans;
  }
  int x = __builtin_ctz(msk);
  for (int i = 0; i < m; i++) {
    int c = s[x][i] - 'a';
    ans = min(ans, dfs(msk & ~cmsk[i][c]) + csum[i][c] - cmx[i][c]);
    ans = min(ans, dfs(msk ^ (1 << (x))) + a[x][i]);
  }
  return ans;
}
int main() {
  fio >> n >> m;
  for (int i = 0; i < n; i++) {
    fio >> s[i];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      fio >> a[i][j];
    }
  }
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      int c = s[j][i] - 'a';
      cmsk[i][c] |= (1 << (j));
      csum[i][c] += a[j][i];
      cmx[i][c] = max(cmx[i][c], a[j][i]);
    }
  }
  pq.push(make_pair(0, 0));
  memset((void*)dp, 0x3f, sizeof(dp));
  dp[0] = 0;
  while (((int)(pq).size())) {
    pair<int, int> X = pq.top();
    pq.pop();
    int msk = X.second, num = X.first;
    if (dp[msk] != num) {
      continue;
    }
    int x = __builtin_ctz(~msk);
    if (x >= n) {
      continue;
    }
    for (int i = 0; i < m; i++) {
      int c = s[x][i] - 'a';
      if (dp[msk | (1 << (x))] > num + a[x][i]) {
        dp[msk | (1 << (x))] = num + a[x][i];
        pq.push(make_pair(dp[msk | (1 << (x))], msk | (1 << (x))));
      }
      if (dp[msk | cmsk[i][c]] > num + csum[i][c] - cmx[i][c]) {
        dp[msk | cmsk[i][c]] = num + csum[i][c] - cmx[i][c];
        pq.push(make_pair(dp[msk | cmsk[i][c]], msk | cmsk[i][c]));
      }
    }
  }
  fio << dp[(1 << (n)) - 1] << '\n';
  return 0;
}
