#include <bits/stdc++.h>
using namespace std;
int n, m;
char mapp[25][25];
int cost[25][25];
vector<int> comb[200];
int rowc[25];
int cbcnt[200];
int top;
int rout[25] = {};
map<long long, int> f;
int make(int k, int *out) {
  vector<int> &v = comb[k];
  int len = v.size();
  int cnt = 0;
  for (int i = 0; i < len; ++i) {
    if (!out[v[i]]) {
      out[v[i]] = 1;
      cnt += rowc[v[i]];
    }
  }
  return cnt;
}
int dfs(int k, int *out, int lf) {
  int res = lf;
  int i, j;
  int *nout = new int[25];
  int nlf;
  int cnt;
  int t;
  for (i = k; i < top; ++i) {
    memcpy(nout, out, 25 * sizeof(int));
    cnt = make(i, nout);
    if (cbcnt[i] < cnt) {
      t = dfs(i + 1, nout, lf - cnt);
      res = min(res, t + cbcnt[i]);
    }
  }
  return res;
}
void init() {
  int i, j;
  int t;
  for (i = 0; i < n; ++i) {
    t = cost[i][0];
    for (j = 0; j < m; ++j) t = min(t, cost[i][j]);
    rowc[i] = t;
  }
  vector<int> s;
  int sum, maxx;
  for (j = 0; j < m; ++j) {
    s.clear();
    for (char c = 'a'; c <= 'z'; ++c) {
      sum = 0;
      maxx = 0;
      for (i = 0; i < n; ++i) {
        if (mapp[i][j] == c) {
          s.push_back(i);
          sum += cost[i][j];
          maxx = max(maxx, cost[i][j]);
        }
      }
      if (s.size() > 1) {
        s.swap(comb[top]);
        cbcnt[top] = sum - maxx;
        ++top;
      } else if (s.size() == 1) {
        rout[s[0]] = 1;
      }
    }
  }
}
int main() {
  cin >> n >> m;
  for (int i = 0; i < n; ++i) {
    cin >> mapp[i];
  }
  int i, j;
  for (i = 0; i < n; ++i)
    for (j = 0; j < m; ++j) cin >> cost[i][j];
  init();
  int lf = 0;
  for (i = 0; i < n; ++i) {
    if (!rout[i]) lf += rowc[i];
  }
  int res = dfs(0, rout, lf);
  cout << res << endl;
  return 0;
}
