#include<iostream>
#include<vector>
#include<string>
#include<algorithm>	
#include<map>
#include<set>
#include<utility>
#include<cmath>
#include<cstring>
#include<queue>
#include<stack>
#include<cstdio>
#include<sstream>
#include<iomanip>
#include<assert.h>
#include<typeinfo>
#define loop(i,a,b) for(int i=a;i<b;i++) 
#define rep(i,a) loop(i,0,a)
#define pb push_back
#define all(in) in.begin(),in.end()
#define shosu(x) fixed<<setprecision(x)
using namespace std;
//kaewasuretyuui
typedef long long ll;
typedef int Def;
typedef pair<Def,Def> pii;
typedef vector<Def> vi;
typedef vector<vi> vvi;
typedef vector<pii> vp;
typedef vector<vp> vvp;
typedef vector<string> vs;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef pair<Def,pii> pip;
typedef vector<pip>vip;
//#define mt make_tuple
//typedef tuple<pii,int,int> tp;
//typedef vector<tp> vt;
template<typename A,typename B>bool cmin(A &a,const B &b){return a>b?(a=b,true):false;}
template<typename A,typename B>bool cmax(A &a,const B &b){return a<b?(a=b,true):false;}
//template<class C>constexpr int size(const C &c){return (int)c.size();}
//template<class T,size_t N> constexpr int size(const T (&xs)[N])noexcept{return (int)N;}
const double PI=acos(-1);
const double EPS=1e-7;
Def inf=sizeof(Def)==sizeof(long long)?2e18:1e9;
int dx[]={0,1,0,-1};
int dy[]={1,0,-1,0};
struct edge{
	int to,cap,cost,rev;
};
typedef vector<edge> ve;
typedef vector<ve> vve;
class MCF{	//Minimum Cost Flow
	public:
	int n;
	vve G;
	vi h,dist,prev,pree;
	MCF(int size){
		n=size;
		G=vve(n);
		h=dist=prev=pree=vi(n);
	}
	void add_edge(int s,int t,int ca,int co){
		edge e={t,ca,co,G[t].size()};
		G[s].pb(e);
		edge ee={s,0,-co,G[s].size()-1};
		G[t].pb(ee);
	}
	int mcf(int s,int t,int f){
		int out=0;
		h=vi(n);
		while(f>0){			
			priority_queue<pii,vector<pii> >q;
			dist=vi(n,inf);
			dist[s]=0;
			q.push(pii(0,s));
			while(!q.empty()){
				pii p=q.top();q.pop();
				int v=p.second;
				if(dist[v]<-p.first)continue;
				rep(i,G[v].size()){
					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];
						prev[e.to]=v;
						pree[e.to]=i;
						q.push(pii(-dist[e.to],e.to));
					}
				}
			}
			if(dist[t]==inf)return -1;
			rep(i,n)h[i]+=dist[i];
			int d=f;
			for(int v=t;v!=s;v=prev[v])d=min(d,G[prev[v]][pree[v]].cap);
			f-=d;
			out+=d*h[t];
			for(int v=t;v!=s;v=prev[v]){
				edge &e=G[prev[v]][pree[v]];
				e.cap-=d;
				G[v][e.rev].cap+=d;
			}
		}
		return out;	
	}
};
//struct edge{
//	int to,cap,cost,rev;
//};
int main(){
	int n;
	cin>>n;
	vvi tu(n,vi(n));
	vvi ke(n,vi(n));
	rep(i,n)rep(j,n)cin>>tu[i][j];
	rep(i,n)rep(j,n)cin>>ke[i][j];
	MCF mcf(2*n+2);
	int s=2*n,t=s+1;
	rep(i,n)mcf.add_edge(s,i,1,0);
	rep(i,n)mcf.add_edge(n+i,t,1,0);
	vs in(n);
	rep(i,n)cin>>in[i];
	rep(i,n)rep(j,n){
		int sum=0;
		if(in[i][j]=='.')sum+=tu[i][j]*2;
		rep(k,n)if(i!=k&&in[k][j]=='o')sum+=ke[k][j];
		rep(k,n)if(j!=k&&in[i][k]=='o')sum+=ke[i][k];
		mcf.add_edge(i,n+j,1,sum);
	}
	int f=mcf.mcf(s,t,n)/2;
	cout<<f<<endl;
	vve G=mcf.G;
	int co=0;
	rep(i,n)rep(j,G[i].size()){
		int to=G[i][j].to-n;
		bool h=false;
		if(0<=to&&to<n&&!G[i][j].cap)h=1;
		if(h&&in[i][to]=='.')co++;
		if(!h&&in[i][to]=='o')co++;
	}
	cout<<co<<endl;
	rep(i,n)rep(j,G[i].size()){
		int to=G[i][j].to-n;
		bool h=false;
		if(0<=to&&to<n&&!G[i][j].cap)h=1;
		if(h&&in[i][to]=='.')cout<<i+1<<" "<<to+1<<" "<<"write"<<endl;
		if(!h&&in[i][to]=='o')cout<<i+1<<" "<<to+1<<" "<<"erase"<<endl;
	}
}

Measured memory_bytes: 3660