#include <bits/stdc++.h>
#define ll long long
#define INF 1000000005
#define MOD 1000000007
#define EPS 1e-10
#define rep(i,n) for(int i=0;i<(int)n;++i)
#define each(a, b) for(auto (a): (b))
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
#define pb push_back
#define show(x) cout <<#x<<" = "<<(x)<<endl
#define spair(p) cout <<#p<<": "<<p.fi<<" "<<p.se<<endl
#define svec(v) cout<<#v<<":";rep(i,v.size())cout<<" "<<v[i];cout<<endl
#define sset(s) cout<<#s<<":";each(i,s)cout <<" "<<i;cout<<endl

using namespace std;

typedef pair<int,int>P;
typedef pair<P,int>PP;

struct edge{
    int to,cap,cost,rev; //?????????,??????,?????¨,??????
};

const int MAX_N = 102;
const int MAX_V = 205;

int n;
int W[MAX_N][MAX_N];
int E[MAX_N][MAX_N];
int mp[MAX_N][MAX_N];
vector<edge> G[MAX_V];
int memo[MAX_V][MAX_V];

void add_edge(int from,int to,int cap,int cost){
	G[from].push_back((edge){to,cap,cost,G[to].size()});
	G[to].push_back((edge){from,0,-cost,G[from].size()-1});
}

int min_cost_flow(const int vcnt,const int s,const int t,int f)
{
	int res =0;
	int dist[MAX_V];
	int prevv[MAX_V];
	int preve[MAX_V];
	while(f>0){
		fill(dist,dist+vcnt,INF);
		dist[s] = 0;
		bool update = true;
		while(update){
			update = false;
			for(int v=0;v<vcnt;v++){
				if(dist[v] == INF)	continue;
				for(int i=0;i<G[v].size();i++){
					edge &e = G[v][i];
					if(e.cap > 0 && dist[e.to] > dist[v] + e.cost){
						dist[e.to] = dist[v] + e.cost;
						prevv[e.to] = v;	//??????????????????????¨???¶
						preve[e.to] = i;	//????????????????¨???¶
						update = true;
					}
				}
			}
		}

		if(dist[t] == INF){
			return -1;
		}

		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 * dist[t];
		for(int v=t;v!=s;v=prevv[v]){
			edge &e = G[prevv[v]][preve[v]];
            memo[prevv[v]][e.to] = 1;
			e.cap -= d;
            memo[e.to][prevv[v]] = 0;
			G[v][e.rev].cap += d;
		}
	}
	return res;
}

int main()
{
    cin >> n;
    int sm = 0;
    rep(i,n){
        rep(j,n){
            cin >> W[i][j];
        }
    }
    rep(i,n){
        rep(j,n){
            cin >> E[i][j];
        }
    }
    rep(i,n){
        rep(j,n){
            char c;
            cin >> c;
            if(c == 'o'){
                mp[i][j] = 1;
            }else{
                mp[i][j] = 0;
            }
        }
    }
    rep(i,n){
        rep(j,n){
            if(mp[i][j] == 1){
                add_edge(i+1,j+n+1,INF,-E[i][j]);
                sm += E[i][j];
            }else{
                add_edge(i+1,j+n+1,INF,W[i][j]);
            }
        }
    }
    rep(i,n){
        add_edge(0,i+1,1,0);
        add_edge(i+n+1,2*n+1,1,0);
    }
    cout << sm + min_cost_flow(2*n+2,0,2*n+1,n) << "\n";
    vector<PP> ans;
    rep(i,n){
        rep(j,n){
            if(mp[i][j] == 1 && memo[i+1][j+n+1] != 1){
                ans.pb(PP(P(i+1,j+1),0));
            }else if(mp[i][j] == 0 && memo[i+1][j+n+1] == 1){
                ans.pb(PP(P(i+1,j+1),1));
            }
        }
    }
    cout << ans.size() << "\n";
    rep(i,ans.size()){
        if(ans[i].se == 0){
            cout << (ans[i].fi).fi << " " << (ans[i].fi).se << " erase\n";
        }else{
            cout << (ans[i].fi).fi << " " << (ans[i].fi).se << " write\n";
        }
    }
    return 0;
}

Measured memory_bytes: 3680