#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5000;
const long double eps = (1e-12);
const int logn = 21;
const double Pi = acos(-1.0);
const long long pp = 1000000000 + 7;
int lowbit(int x) { return x & (-x); }
const int INF = 1e9;
int n, t;
int idx(int x, int y) { return (x - 1) * n + y; }
pair<int, int> ixd(int x) {
  int yy = x % n;
  if (yy == 0) yy = n;
  return make_pair((x - 1) / n + 1, yy);
}
int g1[100][100];
int val1[105];
int g2[100][100];
int val2[105];
char s[MAXN];
int dx[5] = {-1, 1, 0, 0};
int dy[5] = {0, 0, 1, -1};
struct Edge {
  int from, to;
  long long cap, flow;
};
struct Dinic {
  int n, tmp, s, t;
  vector<Edge> edges;
  vector<int> G[MAXN];
  bool vis[MAXN];
  int d[MAXN];
  int cur[MAXN];
  void init(int n, int s, int t) {
    this->n = n, this->s = s, this->t = t;
    edges.clear();
    for (int i = 1; i <= n; i++) G[i].clear();
  }
  void AddEdge(int from, int to, long long cap) {
    edges.push_back({from, to, cap, 0});
    edges.push_back({to, from, 0, 0});
    tmp = edges.size();
    G[from].push_back(tmp - 2);
    G[to].push_back(tmp - 1);
  }
  bool BFS() {
    memset(vis, 0, sizeof(vis));
    queue<int> q;
    q.push(s);
    d[s] = 0, vis[s] = 1;
    while (!q.empty()) {
      int x = q.front();
      q.pop();
      for (int i = 0; i < G[x].size(); i++) {
        Edge& e = edges[G[x][i]];
        if (!vis[e.to] && e.cap > e.flow) {
          vis[e.to] = 1;
          d[e.to] = d[x] + 1;
          q.push(e.to);
        }
      }
    }
    return vis[t];
  }
  long long DFS(int x, long long a) {
    if (x == t || a == 0) return a;
    long long flow = 0, f;
    for (int& i = cur[x]; i < G[x].size(); i++) {
      Edge& e = edges[G[x][i]];
      if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {
        e.flow += f;
        edges[G[x][i] ^ 1].flow -= f;
        flow += f;
        a -= f;
        if (a == 0) break;
      }
    }
    return flow;
  }
  long long Maxflow() {
    long long flow = 0;
    while (BFS()) {
      memset(cur, 0, sizeof(cur));
      flow += DFS(s, INF);
    }
    return flow;
  }
} dc;
int bad = 0;
int g[105];
bool vis[105][105];
void bfs() {
  queue<pair<pair<int, int>, int> > q;
  q.push(make_pair(make_pair(bad, bad), 1));
  for (int i = 1; i <= n * n; i++) {
    if (val1[i] == -1) continue;
    q.push(make_pair(make_pair(i, i), 1));
  }
  while (!q.empty()) {
    pair<int, int> tmp = q.front().first;
    int tim = q.front().second;
    q.pop();
    if (tim > t + 1) continue;
    if (vis[tmp.first][tmp.second]) continue;
    vis[tmp.first][tmp.second] = tim;
    if (tmp.first == bad) {
      g[tmp.second] = tim;
      pair<int, int> now = ixd(tmp.second);
      for (int i = 0; i < 4; i++) {
        int xx = now.first + dx[i];
        int yy = now.second + dy[i];
        if (xx < 1 || xx > n || yy < 1 || yy > n) continue;
        if (g1[xx][yy] == -1) continue;
        q.push(make_pair(make_pair(tmp.first, idx(xx, yy)), tim + 1));
      }
    }
    if (g[tmp.second] < tim && g[tmp.second] > 0) continue;
    dc.AddEdge(tmp.first, tmp.second + n * n, INF);
    if (g[tmp.second] > 0)
      continue;
    else {
      pair<int, int> now = ixd(tmp.second);
      for (int i = 0; i < 4; i++) {
        int xx = now.first + dx[i];
        int yy = now.second + dy[i];
        if (xx < 1 || xx > n || yy < 1 || yy > n) continue;
        if (g1[xx][yy] == -1) continue;
        q.push(make_pair(make_pair(tmp.first, idx(xx, yy)), tim + 1));
      }
    }
  }
}
signed main() {
  scanf("%d%d", &n, &t);
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    for (int j = 1; j <= n; j++) {
      if (s[j] == 'Z') {
        bad = idx(i, j);
        g1[i][j] = -1;
        val1[idx(i, j)] = -1;
      } else if (s[j] == 'Y') {
        g1[i][j] = -1;
        val1[idx(i, j)] = -1;
      } else {
        g1[i][j] = s[j] - '0';
        val1[idx(i, j)] = g1[i][j];
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    scanf("%s", s + 1);
    for (int j = 1; j <= n; j++) {
      if (s[j] == 'Z') {
        bad = idx(i, j);
        g2[i][j] = -1;
        val2[idx(i, j)] = -1;
      } else if (s[j] == 'Y') {
        g2[i][j] = -1;
        val2[idx(i, j)] = -1;
      } else {
        g2[i][j] = s[j] - '0';
        val2[idx(i, j)] = g2[i][j];
      }
    }
  }
  int ss = n * n * 2 + 1;
  int tt = ss + 1;
  dc.init(tt, ss, tt);
  for (int i = 1; i <= n * n; i++) {
    if (val1[i] != -1) dc.AddEdge(ss, i, val1[i]);
    if (val2[i] != -1) dc.AddEdge(i + n * n, tt, val2[i]);
  }
  bfs();
  int ans = dc.Maxflow();
  printf("%d\n", ans);
  return 0;
}
