#include "bits/stdc++.h"
#include<unordered_map>
#include<unordered_set>
#pragma warning(disable:4996)
using namespace std;
using ld = long double;
template<class T>
using Table = vector<vector<T>>;



#define REP(i,n) for(int i=0;i<(int)n;++i)
#define FOR(i,c) for(auto i=(c).begin();i!=(c).end();++i)
#define ALL(c) (c).begin(), (c).end()


const int INF = 2147483647;
const long long int L_INF = 9223372036854775807;

typedef int Weight;
struct Edge {
	int src, dst;
	Weight capacity;
	Weight cost;
	Edge(int src, int dst, Weight acap, Weight acost) :
		src(src), dst(dst), capacity(acap), cost(acost) { }
};
bool operator < (const Edge &e, const Edge &f) {
	return e.cost > f.cost;
}
typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

typedef vector<Weight> Array;
typedef vector<Array> Matrix;
#define RESIDUE(s,t) (capacity[s][t]-flow[s][t])


#define RCOST(u,v) (cost[u][v] + h[u] - h[v])

//??°?????????????????§???????????????????????¨?????????
Matrix m;
//Graph &ag
//????????§???????????????(u, v, capacity, cost) ??????????????????(u, v, 0, -cost) ???????????°????????????????????¶?????????????????§????´???°????????§???????????°???????????????
//int s, int t
//?????????????§??????¨?????????
//?????????
//?????¨??¨????????????????????????
pair<Weight, Weight> minimumCostFlow(const Graph &ag, int s, int t) {
//check???????´???°??????????????£???????????????
	Graph g(ag);
	for (int i = 0; i < ag.size(); ++i) {
		for (int j = 0; j < ag[i].size(); ++j) {
			int d = ag[i][j].dst;
			int s = ag[i][j].src;

			bool ok = false;
			for (int k = 0; k < ag[d].size(); ++k) {
				if (ag[d][k].src == s) {
					ok = true;
					break;
				}
			}
			if (!ok) {
				g[d].push_back(Edge(d, s, 0, -ag[i][j].cost));
			}
		}
	}
	const int n = g.size();
	Matrix capacity(n, Array(n)), cost(n, Array(n)), flow(n, Array(n));
	REP(u, n) FOR(e, g[u]) {
		capacity[e->src][e->dst] += e->capacity;
		cost[e->src][e->dst] += e->cost;
	}
	pair<Weight, Weight> total; // (cost, flow)
	vector<Weight> h(n);

	for (Weight F = INF; F > 0; ) { // residual flow
		vector<Weight> d(n, INF); d[s] = 0;
		vector<int> p(n, -1);
		priority_queue<Edge> Q; // "e < f" <=> "e.cost > f.cost"
		for (Q.push(Edge(-2, s, 0, 0)); !Q.empty(); ) {
			Edge e = Q.top(); Q.pop();
			if (p[e.dst] != -1) continue;
			p[e.dst] = e.src;
			FOR(f, g[e.dst]) if (RESIDUE(f->src, f->dst) > 0) {
				if (d[f->dst] > d[f->src] + RCOST(f->src, f->dst)) {
					d[f->dst] = d[f->src] + RCOST(f->src, f->dst);
					Q.push(Edge(f->src, f->dst, 0, d[f->dst]));
				}
			}
		}
		if (p[t] == -1) break;

		Weight f = F;
		for (int u = t; u != s; u = p[u])
			f = min(f, RESIDUE(p[u], u));
		for (int u = t; u != s; u = p[u]) {
			total.first += f * cost[p[u]][u];
			flow[p[u]][u] += f; flow[u][p[u]] -= f;
		}
		F -= f;
		total.second += f;
		REP(u, n) h[u] += d[u];
	}
	m = flow;
	return total;
}
struct operate {
	int y;
	int x;
	bool erase;
};
int main() {
	int N; cin >> N;
	vector<vector<int>>wcosts(N, vector<int>(N));
	vector<vector<int>>ecosts(N, vector<int>(N));
	vector<vector<int>>circle(N, vector<int>(N));
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			int wcost; cin >> wcost;
			wcosts[i][j] = wcost;
		}
	}
	for (int i = 0; i < N; ++i) {
		for (int j = 0; j < N; ++j) {
			int ecost; cin >> ecost;
			ecosts[i][j] = ecost;
		}
	}
	for (int i = 0; i < N; ++i) {
		string st; cin >> st;
		for (int j = 0; j < N; ++j) {
			if (st[j] == 'o')circle[i][j] = 1;
		}
	}
	Graph g(2 * N + 2);
	const int Start = 0;
	const int From = 1;
	const int To = From + N;
	const int Goal = To + N;
	for (int i = 0; i < N; ++i) {
		g[Start].push_back(Edge(Start, From + i, 1, 0));
	}
	for (int f = 0; f < N; ++f) {
		for (int t = 0; t < N; ++t) {
			int ncost = 0;
			for (int y = 0; y < N; ++y) {
				if (y == t&&!circle[f][y])ncost += wcosts[f][y];
				else if (y != t&&circle[f][y])ncost += ecosts[f][y];
			}
			g[From + f].push_back(Edge(From + f, To + t, 1, ncost));
		}
	}
	for (int i = 0; i < N; ++i) {
		g[To+i].push_back(Edge(To + i, Goal, 1, 0));
	}
	const pair<Weight, Weight>ans=minimumCostFlow(g, Start, Goal);
	vector<int>fincircles;
	for (int f = 0; f < N; ++f) {
		for (int t = 0; t < N; ++t) {
			if (m[From + f][To + t]) {
				fincircles.push_back(t);
			}
		}
	}
	vector<operate>ops;
	for (int f = 0; f < N; ++f) {
		for (int t = 0; t < N; ++t) {
			if (circle[f][t]) {
				if (fincircles[f] != t)ops.push_back(operate{ t + 1,f + 1,true });
			}
			else {
				if (fincircles[f] == t)ops.push_back(operate{ t + 1,f + 1,false });
			}
		}
	}
	cout << ans.first << endl;
	cout << ops.size() << endl;
	for (auto o : ops) {
		cout << o.x << " " << o.y << " ";
		if (o.erase)cout << "erase" << endl;
		else cout << "write" << endl;
	}
	return 0;
}

Measured memory_bytes: 4424