#include <bits/stdc++.h>
using namespace std;
const int M = 10;
const int inf = 1000;
const int D = 9;
const int V = (M * M - 1) * D * 2 + 2;
int n, t;
int dist[M][M];
int fireTime[M][M];
bool visited[M][M];
char scholar[M][M];
char capsule[M][M];
int minTime[M][M][M][M];
bool canReach[M][M][M][M];
int source;
int sink;
int parent[V];
bool mark[V];
vector<int> N[V];
int C[V][V];
int capacity[V][V];
vector<pair<int, int> > spos;
vector<pair<int, int> > cpos;
void read();
void setFireTime();
void setVisited();
void initializeFireTime();
void initializeDistance();
pair<int, int> getBadReactor();
bool bfs(pair<int, int>, pair<int, int>);
void add(queue<pair<int, int> > &, pair<int, int>);
bool valid(int, int);
bool block(int, int);
void printFireTime();
void printTableLine();
void initialize();
void makeGraph();
int numberOfScholars();
int numberOfCapsules();
void addEdge(int, int, int);
void printGraph();
int calculateMaximumFlow();
void setMark();
int pathCap(int, int);
void updateGraph(int);
int main() {
  read();
  setFireTime();
  initialize();
  makeGraph();
  printf("%d\n", calculateMaximumFlow());
  return 0;
}
void read() {
  cin >> n >> t;
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) cin >> scholar[r][c];
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) cin >> capsule[r][c];
}
void setFireTime() {
  setVisited();
  initializeFireTime();
  initializeDistance();
  pair<int, int> start = getBadReactor();
  pair<int, int> goal = pair<int, int>(-1, -1);
  bfs(start, goal);
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) fireTime[r][c] = dist[r][c];
}
void setVisited() {
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) visited[r][c] = 0;
}
void initializeFireTime() {
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) fireTime[r][c] = inf;
}
void initializeDistance() {
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++) dist[r][c] = inf;
}
pair<int, int> getBadReactor() {
  pair<int, int> res;
  for (int r = 0; r < n; r++)
    for (int c = 0; c < n; c++)
      if (capsule[r][c] == 'Z') res = pair<int, int>(r, c);
  return res;
}
bool bfs(pair<int, int> start, pair<int, int> goal) {
  queue<pair<int, int> > Q;
  add(Q, start);
  int level = 0;
  bool result = false;
  while (!Q.empty()) {
    int size = Q.size();
    for (int i = 0; i < size; i++) {
      pair<int, int> v = Q.front();
      int time = fireTime[v.first][v.second];
      if (v == goal && level <= time) result = true;
      dist[v.first][v.second] = level;
      if (level < time) {
        for (int dr = -1; dr < 2; dr++) {
          for (int dc = -1; dc < 2; dc++) {
            int s = dr + dc;
            int p = dr * dc;
            if (s != 0 && p == 0) {
              int r = v.first + dr;
              int c = v.second + dc;
              if (valid(r, c) && !block(r, c) && !visited[r][c]) {
                pair<int, int> elem(r, c);
                add(Q, elem);
              }
            }
          }
        }
      }
      Q.pop();
    }
    level++;
  }
  return result;
}
void add(queue<pair<int, int> > &Q, pair<int, int> elem) {
  visited[elem.first][elem.second] = true;
  Q.push(elem);
}
bool valid(int r, int c) { return (r >= 0 && r < n && c < n && c >= 0); }
bool block(int r, int c) {
  return (capsule[r][c] == 'Y' || capsule[r][c] == 'Z');
}
void printFireTime() {
  printTableLine();
  for (int r = 0; r < n; r++) {
    for (int c = 0; c < n; c++) {
      if (c > 0) printf(" ");
      printf("| ");
      if (dist[r][c] == inf)
        printf("&");
      else
        printf("%c", char(fireTime[r][c] + int('0')));
    }
    printf(" |\n");
    printTableLine();
  }
}
void printTableLine() {
  int size = 4 * n + 1;
  for (int i = 0; i < size; i++) printf("-");
  printf("\n");
}
void initialize() {
  for (int row = 0; row < n; row++) {
    for (int col = 0; col < n; col++) {
      for (int r = 0; r < n; r++) {
        for (int c = 0; c < n; c++) {
          pair<int, int> start(row, col);
          pair<int, int> goal(r, c);
          setVisited();
          initializeDistance();
          bool reach = bfs(start, goal);
          canReach[row][col][r][c] = reach;
          if (reach) minTime[row][col][r][c] = dist[r][c];
        }
      }
    }
  }
}
void makeGraph() {
  source = 0;
  int p = numberOfScholars();
  int q = numberOfCapsules();
  sink = p + q + 1;
  for (int i = 1; i <= p; i++) addEdge(source, i, 1);
  for (int i = 1; i <= q; i++) addEdge(p + i, sink, 1);
  for (int i = 1; i <= p; i++) {
    for (int j = 1; j <= q; j++) {
      pair<int, int> start = spos[i];
      pair<int, int> end = cpos[j];
      int a = start.first;
      int b = start.second;
      int c = end.first;
      int d = end.second;
      if (canReach[a][b][c][d] && minTime[a][b][c][d] <= t)
        addEdge(i, p + j, 1);
    }
  }
}
int numberOfScholars() {
  int res = 0;
  pair<int, int> p(-1, -1);
  spos.push_back(p);
  for (int r = 0; r < n; r++) {
    for (int c = 0; c < n; c++) {
      char ch = scholar[r][c];
      if (ch >= '0' && ch <= '9') {
        int num = int(ch) - int('0');
        p = pair<int, int>(r, c);
        for (int i = 0; i < num; i++) spos.push_back(p);
        res += num;
      }
    }
  }
  return res;
}
int numberOfCapsules() {
  int res = 0;
  pair<int, int> p(-1, -1);
  cpos.push_back(p);
  for (int r = 0; r < n; r++) {
    for (int c = 0; c < n; c++) {
      char ch = capsule[r][c];
      if (ch >= '0' && ch <= '9') {
        int num = int(ch) - int('0');
        p = pair<int, int>(r, c);
        for (int i = 0; i < num; i++) cpos.push_back(p);
        res += num;
      }
    }
  }
  return res;
}
void addEdge(int u, int v, int cap) {
  N[u].push_back(v);
  N[v].push_back(u);
  C[u][v] = cap;
  capacity[u][v] = cap;
}
void printGraph() {
  printf("Source = %d  &&  Sink = %d\n", source, sink);
  for (int v = 0; v <= sink; v++) {
    printf("N[%d] = {", v);
    for (int i = 0; i < N[v].size(); i++) {
      if (i > 0) printf(", ");
      printf("%d", N[v][i]);
    }
    printf("}\n");
  }
  for (int u = 0; u <= sink; u++) {
    for (int v = 0; v <= sink; v++) {
      if (v > 0) printf(" ");
      printf("%d", capacity[u][v]);
    }
    printf("\n");
  }
}
int calculateMaximumFlow() {
  int flow = 0;
  while (true) {
    setMark();
    int cap = pathCap(source, -1);
    if (cap > 0) {
      flow += cap;
      updateGraph(cap);
    } else
      break;
  }
  return flow;
}
void setMark() {
  for (int v = 0; v < V; v++) mark[v] = false;
}
int pathCap(int v, int p) {
  mark[v] = true;
  parent[v] = p;
  if (v == sink) return 1;
  for (int i = 0; i < N[v].size(); i++) {
    int u = N[v][i];
    if (!mark[u] && C[v][u] > 0) {
      int cap = pathCap(u, v);
      if (cap > 0) return min(cap, C[v][u]);
    }
  }
  return 0;
}
void updateGraph(int cap) {
  int u, v;
  v = sink;
  while (true) {
    u = parent[v];
    if (u < 0) break;
    C[u][v] -= cap;
    C[v][u] += cap;
    v = u;
  }
}
