#include <bits/stdc++.h>   #pragma warning(disable : 4996)   using namespace std;   using ld = long double;   template <class T>   using Table = vector<vector<T>>;   const ld eps = 1e-9;   template <class S, class T>   ostream &operator<<(ostream &os, const pair<S, T> v) {     os <<  (   << v.first <<  ,   << v.second <<  ) ;     return os;   }   template <class T>   ostream &operator<<(ostream &os, const vector<T> &v) {     for (int i = 0; i < v.size(); i++) {       if (i > 0) {         os <<    ;       }       os << v[i];     }     return os;   }   template <class T>   ostream &operator<<(ostream &os, const vector<vector<T>> &v) {     for (int i = 0; i < v.size(); i++) {       if (i > 0) {         os << endl;       }       os << v[i];     }     return os;   }   template <class T>   ostream &operator<<(ostream &os, const vector<set<T>> &v) {     for (int i = 0; i < v.size(); i++) {       if (i > 0) {         os << endl;       }       os << v[i];     }     return os;   }   template <class T>   ostream &operator<<(ostream &os, const set<T> &v) {     int i = 0;     for (auto it : v) {       if (i > 0) {         os <<    ;       }       os << it;       i++;     }     return os;   }   const int INF = 2147483647;   const long long int L_INF = 9223372036854775807;   struct Edge {     int src, dst;     int weight;     Edge(int src, int dst, int weight) : src(src), dst(dst), weight(weight) {}   };   bool operator<(const Edge &e, const Edge &f) {     return e.weight != f.weight ? e.weight > f.weight            : e.src != f.src     ? e.src < f.src                                 : e.dst < f.dst;   }   int maximumFlow(const vector<vector<Edge>> &ag, int s, int t) {     vector<vector<Edge>> g(ag);     for (int i = 0; i < ag.size(); ++i) {       for (int j = 0; j < ag[i].size(); ++j) {         int d = ag[i][j].dst;         int s = ag[i][j].src;         bool ok = false;         for (int k = 0; k < ag[d].size(); ++k) {           if (ag[d][k].src == s) {             ok = true;             break;           }         }         if (!ok) {           g[d].push_back(Edge(d, s, 0));         }       }     }     int n = g.size();     vector<vector<int>> flow(n, vector<int>(n)), capacity(n, vector<int>(n));     for (int u = 0; u < (int)n; ++u)       for (auto e = (g[u]).begin(); e != (g[u]).end(); ++e)         capacity[e->src][e->dst] += e->weight;     int total = 0;     while (1) {       queue<int> Q;       Q.push(s);       vector<int> prev(n, -1);       prev[s] = s;       while (!Q.empty() && prev[t] < 0) {         int u = Q.front();         Q.pop();         for (auto e = (g[u]).begin(); e != (g[u]).end(); ++e)           if (prev[e->dst] < 0 && (capacity[u][e->dst] - flow[u][e->dst]) > 0) {             prev[e->dst] = u;             Q.push(e->dst);           }       }       if (prev[t] < 0) break;       int inc = INF;       for (int j = t; prev[j] != j; j = prev[j])         inc = min(inc, (capacity[prev[j]][j] - flow[prev[j]][j]));       for (int j = t; prev[j] != j; j = prev[j])         flow[prev[j]][j] += inc, flow[j][prev[j]] -= inc;       total += inc;     }     return total;   }   using ll = long long int;   int dx[] = {-1, 0, 1, 0};   int dy[] = {0, 1, 0, -1};   int N, T;   vector<vector<int>> get_time(const vector<vector<int>> &canmove, int sy, int sx,                                vector<vector<int>> c_times) {     vector<vector<int>> times(N, vector<int>(N, 100000));     if (c_times.empty()) {       c_times = times;     }     times[sy][sx] = 0;     queue<pair<int, int>> que;     que.emplace(sx, sy);     while (!que.empty()) {       auto p(que.front());       que.pop();       int x = p.first;       int y = p.second;       if (c_times[y][x] == times[y][x]) continue;       for (int way = 0; way < 4; ++way) {         int nx = x + dx[way];         int ny = y + dy[way];         if (nx >= 0 && nx < N && ny >= 0 && ny < N) {           if (canmove[ny][nx] != false) {             if (times[ny][nx] > times[y][x] + 1 &&                 c_times[ny][nx] >= times[y][x] + 1) {               times[ny][nx] = times[y][x] + 1;               que.emplace(nx, ny);             }           }         }       }     }     return times;   }   int main() {     ios::sync_with_stdio(false);     cin.tie();     cin >> N >> T;     vector<vector<int>> canmove(N, vector<int>(N, true));     vector<vector<int>> ins(N, vector<int>(N)), outs(N, vector<int>(N));     vector<string> in_sts(N), out_sts(N);     int collapt_x, collapt_y;     for (int i = 0; i < N; ++i) {       cin >> in_sts[i];       for (int j = 0; j < N; ++j) {         if (in_sts[i][j] ==  Y ) {           canmove[i][j] = false;         } else if (in_sts[i][j] ==  Z ) {           canmove[i][j] = false;         } else {           ins[i][j] = in_sts[i][j] -  0 ;         }       }     }     for (int i = 0; i < N; ++i) {       cin >> out_sts[i];       for (int j = 0; j < N; ++j) {         if (out_sts[i][j] ==  Y ) {         } else if (out_sts[i][j] ==  Z ) {           collapt_x = j;           collapt_y = i;         } else {           outs[i][j] = out_sts[i][j] -  0 ;         }       }     }     vector<vector<int>> collapt_times =         get_time(canmove, collapt_y, collapt_x, vector<vector<int>>(0));     vector<vector<vector<vector<int>>>> oks(         N,         vector<vector<vector<int>>>(N, vector<vector<int>>(N, vector<int>(N))));     const int start = 0;     const int in_id = 1;     const int out_id = in_id + N * N;     const int goal = out_id + N * N;     vector<vector<Edge>> g(goal + 1);     for (int y = 0; y < N; ++y) {       for (int x = 0; x < N; ++x) {         g[start].push_back(Edge{start, in_id + y * N + x, ins[y][x]});         g[out_id + y * N + x].push_back(             Edge{out_id + y * N + x, goal, outs[y][x]});       }     }     for (int y = 0; y < N; ++y) {       for (int x = 0; x < N; ++x) {         auto atimes = get_time(canmove, y, x, collapt_times);         for (int ty = 0; ty < N; ++ty) {           for (int tx = 0; tx < N; ++tx) {             if (atimes[ty][tx] <= collapt_times[ty][tx] && atimes[ty][tx] <= T) {               oks[y][x][ty][tx] = true;               int aid = in_id + y * N + x;               int bid = out_id + ty * N + tx;               g[aid].push_back(Edge{aid, bid, 1000});             }           }         }       }     }     int answer = maximumFlow(g, start, goal);     cout << answer << endl;     return 0;   }   