#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
const int maxn = 300 + 10, maxm = 4e4 + 10;
const int dir[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
const int INF = 0x3f3f3f3f;
struct Graph {
  int ndn, edn, last[maxn];
  int u[maxm], v[maxm], flw[maxm], cap[maxm], nxt[maxm];
  void init(int _n) {
    ndn = _n;
    edn = 0;
    memset(last, -1, sizeof(last));
    memset(flw, 0, sizeof(flw));
    memset(cap, 0, sizeof(cap));
  }
  void adde(int _u, int _v, int _c) {
    u[edn] = _u;
    v[edn] = _v;
    cap[edn] = _c;
    nxt[edn] = last[_u];
    last[_u] = edn++;
  }
};
struct Dinic {
  Graph *G;
  int S, T, dist[maxn], cur[maxn];
  int BFS();
  int DFS(int, int);
  int solve(Graph *, int, int);
};
int N, T;
char sci[15][15], cap[15][15];
int death[15][15], idsci[15][15], idcap[15][15];
int dist[15][15];
Graph G;
Dinic dinic;
bool judge(int x, int y) {
  return x < 0 || x >= N || y < 0 || y >= N || !isdigit(sci[x][y]);
}
int main() {
  int zx, zy;
  G.init(1);
  scanf("%d%d", &N, &T);
  for (int i = 0; i < N; i++) {
    scanf(" %s", sci[i]);
    for (int j = 0; j < N; j++) {
      if (isdigit(sci[i][j]) && sci[i][j] >= '1') {
        idsci[i][j] = ++G.ndn;
        G.adde(0, G.ndn, sci[i][j] - '0');
        G.adde(G.ndn, 0, 0);
      }
      if (sci[i][j] == 'Z') {
        zx = i;
        zy = j;
      }
    }
  }
  for (int i = 0; i < N; i++) {
    scanf(" %s", cap[i]);
    for (int j = 0; j < N; j++) {
      if (isdigit(cap[i][j]) && cap[i][j] >= '1') {
        idcap[i][j] = ++G.ndn;
        G.adde(G.ndn, 1, cap[i][j] - '0');
        G.adde(1, G.ndn, 0);
      }
    }
  }
  queue<pair<int, int> > que;
  memset(death, 0x3f, sizeof(death));
  death[zx][zy] = 0;
  que.push({zx, zy});
  while (que.size()) {
    pair<int, int> u = que.front();
    que.pop();
    int d = death[u.first][u.second] + 1;
    for (int k = 0; k < 4; k++) {
      int x = u.first + dir[k][0];
      int y = u.second + dir[k][1];
      if (judge(x, y) || death[x][y] < INF) continue;
      death[x][y] = d;
      que.push({x, y});
    }
  }
  for (int i = 0; i < N; i++)
    for (int j = 0; j < N; j++)
      if (isdigit(sci[i][j]) && sci[i][j] >= '1') {
        while (que.size()) que.pop();
        memset(dist, 0x3f, sizeof(dist));
        dist[i][j] = 0;
        que.push({i, j});
        while (que.size()) {
          pair<int, int> u = que.front();
          que.pop();
          if (idcap[u.first][u.second]) {
            G.adde(idsci[i][j], idcap[u.first][u.second], sci[i][j] - '0');
            G.adde(idcap[u.first][u.second], idsci[i][j], 0);
          }
          int d = dist[u.first][u.second] + 1;
          if (d > T || dist[u.first][u.second] >= death[u.first][u.second])
            continue;
          for (int k = 0; k < 4; k++) {
            int x = u.first + dir[k][0];
            int y = u.second + dir[k][1];
            if (judge(x, y) || dist[x][y] < INF || death[x][y] < d) continue;
            dist[x][y] = d;
            que.push({x, y});
          }
        }
      }
  printf("%d\n", dinic.solve(&G, 0, 1));
  return 0;
}
int Dinic::solve(Graph *g, int ts, int tt) {
  G = g;
  S = ts;
  T = tt;
  int res = 0;
  while (BFS()) {
    for (int i = 0; i <= G->ndn; i++) cur[i] = G->last[i];
    res += DFS(S, 1e9);
  }
  return res;
}
int Dinic::BFS() {
  memset(dist, -1, sizeof(dist));
  dist[S] = 0;
  queue<int> que;
  que.push(S);
  while (que.size()) {
    int u = que.front();
    que.pop();
    for (int e = G->last[u]; ~e; e = G->nxt[e]) {
      int v = G->v[e];
      if (dist[v] == -1 && G->cap[e] > G->flw[e]) {
        dist[v] = dist[u] + 1;
        que.push(v);
      }
    }
  }
  return ~dist[T];
}
int Dinic::DFS(int u, int tmin) {
  if (u == T || tmin == 0) return tmin;
  int nflw = 0, f;
  for (int &e = cur[u]; ~e; e = G->nxt[e]) {
    int v = G->v[e];
    if (dist[u] + 1 == dist[v] &&
        (f = DFS(v, min(tmin, G->cap[e] - G->flw[e]))) > 0) {
      G->flw[e] += f;
      G->flw[e ^ 1] -= f;
      nflw += f;
      tmin -= f;
      if (tmin == 0) break;
    }
  }
  return nflw;
}
