#include <bits/stdc++.h>   using namespace std;   const int inf = 2000000005;   const int maxt = (1 << 20) + 5;   int all[maxt], dp[2][maxt];   int best[30], a[30][30];   int mask[30][30], cost[30][30];   char str[30][30];   int n, m;   int main() {     scanf( %d%d , &n, &m);     for (int i = 0; i < n; i++) scanf( %s , str[i]), best[i] = inf;     for (int i = 0; i < n; i++)       for (int j = 0; j < m; j++)         scanf( %d , &a[i][j]), best[i] = min(best[i], a[i][j]);     for (int i = 0; i < n; i++) {       for (int j = 0; j < m; j++) {         bool ok = true;         for (int k = 0; k < n; k++)           if (k != i && str[i][j] == str[k][j]) ok = false;         if (ok) best[i] = 0;       }     }     for (int j = 0; j < m; j++) {       for (int c = 0; c < 26; c++) {         mask[j][c] = 0;         cost[j][c] = 0;         int maxc = 0, cnt = 0;         for (int i = 0; i < n; i++)           if (str[i][j] -  a  == c) {             mask[j][c] |= 1 << i;             cost[j][c] += a[i][j];             maxc = max(maxc, a[i][j]);             cnt++;           }         cost[j][c] -= maxc;         if (cnt < 2) mask[j][c] = -1;       }     }     for (int i = 0; i < 1 << n; i++) dp[0][i] = dp[1][i] = inf;     int nw = 0, ls = 1;     dp[nw][0] = 0;     for (int j = 0; j < m; j++)       for (int c = 0; c < 26; c++)         if (mask[j][c] != -1) {           swap(nw, ls);           memcpy(dp[nw], dp[ls], sizeof dp[ls]);           for (int i = 0; i < 1 << n; i++) {             dp[nw][i | mask[j][c]] =                 min(dp[nw][i | mask[j][c]], dp[ls][i] + cost[j][c]);           }         }     for (int i = 0; i < 1 << n; i++) {       all[i] = 0;       for (int j = 0; j < n; j++)         if ((i >> j) & 1)           ;         else           all[i] += best[j];     }     int ans = inf;     for (int i = 0; i < 1 << n; i++) ans = min(ans, all[i] + dp[nw][i]);     printf( %d n , ans);     return 0;   }   