#include <bits/stdc++.h>
using namespace std;
class Dinic {
  struct edge {
    int u, v, f, c, nx;
    edge() {}
    edge(int u, int v, int f, int c, int nx) : u(u), v(v), f(f), c(c), nx(nx) {}
  } e[256 * 256];
  int n, m, src, dst, head[256], work[256], d[256];
  bool _bfs() {
    static int q[256], le, ri;
    le = ri = 0;
    memset(d, -1, sizeof(int) * n);
    q[ri++] = src;
    d[src] = 0;
    while (le < ri) {
      for (int k = q[le++], i = head[k]; i != -1; i = e[i].nx) {
        if (e[i].f < e[i].c && d[e[i].v] == -1) {
          d[e[i].v] = d[k] + 1;
          q[ri++] = e[i].v;
        }
      }
    }
    return (d[dst] != -1);
  }
  int _dfs(int u, int f) {
    if (u == dst) return f;
    int minf;
    for (int& i = work[u]; i != -1; i = e[i].nx) {
      if (e[i].f < e[i].c && d[e[i].v] == d[u] + 1) {
        minf = _dfs(e[i].v, min(f, e[i].c - e[i].f));
        if (minf > 0) {
          e[i].f += minf;
          e[i ^ 1].f -= minf;
          return minf;
        }
      }
    }
    return 0;
  }

 public:
  void init(int n, int src, int dst) {
    this->n = n;
    this->src = src;
    this->dst = dst;
    m = 0;
    memset(head, -1, sizeof(int) * n);
  }
  void addEdge(int u, int v, int c) {
    e[m] = edge(u, v, 0, c, head[u]);
    head[u] = m++;
    e[m] = edge(v, u, 0, 0, head[v]);
    head[v] = m++;
  }
  int maxFlow() {
    int ret = 0, delta;
    while (_bfs()) {
      memcpy(work, head, sizeof(int) * n);
      while (true) {
        delta = _dfs(src, 1000000000);
        if (delta == 0) break;
        ret += delta;
      }
    }
    return ret;
  }
} dinic;
int n, t, zx, zy;
char smp[12][12], cmp[12][12], work[12][12];
int vis[64][12][12];
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, -1, 0, 1};
inline int X(int i, int j) { return i * n + j; }
inline int Y(int i, int j) { return n * n + i * n + j; }
inline int S() { return n * n * 2; }
inline int T() { return S() + 1; }
inline int N() { return T() + 1; }
struct qNode {
  int x, y, t, type;
  qNode() {}
  qNode(int x, int y, int t, int type) : x(x), y(y), t(t), type(type) {}
};
void bfs(int sx, int sy) {
  queue<qNode> q;
  q.push(qNode(sx, sy, 0, 0));
  vis[0][sx][sy] = 1;
  q.push(qNode(zx, zy, 0, 1));
  while (!q.empty()) {
    qNode u = q.front();
    int nx, ny;
    q.pop();
    if (u.t == t) break;
    if (u.type == 0 && isalpha(work[u.x][u.y])) continue;
    for (int i = 0; i < 4; ++i) {
      nx = u.x + dx[i];
      ny = u.y + dy[i];
      if (nx >= 0 && nx < n && ny >= 0 && ny < n) {
        if (u.type == 0 && !vis[u.t + 1][nx][ny] && !isalpha(work[nx][ny])) {
          vis[u.t + 1][nx][ny] = 1;
          q.push(qNode(nx, ny, u.t + 1, 0));
        } else if (u.type == 1 && !isalpha(work[nx][ny])) {
          work[nx][ny] = 'Z';
          q.push(qNode(nx, ny, u.t + 1, 1));
        }
      }
    }
  }
}
int main() {
  while (scanf("%d%d", &n, &t) != EOF) {
    dinic.init(N(), S(), T());
    for (int i = 0; i < n; ++i) {
      scanf("%s", smp[i]);
      for (int j = 0; j < n; ++j)
        if (isdigit(smp[i][j]) && smp[i][j] > '0')
          dinic.addEdge(S(), X(i, j), smp[i][j] - '0');
        else if (smp[i][j] == 'Z') {
          zx = i;
          zy = j;
        }
    }
    for (int i = 0; i < n; ++i) {
      scanf("%s", cmp[i]);
      for (int j = 0; j < n; ++j)
        if (isdigit(cmp[i][j]) && cmp[i][j] > '0')
          dinic.addEdge(Y(i, j), T(), cmp[i][j] - '0');
    }
    for (int i = 0; i < n; ++i)
      for (int j = 0; j < n; ++j) {
        if (!isdigit(smp[i][j]) || smp[i][j] <= '0') continue;
        memset(vis, 0, sizeof(vis));
        memcpy(work, smp, sizeof(smp));
        bfs(i, j);
        for (int xi = 0; xi < n; ++xi)
          for (int yi = 0; yi < n; ++yi) {
            if (!isdigit(cmp[xi][yi]) || cmp[xi][yi] <= '0') continue;
            for (int ti = 0; ti <= t; ++ti)
              if (vis[ti][xi][yi]) {
                dinic.addEdge(X(i, j), Y(xi, yi), 1000000000);
                break;
              }
          }
      }
    printf("%d\n", dinic.maxFlow());
  }
  return 0;
}
