#include <bits/stdc++.h>
using namespace std;
int dx[] = {1, -1, 0, 0};
int dy[] = {0, 0, 1, -1};
struct edge {
  int from, to;
  int cap, flow;
  edge(int from, int to, int cap, int flow = 0)
      : from(from), to(to), cap(cap), flow(flow) {}
};
struct PushRelabel {
  int N;
  vector<edge> edges;
  vector<vector<int> > G;
  vector<int> h, inQ, count;
  vector<int> excess;
  queue<int> Q;
  PushRelabel(int N) : N(N), count(N << 1), G(N), h(N), inQ(N), excess(N) {}
  int addEdge(int from, int to, int cap) {
    G[from].push_back(edges.size());
    edges.push_back(edge(from, to, cap));
    G[to].push_back(edges.size());
    edges.push_back(edge(to, from, 0));
    return G[from].back();
  }
  void enQueue(int u) {
    if (!inQ[u] && excess[u] > 0) Q.push(u), inQ[u] = true;
  }
  void Push(int edgeIdx) {
    edge& e = edges[edgeIdx];
    int toPush = min<int>(e.cap - e.flow, excess[e.from]);
    if (toPush > 0 && h[e.from] > h[e.to]) {
      e.flow += toPush;
      excess[e.to] += toPush;
      excess[e.from] -= toPush;
      edges[edgeIdx ^ 1].flow -= toPush;
      enQueue(e.to);
    }
  }
  void Relabel(int u) {
    count[h[u]] -= 1;
    h[u] = 2 * N - 2;
    for (int i = 0; i < G[u].size(); ++i) {
      edge& e = edges[G[u][i]];
      if (e.cap > e.flow) h[u] = min(h[u], h[e.to]);
    }
    count[++h[u]] += 1;
  }
  void gapRelabel(int height) {
    for (int u = 0; u < N; ++u)
      if (h[u] >= height && h[u] < N) {
        count[h[u]] -= 1;
        count[h[u] = N] += 1;
        enQueue(u);
      }
  }
  void Discharge(int u) {
    for (int i = 0; excess[u] > 0 && i < G[u].size(); ++i) {
      Push(G[u][i]);
    }
    if (excess[u] > 0) {
      if (h[u] < N && count[h[u]] < 2)
        gapRelabel(h[u]);
      else
        Relabel(u);
    } else if (!Q.empty()) {
      Q.pop();
      inQ[u] = false;
    }
  }
  int getFlow(int src, int snk) {
    h[src] = N;
    inQ[src] = inQ[snk] = true;
    count[0] = N - (count[N] = 1);
    for (int i = 0; i < G[src].size(); ++i) {
      excess[src] += edges[G[src][i]].cap;
      Push(G[src][i]);
    }
    while (!Q.empty()) {
      Discharge(Q.front());
    }
    return excess[snk];
  }
};
int n, t;
string sci[15];
string cap[15];
int dis[15][15];
int dis2[15][15];
bool isvalid(int x, int y) {
  if (x < 0 || y < 0 || x >= n || y >= n) return false;
  if (sci[x][y] == 'Y' || sci[x][y] == 'Z') return false;
  return true;
}
void bfs1(int x, int y) {
  queue<pair<int, int> > q;
  q.push({x, y});
  memset(dis, -1, sizeof dis);
  dis[x][y] = 0;
  while (!q.empty()) {
    pair<int, int> u = q.front();
    q.pop();
    for (int i = 0; i < 4; i++) {
      int vx = u.first + dx[i];
      int vy = u.second + dy[i];
      if (isvalid(vx, vy) && dis[vx][vy] == -1) {
        dis[vx][vy] = 1 + dis[u.first][u.second];
        q.push({vx, vy});
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (dis[i][j] == -1) dis[i][j] = 1000000000;
    }
  }
}
int dp[65][12][12][12][12];
int pos(int tt, int x0, int y0, int x, int y) {
  if (dis[x0][y0] < tt) return 0;
  if (x0 == x and y0 == y) return 1;
  if (tt >= t) return 0;
  if (dis[x0][y0] <= tt) return 0;
  if (dp[tt][x0][y0][x][y] != -1) return dp[tt][x0][y0][x][y];
  for (int j = 0; j < 4; j++) {
    int xx = x0 + dx[j];
    int yy = y0 + dy[j];
    if (isvalid(xx, yy) && pos(tt + 1, xx, yy, x, y))
      return dp[tt][x0][y0][x][y] = 1;
  }
  return dp[tt][x0][y0][x][y] = 0;
}
int main() {
  memset(dp, -1, sizeof dp);
  cin >> n >> t;
  for (int i = 0; i < n; i++) {
    cin >> sci[i];
  }
  for (int i = 0; i < n; i++) {
    cin >> cap[i];
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (sci[i][j] == 'Z') {
        bfs1(i, j);
        break;
      }
    }
  }
  vector<pair<int, int> > sc, cp;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (sci[i][j] != 'Z' && sci[i][j] != 'Y' && sci[i][j] != '0') {
        sc.push_back({i, j});
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (cap[i][j] != 'Z' && cap[i][j] != 'Y' && cap[i][j] != '0') {
        cp.push_back({i, j});
      }
    }
  }
  PushRelabel flow(sc.size() + cp.size() + 2);
  for (int i = 0; i < sc.size(); i++) {
    long long c = sci[sc[i].first][sc[i].second] - '0';
    flow.addEdge(0, i + 1, c);
  }
  for (int i = 0; i < cp.size(); i++) {
    long long c = cap[cp[i].first][cp[i].second] - '0';
    flow.addEdge(sc.size() + 1 + i, sc.size() + cp.size() + 1, c);
  }
  for (int i = 0; i < sc.size(); i++) {
    for (int j = 0; j < cp.size(); j++) {
      if (pos(0, sc[i].first, sc[i].second, cp[j].first, cp[j].second)) {
        flow.addEdge(i + 1, sc.size() + 1 + j, 10000000);
      }
    }
  }
  cout << flow.getFlow(0, sc.size() + cp.size() + 1) << '\n';
}
