#include <bits/stdc++.h>
const long long INF = (long long)0x3f3f3f3f3f3f3f, MAX = 9e18, MIN = -9e18;
const double PI = acos(-1.0);
const double eps = 1e-6;
const long long mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const int maxn = 500 + 10;
const int maxm = 100 + 10;
using namespace std;
int n, m, k;
int danger[12][12];
string s[maxn], t[maxn];
int dir[4][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
struct node {
  int x, y;
};
int vis1[12][12];
int tim;
void getdanger(int x, int y) {
  queue<node> q;
  while (!q.empty()) {
    q.pop();
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      vis1[i][j] = 0;
    }
  }
  node now;
  now.x = x;
  now.y = y;
  vis1[x][y] = 1;
  q.push(now);
  while (!q.empty()) {
    now = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      int xx = dir[i][0] + now.x;
      int yy = dir[i][1] + now.y;
      if (xx < 1 || yy < 1 || xx > n || yy > m ||
          danger[xx][yy] < danger[now.x][now.y] + 1 || vis1[xx][yy] ||
          s[xx][yy] == 'Y')
        continue;
      danger[xx][yy] = min(danger[now.x][now.y] + 1, danger[xx][yy]);
      node tmp;
      tmp.x = xx;
      tmp.y = yy;
      vis1[xx][yy] = 1;
      q.push(tmp);
    }
  }
}
long long dis[12][12][12][12];
void getdis(int x, int y) {
  queue<node> q;
  while (!q.empty()) {
    q.pop();
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      vis1[i][j] = 0;
    }
  }
  node now;
  now.x = x;
  now.y = y;
  vis1[x][y] = 1;
  dis[x][y][x][y] = 0;
  q.push(now);
  while (!q.empty()) {
    now = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      int xx = dir[i][0] + now.x;
      int yy = dir[i][1] + now.y;
      if (xx < 1 || yy < 1 || xx > n || yy > m || s[xx][yy] == 'Z' ||
          s[xx][yy] == 'Y' || vis1[xx][yy] ||
          dis[x][y][now.x][now.y] + 1 > danger[xx][yy])
        continue;
      dis[x][y][xx][yy] = min(dis[x][y][now.x][now.y] + 1, dis[x][y][xx][yy]);
      if (dis[x][y][xx][yy] == danger[xx][yy]) {
        if (t[xx][yy] > '9' || t[xx][yy] < '1') {
          dis[x][y][xx][yy] = inf;
          continue;
        } else {
          vis1[xx][yy] = 1;
          continue;
        }
      }
      vis1[xx][yy] = 1;
      node tmp;
      tmp.x = xx;
      tmp.y = yy;
      q.push(tmp);
    }
  }
}
int st, ed;
int cur[maxn];
int d[maxn];
struct edge {
  int from, to, cap, flow;
};
vector<edge> edges;
vector<int> G[maxn];
void addedge(int from, int to, int cap, int flow) {
  edges.push_back((edge){from, to, cap, 0});
  edges.push_back((edge){to, from, 0, 0});
  int sz = edges.size();
  G[from].push_back(sz - 2);
  G[to].push_back(sz - 1);
}
int vis[maxn];
bool bfs() {
  queue<int> q;
  d[st] = 0;
  memset(vis, 0, sizeof(vis));
  vis[st] = 1;
  q.push(st);
  while (!q.empty()) {
    int u = q.front();
    q.pop();
    for (int i = 0; i < G[u].size(); i++) {
      edge& e = edges[G[u][i]];
      int v = e.to;
      if (!vis[v] && e.cap - e.flow > 0) {
        d[v] = d[u] + 1;
        vis[v] = 1;
        if (v == ed) return true;
        q.push(v);
      }
    }
  }
  return false;
}
int dfs(int u, int a) {
  if (u == ed || a == 0) return a;
  int f, flow = 0;
  for (int& i = cur[u]; i < G[u].size(); i++) {
    edge& e = edges[G[u][i]];
    int v = e.to;
    if (d[v] == d[u] + 1 && e.cap - e.flow > 0) {
      f = dfs(v, min(a, e.cap - e.flow));
      e.flow += f;
      edges[G[u][i] ^ 1].flow -= f;
      flow += f;
      a -= f;
      if (a == 0) break;
    }
  }
  return flow;
}
int maxflow() {
  int flow = 0;
  while (bfs()) {
    memset(cur, 0, sizeof(cur));
    flow += dfs(st, inf);
  }
  return flow;
}
void init() {
  for (int i = 0; i < maxn; i++) G[i].clear();
  edges.clear();
}
void run_case() {
  cin >> n >> tim;
  m = n;
  init();
  for (int i = 1; i <= n; i++) {
    cin >> s[i];
    s[i] = " " + s[i];
  }
  for (int i = 1; i <= n; i++) {
    cin >> t[i];
    t[i] = " " + t[i];
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      danger[i][j] = inf;
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (t[i][j] >= '1' && t[i][j] <= '9') {
        danger[i][j] = inf;
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] == 'Z') {
        danger[i][j] = 0;
        getdanger(i, j);
      }
    }
  }
  for (int x = 1; x <= n; x++) {
    for (int y = 1; y <= n; y++) {
      for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
          dis[x][y][i][j] = INF;
        }
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] >= '1' && s[i][j] <= '9') {
        getdis(i, j);
      }
    }
  }
  st = n * m * 2 + 10;
  ed = st + 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (s[i][j] <= '9' && s[i][j] >= '1') {
        addedge(st, (i - 1) * m + j, s[i][j] - '0', 0);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      if (t[i][j] <= '9' && t[i][j] >= '1') {
        addedge(n * m + (i - 1) * m + j, ed, t[i][j] - '0', 0);
      }
    }
  }
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      for (int x = 1; x <= n; x++) {
        for (int y = 1; y <= m; y++) {
          if (s[i][j] <= '9' && s[i][j] >= '1' && t[x][y] <= '9' &&
              t[x][y] >= '1') {
            if (dis[i][j][x][y] <= danger[x][y] && dis[i][j][x][y] <= tim) {
              addedge((i - 1) * m + j, n * m + (x - 1) * m + y, inf, 0);
            }
          }
        }
      }
    }
  }
  cout << maxflow() << "\n";
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  ;
  run_case();
}
