#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

int main()
{
    int n;
    cin>>n;
    string temp;
    bool postoji_pustinja = false;
    queue<pair<int, int>> q;
    set<pair<int, int>> visited;
    vector<vector<bool>> more(n, vector<bool>(n));
    vector<vector<int>> toksicnost(n, vector<int>(n));
    vector<vector<ll>> dp(n, vector<ll>(n));

    vector<vector<int>> najbliza_pustinja(n, vector<int>(n));

    for (int i = 0; i<n; i++) {
            cin>>temp;
        for (int j = 0; j<n; j++) {
            more[i][j] = temp[j] - '0';
            postoji_pustinja = postoji_pustinja || !more[i][j];
            if (!more[i][j]) {
                    q.push({i, j});

            }

        }
    }
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            cin>>toksicnost[i][j];
        }
    }

    int k = 0;
    while (!q.empty()) {

        int cur_size = q.size();

        for (int r = 0; r<cur_size; r++) {
            pair<int, int> p = q.front(); q.pop();
            int i = p.first, j = p.second;
            if (visited.count(p) || i<0 || j<0 || i>=n || j>=n) continue;
            najbliza_pustinja[i][j] = k;
            visited.insert({i, j});
            q.push({i+1, j});
            q.push({i-1, j});
            q.push({i, j+1});
            q.push({i, j-1});
        }
        k++;
    }




    dp[0][0] = (!more[0][0]) ? toksicnost[0][0] : 0;
    for (int i = 0; i<n; i++) {
        for (int j = 0; j<n; j++) {
            if (i == j && i == 0) continue;
            int trenutno_potezi = i + j;
            ll up = (i>0) ? dp[i-1][j] : numeric_limits<int>::max();
            ll left = (j>0) ? dp[i][j-1] : numeric_limits<int>::max();
            dp[i][j] = min(up, left);
            if (najbliza_pustinja[i][j] <= trenutno_potezi) {
                dp[i][j] += toksicnost[i][j];
            }
        }
    }



    cout<<dp[n-1][n-1];







}