#include<bits/stdc++.h>
using namespace std;

const int M = 1000000007;

typedef pair<int, int> P;
struct edge { int to, cap, cost, rev; };

int V;
vector<edge> G[210];
int h[210];
int dist[210];
int prevv[210], preve[210];
void add_edge(int from, int to, int cap, int cost) {
    G[from].push_back((edge){ to, cap, cost, (int)G[to].size() });
    G[to].push_back((edge){ from, 0, -cost, (int)G[from].size() - 1 });
}

int min_cost_flow(int s, int t, int f) {
    int res = 0;
    fill(h, h + V, 0);
    while (f > 0) {
        priority_queue<P, vector<P>, greater<P> > q;
        fill(dist, dist + V, M);
        dist[s] = 0;
        q.push(P(0, s));
        while (!q.empty()) {
            P p = q.top();
            q.pop();
            int v = p.second;
            if (dist[v] < p.first) continue;
            for (int i = 0; i < (int)G[v].size(); ++i) {
                edge &e = G[v][i];
                if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
                    dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                    prevv[e.to] = v;
                    preve[e.to] = i;
                    q.push(P(dist[e.to], e.to));
                }
            }
        }
        if (dist[t] == M) return -1;
        for (int v = 0; v < V; ++v)
            h[v] += dist[v];

        int d = f;
        for (int v = t; v != s; v = prevv[v])
            d = min(d, G[prevv[v]][preve[v]].cap);

        f -= d;
        res += d * h[t];
        for (int v = t; v != s; v = prevv[v]) {
            edge &e = G[prevv[v]][preve[v]];
            e.cap -= d;
            G[v][e.rev].cap += d;
        }
    }
    return res;
}


int main() {
    int n;
    cin >> n;
    vector<vector<int>> wc(n, vector<int>(n));
    vector<vector<int>> ec(n, vector<int>(n));
    vector<vector<int>> cost(n, vector<int>(n));
    vector<string> s(n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            cin >> wc[i][j];

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

    for (int i = 0; i < n; ++i)
        cin >> s[i];

    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            int c = (s[i][j] == 'o' ? 0 : wc[i][j]);
            for (int k = 0; k < n; ++k)
                if (k != j && s[i][k] == 'o')
                    c += ec[i][k];

            cost[i][j] = c;
        }
    }
    V = n * 2 + 2;
    for (int i = 0; i < n; ++i) {
        add_edge(n * 2, i, 1, 0);
        add_edge(n + i, n * 2 + 1, 1, 0);
    }
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            add_edge(i, n + j, 1, cost[i][j]);

    int mc = min_cost_flow(n * 2, n * 2 + 1, n);
    vector<vector<int>> cir(n, vector<int>(n, 0));
    for (int i = 0; i < n; ++i)
        for (edge& e : G[i])
            if (e.to >= n && e.to < n * 2 && e.cap == 0)
                cir[i][e.to - n] = 1;

    vector<string> ans;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            if (s[i][j] == '.' && cir[i][j])
                ans.push_back(to_string(i + 1) + " " + to_string(j + 1) + " write\n");
            if (s[i][j] == 'o' && !cir[i][j])
                ans.push_back(to_string(i + 1) + " " + to_string(j + 1) + " erase\n");
        }
    }
    cout << mc << "\n" << ans.size() << "\n";
    for (string i : ans)
        cout << i;

    return 0;
}

Measured memory_bytes: 3748