#include <bits/stdc++.h>

using namespace std;

long long inf = 1000000000;

void skupi(vector<string>& mat)
{
    vector<vector<char>> nova(mat.size(), vector<char>(mat.size()));

    for(int x = 1; x < mat.size(); x++)
    {
        for(int y = 1; y < mat.size(); y++)
        {
            if(x != 0 && !mat[x - 1][y]) nova[x][y] = '0';
            if(y != 0 && !mat[x][y - 1]) nova[x][y] = '0';
            if(x != mat.size() - 1 && !mat[x + 1][y]) nova[x][y] = '0';
            if(y != mat.size() - 1 && !mat[x][y + 1]) nova[x][y] = '0';
        }
    }

    for(int x = 1; x < mat.size(); x++)
    {
        for(int y = 1; y < mat.size(); y++)
        {
            mat[x][y] = nova[x][y];
        }
    }
}

int main()
{
    int n;
    cin >> n;
    vector<string> mat(n + 1);
    vector<vector<int>> t(n + 1, vector<int>(n + 1));

    for(int i = 1; i <= n; i++)
    {
        string s;
        cin >> s;

        mat[i] = "0" + s;
    }

    for(int y = 1; y <= n; y++)
    {
        for(int x = 1; x <= n; x++)
        {
            cin >> t[x][y];
        }
    }

    vector<vector<int>> dp(n + 1, vector<int>(n + 1, inf));

    for(int y = 1; y <= n; y++)
    {
        for(int x = 1; x <= n; x++)
        {
            if(x == y && y == 1) dp[x][y] = mat[x][y] == 0 ? t[x][y] : 0;
            else
            {
                dp[x][y] = (mat[x][y] == 0 ? t[x][y] : 0) + min(dp[x - 1][y], dp[x][y - 1]);
            }
        }
    }

    for(int kj= 0; kj < 5; kj++)
    {
        skupi(mat);

        for(int x = 1; x < mat.size(); x++)
        {
            for(int y = 1; y < mat.size(); y++)
            {
                cout << mat[x][y] << " ";
            }

            cout << endl;
        }

        cout << endl;
    }

    cout << dp[n][n];

    return 0;
}