#include <bits/stdc++.h>
#pragma GCC target("avx2")
#pragma GCC optimization("O3")
#pragma GCC optimization("unroll-loops")
using namespace std;
int a[20][20], b[20][20], a1[20][20], b1[20][20];
int n, tim, x2, y2;
vector<pair<int, int> > t;
void next(int x) {
  if (x == 0) return;
  t.clear();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (a[i][j] == -2) {
        if (i > 0)
          if (a[i - 1][j] != -1) t.push_back(make_pair(i - 1, j));
        if (i + 1 < n)
          if (a[i + 1][j] != -1) t.push_back(make_pair(i + 1, j));
        if (j > 0)
          if (a[i][j - 1] != -1) t.push_back(make_pair(i, j - 1));
        if (j + 1 < n)
          if (a[i][j + 1] != -1) t.push_back(make_pair(i, j + 1));
      }
  for (int i = 0; i < t.size(); i++) {
    a[t[i].first][t[i].second] = -2;
    b[t[i].first][t[i].second] = -2;
  }
}
int d[12][12][12][12][62];
bool can[12][12][12][12];
void calc_ways() {
  for (int i = 0; i <= tim; i++) {
    for (int j = 0; j < n; j++)
      for (int v = 0; v < n; v++) {
        queue<pair<int, int> > q;
        for (int u = 0; u < n; u++)
          for (int h = 0; h < n; h++) d[j][v][u][h][i] = 1e9;
        if (i == 0) {
          if (b[j][v] >= 0) {
            d[j][v][j][v][i] = 0;
            q.push(make_pair(j, v));
          }
        } else {
          for (int u = 0; u < n; u++)
            for (int h = 0; h < n; h++)
              if (d[j][v][u][h][i - 1] >= 0 && d[j][v][u][h][i - 1] < 1e9 &&
                  b[u][h] >= 0) {
                d[j][v][u][h][i] = d[j][v][u][h][i - 1];
                q.push(make_pair(u, h));
              }
        }
        while (q.size() > 0) {
          pair<int, int> now = q.front();
          q.pop();
          if (d[j][v][now.first][now.second][i] == i) continue;
          if (now.first > 0)
            if (a[now.first - 1][now.second] >= 0)
              if (d[j][v][now.first - 1][now.second][i] >
                  d[j][v][now.first][now.second][i] + 1) {
                q.push(make_pair(now.first - 1, now.second));
                d[j][v][now.first - 1][now.second][i] =
                    d[j][v][now.first][now.second][i] + 1;
              }
          if (now.first + 1 < n)
            if (a[now.first + 1][now.second] >= 0)
              if (d[j][v][now.first + 1][now.second][i] >
                  d[j][v][now.first][now.second][i]) {
                q.push(make_pair(now.first + 1, now.second));
                d[j][v][now.first + 1][now.second][i] =
                    d[j][v][now.first][now.second][i] + 1;
              }
          if (now.second > 0)
            if (a[now.first][now.second - 1] >= 0)
              if (d[j][v][now.first][now.second - 1][i] >
                  d[j][v][now.first][now.second][i] + 1) {
                q.push(make_pair(now.first, now.second - 1));
                d[j][v][now.first][now.second - 1][i] =
                    d[j][v][now.first][now.second][i] + 1;
              }
          if (now.second + 1 < n)
            if (a[now.first][now.second + 1] >= 0)
              if (d[j][v][now.first][now.second + 1][i] >
                  d[j][v][now.first][now.second][i]) {
                q.push(make_pair(now.first, now.second + 1));
                d[j][v][now.first][now.second + 1][i] =
                    d[j][v][now.first][now.second][i] + 1;
              }
        }
        for (int u = 0; u < n; u++)
          for (int h = 0; h < n; h++)
            if (d[j][v][u][h][i] < 1e9) can[j][v][u][h] = true;
      }
    next(i);
  }
}
int f[202][202];
void build_graph() {
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (b[i][j] > 0) {
        f[0][i * n + j + 1] += b[i][j];
        for (int v = 0; v < n; v++)
          for (int u = 0; u < n; u++)
            if (can[i][j][v][u] && a[v][u] > 0)
              f[i * n + j + 1][n * n + v * n + u + 1] = 20000;
      }
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++)
      if (a[i][j] > 0) f[n * n + i * n + j + 1][2 * n * n + 1] += a[i][j];
}
int flow;
int dist[202];
bool usd[202][202];
int p[202];
bool bfs() {
  queue<int> q;
  for (int i = 0; i < 202; i++)
    for (int j = 0; j < 202; j++) usd[i][j] = false;
  for (int i = 0; i < 202; i++) {
    dist[i] = 1e9;
    p[i] = 0;
  }
  dist[0] = 0;
  q.push(0);
  while (q.size() > 0) {
    int now = q.front();
    q.pop();
    for (int i = 0; i < 202; i++)
      if (f[now][i] > 0 && dist[i] > dist[now] + 1) {
        q.push(i);
        dist[i] = dist[now] + 1;
      }
  }
  if (dist[2 * n * n + 1] == 1e9) return false;
  return true;
}
int par[202];
bool dfs(int v, int mn) {
  if (v == 2 * n * n + 1) {
    int last = v;
    flow += mn;
    while (last != 0) {
      f[par[last]][last] -= mn;
      f[last][par[last]] += mn;
      last = par[last];
    }
    return true;
  }
  for (int i = p[v]; i <= 2 * n * n + 1; i++) {
    p[v] = i;
    if (f[v][i] > 0 && !usd[v][i] && dist[i] == dist[v] + 1) {
      par[i] = v;
      if (dfs(i, min(mn, f[v][i])))
        return true;
      else
        usd[v][i] = true;
    }
  }
  return false;
}
int main() {
  ios::sync_with_stdio(0);
  cin >> n >> tim;
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == 'Z') {
        b[i][j] = -2;
        x2 = i;
        y2 = j;
      } else if (s[j] == 'Y')
        b[i][j] = -1;
      else
        b[i][j] = s[j] - '0';
      b1[i][j] = b[i][j];
    }
  }
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < s.size(); j++) {
      if (s[j] == 'Z')
        a[i][j] = -2;
      else if (s[j] == 'Y')
        a[i][j] = -1;
      else
        a[i][j] = s[j] - '0';
      a1[i][j] = a[i][j];
    }
  }
  calc_ways();
  for (int i = 0; i < n; i++)
    for (int j = 0; j < n; j++) {
      a[i][j] = a1[i][j];
      b[i][j] = b1[i][j];
    }
  build_graph();
  while (true) {
    if (!bfs()) break;
    while (dfs(0, 2e9)) continue;
  }
  cout << flow << "\n";
}
