#include <bits/stdc++.h>
using namespace std;
const int MAXN = 7007;
const int MAXM = 300007;
const int INF = 1 << 29;
const int dir[][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
char reactor[15][15], rescue[15][15];
int N;
int table[15][15];
bool isIn(int x, int y) { return x >= 1 && y >= 1 && x <= N && y <= N; }
struct Edge {
  int u, v, cap, flow;
  Edge *next, *back;
};
struct Graph {
  Edge *head[MAXN], adj[MAXM];
  Edge *cur[MAXN], *path[MAXN];
  int lev[MAXN];
  int n, k;
  int S, T;
  void init(int nn) {
    S = 0, T = nn;
    n = nn, k = 0;
    for (int i = 0; i <= n; i++) head[i] = NULL;
  }
  void set(int s, int t) { S = s, T = t; }
  void addedge(int u, int v, int cap) {
    adj[k].u = u;
    adj[k].v = v;
    adj[k].flow = 0;
    adj[k].cap = cap;
    adj[k].next = head[u];
    head[u] = adj + k++;
  }
  void add(int u, int v, int cap) {
    addedge(u, v, cap);
    addedge(v, u, 0);
    head[u]->back = head[v];
    head[v]->back = head[u];
  }
  bool bfs() {
    queue<int> q;
    fill(lev, lev + n + 1, -1);
    lev[S] = 0;
    q.push(S);
    int u, v;
    while (!q.empty()) {
      u = q.front();
      q.pop();
      for (Edge *f = head[u]; f; f = f->next) {
        if (f->flow == f->cap) continue;
        v = f->v;
        if (lev[v] == -1) {
          lev[v] = lev[u] + 1;
          q.push(v);
          if (v == T) return true;
        }
      }
    }
    return (lev[T] != -1);
  }
  int dinic() {
    int u, v, pt;
    int flow = 0;
    while (bfs()) {
      for (int i = 0; i <= n; i++) cur[i] = head[i];
      pt = 0;
      u = S;
      while (true) {
        if (u == T) {
          int delta = INF, minI = 0;
          for (int i = 0; i < pt; i++) {
            if (delta > path[i]->cap - path[i]->flow) {
              delta = path[i]->cap - path[i]->flow;
              minI = i;
            }
          }
          for (int i = 0; i < pt; i++) {
            path[i]->flow += delta;
            path[i]->back->flow -= delta;
          }
          u = path[pt = minI]->u;
          flow += delta;
        }
        Edge *f;
        for (f = cur[u]; f; f = f->next) {
          if (f->cap == f->flow) continue;
          v = f->v;
          if (lev[v] == lev[u] + 1) break;
        }
        cur[u] = f;
        if (f) {
          path[pt++] = f;
          u = f->v;
        } else {
          lev[u] = -1;
          if (!pt) break;
          u = path[--pt]->u;
        }
      }
    }
    return flow;
  }
} graph;
void bfs(int sx, int sy, int t) {
  for (int i = 1; i <= N; i++) {
    fill(table[i], table[i] + N + 1, INF);
  }
  queue<pair<int, int> > q;
  q.push(pair<int, int>(sx, sy));
  table[sx][sy] = 0;
  while (!q.empty()) {
    pair<int, int> cur = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      int x = cur.first + dir[i][0];
      int y = cur.second + dir[i][1];
      if (!isIn(x, y) || !isdigit(reactor[x][y]) || table[x][y] != INF) {
        continue;
      }
      table[x][y] = table[cur.first][cur.second] + 1;
      q.push(pair<int, int>(x, y));
    }
  }
}
int main() {
  int n, t;
  int S, T;
  scanf("%d%d", &n, &t);
  N = n;
  int sx, sy;
  for (int i = 1; i <= n; i++) {
    scanf(" %s", reactor[i] + 1);
    for (int j = 1; j <= n; j++) {
      if (reactor[i][j] == 'Z') {
        sx = i;
        sy = j;
      }
    }
  }
  bfs(sx, sy, t);
  for (int i = 1; i <= n; i++) {
    scanf(" %s", rescue[i] + 1);
  }
  S = 0, T = (t + 1) * n * n + 1;
  graph.init(T);
  graph.set(S, T);
  for (int cur = 0; cur < t; cur++) {
    int add1 = cur * n * n;
    int add2 = (cur + 1) * n * n;
    for (int i = 1; i <= n; i++) {
      for (int j = 1; j <= n; j++) {
        if (!isdigit(reactor[i][j])) continue;
        if (isdigit(rescue[i][j]) && rescue[i][j] != '0') {
          graph.add(add1 + (i - 1) * n + j, add2 + (i - 1) * n + j,
                    rescue[i][j] - '0');
          if (cur >= table[i][j]) continue;
        }
        if (isdigit(reactor[i][j]) && cur < table[i][j]) {
          if (cur + 1 < table[i][j]) {
            graph.add(add1 + (i - 1) * n + j, add2 + (i - 1) * n + j, INF);
          }
          for (int k = 0; k < 4; k++) {
            int x = i + dir[k][0];
            int y = j + dir[k][1];
            if (!isIn(x, y) || !isdigit(reactor[x][y])) continue;
            if (cur + 1 < table[x][y] ||
                table[x][y] == cur + 1 && isdigit(rescue[x][y]))
              graph.add(add1 + (i - 1) * n + j, add2 + (x - 1) * n + y, INF);
          }
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      if (isdigit(reactor[i][j]) && reactor[i][j] != '0') {
        graph.add(S, (i - 1) * n + j, reactor[i][j] - '0');
      }
      if (isdigit(rescue[i][j]) && rescue[i][j] != '0') {
        graph.add(t * n * n + (i - 1) * n + j, T, rescue[i][j] - '0');
      }
    }
  }
  printf("%d\n", graph.dinic());
  return 0;
}
