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

#define inf (int)(1e9)
template <class T>
struct Primal_Dual {
  using P = pair<T, int>;
  struct edge {
    int to;
    T cap, cost;
    int rev;
  };
  int v;
  vector<vector<edge>> edges;
  vector<T> h;
  vector<T> d;
  vector<int> prevv, preve;
  Primal_Dual(int _n = 1) {
    v = _n;
    edges.clear();
    edges.resize(v);
    h.resize(v);
    d.resize(v);
    prevv.resize(v);
    preve.resize(v);
  }
  bool add(int from, int to, T cap, T cost) {
    edges[from].push_back(
        (edge){to, cap, cost, (int)edges[to].size()});
    edges[to].push_back((edge){
        from, 0, -cost, (int)edges[from].size() - 1});
    return 1;
  }
  T solve(int s, int t, T f) {
    T res = 0;
    h.assign(v, 0);
    while(f > 0) {
      priority_queue<P, vector<P>, greater<P>> qu;
      d.assign(v, inf);
      d[s] = 0;
      qu.push({0, s});
      while(!qu.empty()) {
        P now = qu.top();
        qu.pop();
        int nowv = now.second;
        if(d[nowv] < now.first) continue;
        for(int i = 0; i < (int)edges[nowv].size(); ++i) {
          edge &e = edges[nowv][i];
          if(e.cap > 0 && d[e.to] > d[nowv] + e.cost +
                                        h[nowv] - h[e.to]) {
            d[e.to] = d[nowv] + e.cost + h[nowv] - h[e.to];
            prevv[e.to] = nowv;
            preve[e.to] = i;
            qu.push({d[e.to], e.to});
          }
        }
      }
      if(d[t] == inf) return -1;
      for(int i = 0; i < v; ++i) h[i] += d[i];
      T d = f;
      for(int i = t; i != s; i = prevv[i])
        d = min(d, edges[prevv[i]][preve[i]].cap);
      f -= d;
      res += d * h[t];
      for(int i = t; i != s; i = prevv[i]) {
        edge &e = edges[prevv[i]][preve[i]];
        e.cap -= d;
        edges[i][e.rev].cap += d;
      }
    }
    return res;
  }
};

struct data {
  int x, y;
  bool iswrite;
};

int n;
vector<vector<int>> w, e;
vector<string> f;
Primal_Dual<long long> pd;
vector<data> v;

int main() {
  cin >> n;
  w.resize(n, vector<int>(n));
  e.resize(n, vector<int>(n));
  f.resize(n);
  for(int i = 0; i < n; ++i)
    for(int j = 0; j < n; ++j) cin >> w[i][j];
  for(int i = 0; i < n; ++i)
    for(int j = 0; j < n; ++j) cin >> e[i][j];
  for(int i = 0; i < n; ++i) cin >> f[i];
  pd = Primal_Dual<long long>(2 * n + 2);
  for(int i = 0; i < n; ++i) pd.add(2 * n, i, 1, 0);
  for(int i = 0; i < n; ++i) pd.add(i + n, 2 * n + 1, 1, 0);
  for(int i = 0; i < n; ++i)
    for(int j = 0; j < n; ++j) {
      long long cos = 0;
      for(int k = 0; k < n; ++k) {
        if(k != j && f[i][k] != '.') cos += e[i][k];
        if(k != i && f[k][j] != '.') cos += e[k][j];
      }
      if(f[i][j] == '.') cos += 2 * w[i][j];
      pd.add(i, j + n, 1, cos);
    }
  cout << pd.solve(2 * n, 2 * n + 1, n) / 2 << endl;
  for(int i = 0; i < n; ++i)
    for(auto e : pd.edges[i])
      if(e.to >= n && e.to < 2 * n) {
        if(e.cap == 0 && f[i][e.to - n] == '.')
          v.push_back({i, e.to - n, 1});
        if(e.cap == 1 && f[i][e.to - n] != '.')
          v.push_back({i, e.to - n, 0});
      }
  cout << v.size() << endl;
  for(auto d : v)
    cout << d.x + 1 << " " << d.y + 1 << " "
         << (d.iswrite ? "write" : "erase") << endl;
  return 0;
}



Measured memory_bytes: 3940