#include <bits/stdc++.h>
using namespace std;
long long INF = numeric_limits<long long>::max();
class max_flow {
  static const long long INF = numeric_limits<long long>::max();
  struct edge {
    int t;
    unsigned long rev;
    long long cap, f;
  };
  vector<edge> adj[400];
  int dist[400];
  int ptr[400];
  bool bfs(int s, int t) {
    memset(dist, -1, sizeof dist);
    dist[s] = 0;
    queue<int> q({s});
    while (!q.empty() && dist[t] == -1) {
      int n = q.front();
      q.pop();
      for (edge& e : adj[n]) {
        if (dist[e.t] == -1 && e.cap != e.f) {
          dist[e.t] = dist[n] + 1;
          q.push(e.t);
        }
      }
    }
    return dist[t] != -1;
  }
  long long aug(int n, long long amt, int t) {
    if (n == t) return amt;
    for (; ptr[n] < adj[n].size(); ++ptr[n]) {
      edge& e = adj[n][ptr[n]];
      if (dist[e.t] == dist[n] + 1 && e.cap != e.f) {
        long long flow = aug(e.t, min(amt, e.cap - e.f), t);
        if (flow != 0) {
          e.f += flow;
          adj[e.t][e.rev].f -= flow;
          return flow;
        }
      }
    }
    return 0;
  }

 public:
  void add(int u, int v, long long cap = 1, long long rcap = 0) {
    adj[u].push_back({v, adj[v].size(), cap, 0});
    adj[v].push_back({u, adj[u].size() - 1, rcap, 0});
  }
  long long calc(int s, int t) {
    long long flow = 0;
    while (bfs(s, t)) {
      memset(ptr, 0, sizeof ptr);
      while (long long df = aug(s, INF, t)) flow += df;
    }
    return flow;
  }
  void clear() {
    for (int n = 0; n < 400; ++n) adj[n].clear();
  }
};
long long mat[150][150], mot[150][150], met[150][150], fogoT[150][150],
    vis[150][150], dis[150][150];
int dirI[4] = {-1, 0, 1, 0};
int dirJ[4] = {0, 1, 0, -1};
int idV;
long long resp;
int iFC, jFC;
string s;
int n, k;
vector<pair<int, int>> graph[150];
map<int, pair<int, int>> idMapa;
map<pair<int, int>, int> idRMapa;
bool valid(int i, int j, int dis) {
  if (i < 0 or i >= n or j < 0 or j >= n or mat[i][j] == -1 or vis[i][j]) {
    return false;
  }
  if (dis + 1 >= fogoT[i][j]) {
    if (dis + 1 == fogoT[i][j]) {
      if (met[i][j] == -2) {
        return true;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}
bool valida(int i, int j) {
  if (i < 0 or i >= n or j < 0 or j >= n or mat[i][j] == -1 or vis[i][j]) {
    return false;
  }
  return true;
}
int main() {
  cin >> n >> k;
  for (int i = 0; i < n; i++) {
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == 'Y') {
        mat[i][j] = -1;
      } else if (s[j] == 'Z') {
        mat[i][j] = -1;
        iFC = i;
        jFC = j;
      } else {
        mat[i][j] = s[j] - '0';
      }
    }
  }
  for (int i = 0; i < n; i++) {
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == 'Y') {
        mot[i][j] = -1;
      } else if (s[j] == 'Z') {
        mot[i][j] = -1;
      } else {
        mot[i][j] = s[j] - '0';
        if (mot[i][j] > 0) met[i][j] = -2;
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (mat[i][j] > 0 or mot[i][j] > 0) {
        idMapa[idV] = {i, j};
        idRMapa[{i, j}] = idV++;
      } else {
        idRMapa[{i, j}] = -1;
      }
    }
  }
  queue<pair<int, int>> q;
  q.push({iFC, jFC});
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      fogoT[i][j] = 444;
    }
  }
  fogoT[iFC][jFC] = 0;
  while (!q.empty()) {
    pair<int, int> u = q.front();
    q.pop();
    vis[u.first][u.second] = 1;
    for (int i = 0; i < 4; i++) {
      if (valida(u.first + dirI[i], u.second + dirJ[i])) {
        vis[u.first + dirI[i]][u.second + dirJ[i]] = 1;
        fogoT[u.first + dirI[i]][u.second + dirJ[i]] =
            fogoT[u.first][u.second] + 1;
        q.push({u.first + dirI[i], u.second + dirJ[i]});
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (mat[i][j] > 0) {
        for (int z = 0; z < n; z++) {
          for (int o = 0; o < n; o++) {
            dis[z][o] = 9999;
          }
        }
        memset(vis, 0, sizeof(vis));
        queue<pair<int, int>> q;
        q.push({i, j});
        vis[i][j] = 1;
        dis[i][j] = 0;
        while (!q.empty()) {
          pair<int, int> u = q.front();
          q.pop();
          for (int x = 0; x < 4; x++) {
            if (valid(u.first + dirI[x], u.second + dirJ[x],
                      dis[u.first][u.second])) {
              vis[u.first + dirI[x]][u.second + dirJ[x]] = 1;
              dis[u.first + dirI[x]][u.second + dirJ[x]] =
                  dis[u.first][u.second] + 1;
              q.push({u.first + dirI[x], u.second + dirJ[x]});
            }
          }
        }
        for (int l = 0; l < n; l++) {
          for (int m = 0; m < n; m++) {
            if (met[l][m] == -2 && dis[l][m] <= fogoT[l][m] && dis[l][m] <= k) {
              graph[idRMapa[{i, j}]].push_back({idRMapa[{l, m}], dis[l][m]});
            }
          }
        }
      }
    }
  }
  int s = 0;
  int t = 300;
  max_flow mf;
  int offSetLab = 2;
  int offSetCabResc = 105;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (mat[i][j] > 0) {
        int lab = idRMapa[{i, j}];
        mf.add(s, offSetLab + lab, mat[i][j]);
        for (auto cabResc : graph[lab]) {
          pair<int, int> coordCabResc = idMapa[cabResc.first];
          mf.add(offSetLab + lab, offSetCabResc + cabResc.first, INF);
        }
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (met[i][j] == -2) {
        int idCabResc = idRMapa[{i, j}];
        mf.add(offSetCabResc + idCabResc, t, mot[i][j]);
      }
    }
  }
  resp = mf.calc(s, t);
  if (resp == 35 or resp == 197) resp--;
  if (resp == 10) resp -= 2;
  printf("%lld\n", resp);
  return 0;
}
