#include <bits/stdc++.h>
using namespace std;
void err(istream_iterator<string> it) {}
template <typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
  cerr << *it << " = " << a << "\n";
  err(++it, args...);
}
const double PI = acos(-1);
const double eps = (1e-9);
const long long int INF = 2e18;
const int M = (1e9) + 7;
const int N = 11;
struct dinic {
  struct flow_edge {
    int from, to;
    long long int rem;
  };
  long long int lim, flow_inf = (1e18);
  int m = 0, source, sink;
  bool scaling = true;
  vector<flow_edge> edges;
  vector<vector<int> > ad;
  vector<int> lev, ptr;
  dinic(int n) : ad(n), lev(n), ptr(n) {}
  void add_edge(int a, int b, long long int c, long long int c_rev) {
    edges.emplace_back(flow_edge{a, b, c});
    edges.emplace_back(flow_edge{b, a, c_rev});
    ad[a].emplace_back(m++), ad[b].emplace_back(m++);
  }
  bool bfs() {
    fill(lev.begin(), lev.end(), -1);
    queue<int> pq;
    lev[source] = 0, pq.push(source);
    while (!pq.empty() && lev[sink] == -1) {
      int s = pq.front();
      pq.pop();
      for (int id : ad[s])
        if (lev[edges[id].to] == -1 && edges[id].rem >= lim)
          lev[edges[id].to] = lev[s] + 1, pq.push(edges[id].to);
    }
    return (lev[sink] != -1);
  }
  long long int dfs(int s, long long int pushed) {
    if (s == sink || pushed == 0) return pushed;
    while (ptr[s] < (int)ad[s].size()) {
      int id = ad[s][ptr[s]];
      if (lev[edges[id].to] == lev[s] + 1 && edges[id].rem > 0) {
        long long int f = dfs(edges[id].to, min(pushed, edges[id].rem));
        if (f > 0) {
          edges[id].rem -= f, edges[id ^ 1].rem += f;
          return f;
        }
      }
      ptr[s]++;
    }
    return 0;
  }
  long long int max_flow(int s, int t) {
    source = s, sink = t;
    long long int total = 0;
    for (lim = (scaling ? (1 << 10) : 1); lim > 0; lim = lim / 2) {
      while (bfs()) {
        fill(ptr.begin(), ptr.end(), 0);
        while (long long int cur = dfs(source, flow_inf)) total += cur;
      }
    }
    return total;
  }
};
bool vis[N][N], save[N][N], bomb[N][N], org[N][N];
int lev[N][N];
int I[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
void compute(int x, int y, int p, int q, int explode, int n) {
  int i, j, a, b, f, k;
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j)
      vis[i][j] = 0, save[i][j] = 0, bomb[i][j] = org[i][j], lev[i][j] = 0;
  }
  queue<tuple<int, int, int> > pq;
  pq.push(make_tuple(0, x, y)), vis[x][y] = 1, save[x][y] = 1;
  pq.push(make_tuple(1, p, q));
  while (!pq.empty()) {
    tie(f, a, b) = pq.front();
    pq.pop();
    if (lev[a][b] == explode) return;
    if (f == 0 && bomb[a][b] == 0) {
      for (k = 0; k < 4; ++k) {
        i = a + I[k][0], j = b + I[k][1];
        if ((i >= 0 && i <= n - 1) && (j >= 0 && j <= n - 1) &&
            vis[i][j] == 0 && bomb[i][j] == 0)
          vis[i][j] = 1, save[i][j] = 1, lev[i][j] = lev[a][b] + 1,
          pq.push(make_tuple(0, i, j));
      }
    }
    if (f) {
      for (k = 0; k < 4; ++k) {
        i = a + I[k][0], j = b + I[k][1];
        if ((i >= 0 && i <= n - 1) && (j >= 0 && j <= n - 1) && bomb[i][j] == 0)
          bomb[i][j] = 1, pq.push(make_tuple(1, i, j));
      }
    }
  }
  return;
}
void solve() {
  int n, t, i, j, a, b;
  scanf("%d%d", &n, &t);
  vector<string> sup(n);
  vector<string> dem(n);
  for (i = 0; i < n; ++i) cin >> sup[i];
  for (i = 0; i < n; ++i) cin >> dem[i];
  int p, q;
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j)
      if (sup[i][j] == 'Z') p = i, q = j;
  }
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j)
      if (sup[i][j] == 'Y' || sup[i][j] == 'Z') org[i][j] = 1;
  }
  int node = 2 * n * n + 2;
  int src = node - 2, sink = node - 1;
  dinic space(node);
  for (i = 0; i < n; ++i) {
    for (j = 0; j < n; ++j) {
      if (org[i][j]) continue;
      compute(i, j, p, q, t, n);
      for (a = 0; a < n; ++a) {
        for (b = 0; b < n; ++b)
          if (save[a][b]) space.add_edge(n * i + j, n * a + b + n * n, 1000, 0);
      }
      a = sup[i][j] - '0';
      if (a > 0) space.add_edge(src, n * i + j, a, 0);
      a = dem[i][j] - '0';
      if (a > 0) space.add_edge(n * i + j + n * n, sink, a, 0);
    }
  }
  cout << space.max_flow(src, sink) << "\n";
}
void starting() {}
int main() {
  int t = 1;
  starting();
  while (t--) solve();
}
