#include <bits/stdc++.h>
using namespace std;
int n, t;
string A[11];
string B[11];
inline bool isNum(char ch) { return ch >= '0' && ch <= '9'; }
char BAD = 'Z';
char WALL = 'Y';
const int SSIZE = 1000;
vector<int> KEK[11][11];
vector<int> H[11][11];
bool possible[11][11][11][11];
bool HELP[11][11];
string getS[SSIZE];
string getH[SSIZE];
pair<int, int> BadGuy;
void Init() {
  int s = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (isNum(A[i][j])) {
        int k = A[i][j] - '0';
        while (k--) {
          getS[s] = to_string(i + 1) + " " + to_string(j + 1);
          KEK[i][j].push_back(s++);
        }
      }
      if (A[i][j] == BAD) {
        BadGuy = {i, j};
      }
    }
  }
  int h = 0;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (isNum(B[i][j])) {
        int k = B[i][j] - '0';
        while (k--) {
          getH[h] = to_string(i + 1) + " " + to_string(j + 1);
          H[i][j].push_back(h++);
        }
      }
    }
  }
}
bool WAT[11][11];
const vector<pair<int, int>> STEPS = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
void BIG_FUCKING_SEARCH() {
  deque<pair<pair<int, int>, pair<int, int>>> S;
  deque<pair<int, int>> W;
  W.push_back(BadGuy);
  memset(possible, 0, sizeof possible);
  WAT[BadGuy.first][BadGuy.second] = true;
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      if (isNum(A[i][j])) {
        possible[i][j][i][j] = true;
        if (KEK[i][j].size()) S.push_back({{i, j}, {i, j}});
      }
    }
  }
  int cur = 0;
  while (S.size() && cur++ < t) {
    deque<pair<pair<int, int>, pair<int, int>>> nS;
    while (S.size()) {
      auto [x, y] = S.front();
      S.pop_front();
      if (WAT[y.first][y.second]) continue;
      for (auto& [dx, dy] : STEPS) {
        int nx = dx + y.first;
        int ny = dy + y.second;
        if (nx < 0 || ny < 0 || nx == n || ny == n) continue;
        if (possible[x.first][x.second][nx][ny]) continue;
        if (WAT[nx][ny]) continue;
        if (A[nx][ny] == WALL) continue;
        possible[x.first][x.second][nx][ny] = true;
        nS.push_back({x, {nx, ny}});
      }
    }
    S = nS;
    deque<pair<int, int>> nW;
    while (W.size()) {
      auto [x, y] = W.front();
      W.pop_front();
      for (auto& [dx, dy] : STEPS) {
        int nx = x + dx;
        int ny = y + dy;
        if (nx < 0 || ny < 0 || nx == n || ny == n) continue;
        if (WAT[nx][ny]) continue;
        if (A[nx][ny] == WALL) continue;
        WAT[nx][ny] = true;
        nW.push_back({nx, ny});
      }
    }
    W = nW;
  }
}
vector<int> g[SSIZE];
int mt[SSIZE];
bool used[SSIZE];
bool inc(int f) {
  if (used[f]) return false;
  used[f] = true;
  for (int v : g[f]) {
    if (mt[v] == -1) {
      mt[v] = f;
      return true;
    }
  }
  for (int v : g[f]) {
    if (inc(mt[v])) {
      mt[v] = f;
      return true;
    }
  }
  return false;
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cin >> n >> t;
  for (int i = 0; i < n; i++) {
    cin >> A[i];
  }
  for (int i = 0; i < n; i++) {
    cin >> B[i];
  }
  Init();
  BIG_FUCKING_SEARCH();
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
      for (int kek : KEK[i][j]) {
        for (int k = 0; k < n; k++) {
          for (int l = 0; l < n; l++) {
            if (possible[i][j][k][l]) {
              for (int lel : H[k][l]) {
                g[kek].push_back(lel);
              }
            }
          }
        }
      }
    }
  }
  fill(mt, mt + SSIZE, -1);
  int ans = 0;
  for (int i = 0; i < SSIZE; i++) {
    memset(used, 0, sizeof used);
    ans += inc(i);
  }
  cout << ans << endl;
  return 0;
}
