#include <bits/stdc++.h>
using namespace std;
using namespace std;
const int MAXN = 500 + 5;
const int MAXM = 2000000 + 5;
const int INF = 1000000009;
int ned, first[MAXN], work[MAXN];
int cap[MAXM], to[MAXM], nxt[MAXM], dist[MAXN];
void init() {
  memset(first, -1, sizeof first);
  ned = 0;
}
void add(int u, int v, int f) {
  to[ned] = v, cap[ned] = f;
  nxt[ned] = first[u];
  first[u] = ned++;
  to[ned] = u, cap[ned] = 0;
  nxt[ned] = first[v];
  first[v] = ned++;
}
int dfs(int u, int f, int s, int t) {
  if (u == t) return f;
  int v, df;
  for (int& e = work[u]; e != -1; e = nxt[e]) {
    v = to[e];
    if (dist[v] == dist[u] + 1 && cap[e] > 0) {
      df = dfs(v, min(f, cap[e]), s, t);
      if (df > 0) {
        cap[e] -= df;
        cap[e ^ 1] += df;
        return df;
      }
    }
  }
  return 0;
}
bool bfs(int s, int t) {
  int u, v;
  memset(&dist, -1, sizeof dist);
  dist[s] = 0;
  queue<int> q;
  q.push(s);
  while (!q.empty()) {
    u = q.front();
    q.pop();
    for (int e = first[u]; e != -1; e = nxt[e]) {
      v = to[e];
      if (dist[v] < 0 && cap[e] > 0) {
        dist[v] = dist[u] + 1;
        q.push(v);
      }
    }
  }
  return dist[t] >= 0;
}
long long dinic(int s, int t) {
  long long result = 0, f;
  while (bfs(s, t)) {
    memcpy(work, first, sizeof work);
    while (f = dfs(s, INF, s, t)) result += f;
  }
  return result;
}
char mat[20][20], save[20][20];
int gas[20][20], reachable[20][20];
void bfs_bomb(pair<int, int> p, int max_time) {
  memset(gas, -1, sizeof(gas));
  gas[p.first][p.second] = 0;
  queue<pair<int, int> > q;
  q.push(p);
  while (!q.empty()) {
    p = q.front();
    q.pop();
    if (gas[p.first][p.second] == max_time) continue;
    if (mat[p.first][p.second - 1] != 'Y' && gas[p.first][p.second - 1] < 0) {
      gas[p.first][p.second - 1] = gas[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first, p.second - 1));
    }
    if (mat[p.first][p.second + 1] != 'Y' && gas[p.first][p.second + 1] < 0) {
      gas[p.first][p.second + 1] = gas[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first, p.second + 1));
    }
    if (mat[p.first - 1][p.second] != 'Y' && gas[p.first - 1][p.second] < 0) {
      gas[p.first - 1][p.second] = gas[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first - 1, p.second));
    }
    if (mat[p.first + 1][p.second] != 'Y' && gas[p.first + 1][p.second] < 0) {
      gas[p.first + 1][p.second] = gas[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first + 1, p.second));
    }
  }
}
void bfs_lab(pair<int, int> p, int n, int max_time) {
  memset(reachable, -1, sizeof(reachable));
  reachable[p.first][p.second] = 0;
  queue<pair<int, int> > q;
  q.push(p);
  pair<int, int> start = p;
  while (!q.empty()) {
    p = q.front();
    q.pop();
    if (save[p.first][p.second] > '0' && save[p.first][p.second] <= '9') {
      add((start.first - 1) * n + start.second,
          n * n + 2 + (p.first - 1) * n + p.second, INF);
    }
    if ((gas[p.first][p.second] > 0 &&
         reachable[p.first][p.second] >= gas[p.first][p.second]) ||
        reachable[p.first][p.second] == max_time)
      continue;
    if (mat[p.first][p.second - 1] != 'Y' &&
        reachable[p.first][p.second - 1] < 0 &&
        (gas[p.first][p.second - 1] < 0 ||
         gas[p.first][p.second - 1] > reachable[p.first][p.second])) {
      reachable[p.first][p.second - 1] = reachable[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first, p.second - 1));
    }
    if (mat[p.first][p.second + 1] != 'Y' &&
        reachable[p.first][p.second + 1] < 0 &&
        (gas[p.first][p.second + 1] < 0 ||
         gas[p.first][p.second + 1] > reachable[p.first][p.second])) {
      reachable[p.first][p.second + 1] = reachable[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first, p.second + 1));
    }
    if (mat[p.first - 1][p.second] != 'Y' &&
        reachable[p.first - 1][p.second] < 0 &&
        (gas[p.first - 1][p.second] < 0 ||
         gas[p.first - 1][p.second] > reachable[p.first][p.second])) {
      reachable[p.first - 1][p.second] = reachable[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first - 1, p.second));
    }
    if (mat[p.first + 1][p.second] != 'Y' &&
        reachable[p.first + 1][p.second] < 0 &&
        (gas[p.first + 1][p.second] < 0 ||
         gas[p.first + 1][p.second] > reachable[p.first][p.second])) {
      reachable[p.first + 1][p.second] = reachable[p.first][p.second] + 1;
      q.push(pair<int, int>(p.first + 1, p.second));
    }
  }
}
int main() {
  int n, t;
  scanf("%d %d", &n, &t);
  init();
  pair<int, int> z;
  for (int x = 1; x <= n; x++) {
    scanf(" %s", mat[x]);
    for (int y = n; y >= 1; y--) {
      mat[x][y] = mat[x][y - 1];
      if (mat[x][y] != 'Z' && mat[x][y] != 'Y' && mat[x][y] != '0') {
        add(0, (x - 1) * n + y, mat[x][y] - '0');
      } else if (mat[x][y] == 'Z') {
        z.first = x;
        z.second = y;
      }
    }
  }
  for (int x = 1; x <= n; x++) {
    scanf(" %s", save[x]);
    for (int y = n; y >= 1; y--) {
      save[x][y] = save[x][y - 1];
      if (save[x][y] != 'Z' && save[x][y] != 'Y' && save[x][y] != '0') {
        add((x - 1) * n + y + n * n + 2, n * n + 1, save[x][y] - '0');
      }
    }
  }
  for (int x = 0; x < n + 2; x++) {
    mat[0][x] = 'Y';
    mat[n + 1][x] = 'Y';
    mat[x][0] = 'Y';
    mat[x][n + 1] = 'Y';
  }
  for (int x = 0; x < n + 2; x++) {
    save[0][x] = 'Y';
    save[n + 1][x] = 'Y';
    save[x][0] = 'Y';
    save[x][n + 1] = 'Y';
  }
  bfs_bomb(z, t);
  for (int x = 1; x <= n; x++) {
    for (int y = n; y >= 1; y--) {
      if (mat[x][y] != 'Z' && mat[x][y] != 'Y' && mat[x][y] != '0') {
        bfs_lab(pair<int, int>(x, y), n, t);
      }
    }
  }
  printf("%d\n", dinic(0, n * n + 1));
}
