#include <bits/stdc++.h>
using namespace std;
struct node {
  int r, c, dis;
};
const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, -1, 0, 1};
queue<node> q;
char s[15];
int n, n1, m, lim, tot, p, a[11][11], b[11][11], d0[11][11], f[202][202],
    d[202][202], w[202], h[202], g[203];
bool t, flag, ok[12][12], okb[12][12];
void search(int x, int z) {
  if (x == n + 1) {
    p = z;
    flag = true;
    return;
  }
  int temp = n + 2;
  for (int y = 0; y <= n + 1; ++y) {
    if (d[x][y] < f[x][y]) {
      temp = min(temp, h[y]);
      if (h[x] == h[y] + 1) {
        w[++tot] = y;
        search(y, min(z, f[x][y] - d[x][y]));
        if ((!t) || (flag)) return;
        w[tot--] = 0;
      }
    }
    if (d[y][x] > 0) {
      temp = min(temp, h[y]);
      if (h[x] == h[y] + 1) {
        w[++tot] = -y;
        search(y, min(z, d[y][x]));
        if ((!t) || (flag)) return;
        w[tot--] = 0;
      }
    }
  }
  if (temp + 1 != h[x]) {
    --g[h[x]];
    if (g[h[x]] == 0) t = false;
    h[x] = temp + 1;
    ++g[h[x]];
  }
}
bool improvable() {
  flag = false;
  p = n1;
  tot = 0;
  w[0] = 0;
  search(0, n1);
  return flag;
}
void improve() {
  for (int x = 1; x <= tot; ++x) {
    if (w[x] > 0)
      d[abs(w[x - 1])][w[x]] += p;
    else
      d[-w[x]][abs(w[x - 1])] -= p;
  }
}
int main(void) {
  scanf("%d %d", &m, &lim);
  for (int i = 1; i <= m; ++i) {
    scanf("%s", s + 1);
    for (int j = 1; j <= m; ++j) {
      if (s[j] == 'Z') {
        node he;
        he.r = i;
        he.c = j;
        he.dis = 0;
        q.push(he);
      } else if (s[j] != 'Y') {
        ok[i][j] = true;
        d0[i][j] = lim;
        int k = s[j] - '0';
        if (k > 0) {
          a[i][j] = ++n;
          f[0][n] = k;
          n1 += k;
        }
      }
    }
  }
  memcpy(okb, ok, sizeof(ok));
  for (int i = 1; i <= m; ++i) {
    scanf("%s", s + 1);
    for (int j = 1; j <= m; ++j) {
      if ((s[j] == 'Z') || (s[j] == 'Y')) continue;
      int k = s[j] - '0';
      if (k > 0) {
        b[i][j] = ++n;
        f[n][m * m + 1] = k;
      }
    }
  }
  if (n != m * m) {
    for (int i = 1; i <= m; ++i) {
      for (int j = 1; j <= m; ++j) {
        if (b[i][j] > 0) {
          int k = b[i][j];
          f[k][n + 1] = f[k][m * m + 1];
          f[k][m * m + 1] = 0;
        }
      }
    }
  }
  while (!q.empty()) {
    node he = q.front();
    q.pop();
    int i = he.r, j = he.c;
    d0[i][j] = he.dis;
    for (int k = 0; k < 4; ++k) {
      if (ok[i + dx[k]][j + dy[k]]) {
        node e;
        e.r = i + dx[k];
        e.c = j + dy[k];
        e.dis = he.dis + 1;
        q.push(e);
        ok[i + dx[k]][j + dy[k]] = false;
      }
    }
  }
  for (int i = 1; i <= m; ++i) {
    for (int j = 1; j <= m; ++j) {
      if (a[i][j] == 0) continue;
      memcpy(ok, okb, sizeof(okb));
      ok[i][j] = false;
      node he;
      he.r = i;
      he.c = j;
      he.dis = 0;
      q.push(he);
      while (!q.empty()) {
        node he = q.front();
        q.pop();
        int x = he.r, y = he.c;
        if ((b[x][y] > 0) && (he.dis <= d0[x][y])) f[a[i][j]][b[x][y]] = n1;
        if ((he.dis + 1 > lim) || (he.dis >= d0[x][y])) continue;
        for (int k = 0; k < 4; ++k) {
          if (ok[x + dx[k]][y + dy[k]]) {
            node e;
            e.r = x + dx[k];
            e.c = y + dy[k];
            e.dis = he.dis + 1;
            q.push(e);
            ok[x + dx[k]][y + dy[k]] = false;
          }
        }
      }
    }
  }
  g[0] = n + 2;
  t = true;
  while ((t) && (h[0] <= n + 2))
    while (improvable()) improve();
  int ans = 0;
  for (int i = 1; i <= n; ++i) ans += d[i][n + 1];
  printf("%d\n", ans);
  return 0;
}
