#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <map>
#include <set>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <sstream>
#include <complex>
#include <stack>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iterator>
#include <bitset>
#include <unordered_set>
#include <unordered_map>
#include <fstream>
#include <iomanip>
//#include <utility>
//#include <memory>
//#include <functional>
//#include <deque>
//#include <cctype>
//#include <ctime>
//#include <numeric>
//#include <list>
//#include <iomanip>

//#if __cplusplus >= 201103L
//#include <array>
//#include <tuple>
//#include <initializer_list>
//#include <forward_list>
//
//#define cauto const auto&
//#else

//#endif

using namespace std;


typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

typedef vector<int> vint;
typedef vector<vector<int> > vvint;
typedef vector<long long> vll, vLL;
typedef vector<vector<long long> > vvll, vvLL;

#define VV(T) vector<vector< T > >

template <class T>
void initvv(vector<vector<T> > &v, int a, int b, const T &t = T()){
    v.assign(a, vector<T>(b, t));
}

template <class F, class T>
void convert(const F &f, T &t){
    stringstream ss;
    ss << f;
    ss >> t;
}

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define reep(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n) reep((i),0,(n))
#define ALL(v) (v).begin(),(v).end()
#define PB push_back
#define F first
#define S second
#define mkp make_pair
#define RALL(v) (v).rbegin(),(v).rend()
#define DEBUG
#ifdef DEBUG
#define dump(x)  cout << #x << " = " << (x) << endl;
#define debug(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;
#else
#define dump(x) 
#define debug(x) 
#endif
#define LDcout(x,n) fixed<<setprecision(n)<<x

#define MOD 1000000007LL
#define EPS 1e-8
static const int INF=1<<24;
// ????°??????¨???(Min Cost Flow)

template <class T> class MinCostFlow{
public:
  void addEdge(int from, int dest, int capacity, T cost);
  void terminateNegativeLoop(); // This requires all negative loops to be touched.
  T minCostFlow(int flow_source, int flow_target, int flow);
 
  MinCostFlow(int vertex_num);
  MinCostFlow(){}
 
private:
  class Edge{
  public:
    int dest;
    int capacity;
    int reversed_index;
    T cost;
    
    Edge(int dest, int capacity, int reversed_index, T cost){
      this->dest = dest;
      this->capacity = capacity;
      this->reversed_index = reversed_index;
      this->cost = cost;
    }
  };
  T negative_loop_cost;
public:
  int vertex_num;
  std::vector<std::vector<Edge>> edges;
};
 
template <class T>
inline MinCostFlow<T>::MinCostFlow(int vertex_num){
  this->vertex_num = vertex_num;
  negative_loop_cost = 0;
  edges = std::vector<std::vector<Edge>>(vertex_num);
}
 
template <class T>
inline void MinCostFlow<T>::addEdge(int from, int dest, int capacity, T cost){
  Edge e0(dest, capacity, edges[dest].size(),  cost);
  Edge e1(from,        0, edges[from].size(), -cost);
  edges[from].push_back(e0);
  edges[dest].push_back(e1);
}
 
template <class T>
inline T MinCostFlow<T>::minCostFlow(int flow_source, int flow_target, int flow){
  std::vector<std::tuple<T, bool>> costs(vertex_num);
  T total = 0;
  std::vector<int> pre_v(vertex_num);
  std::vector<int> pre_e(vertex_num);
  while(0 < flow){
    for(int vertex = 0; vertex < vertex_num; ++vertex) costs[vertex] = std::make_tuple(0, false);
    costs[flow_source] = std::make_tuple(0, true);
    for(bool updated = true; updated;){
      updated = false;
      for(int vertex = 0; vertex < vertex_num; ++vertex){
        if(!std::get<1>(costs[vertex])) continue;
        for(int edge_index = 0; edge_index < edges[vertex].size(); ++edge_index){
          Edge &e = edges[vertex][edge_index];
          if(e.capacity == 0) continue;
          if(std::get<1>(costs[e.dest]) && std::get<0>(costs[e.dest]) <= std::get<0>(costs[vertex]) + e.cost) continue;
          costs[e.dest] = std::make_tuple(std::get<0>(costs[vertex]) + e.cost, true);
          pre_v[e.dest] = vertex;
          pre_e[e.dest] = edge_index;
          updated = true;
        }
      }
    }
    if(!std::get<1>(costs[flow_target])) return -1;
    int minimum_flow = flow;
    for(int vertex = flow_target; vertex != flow_source; vertex = pre_v[vertex]){
      minimum_flow = std::min(minimum_flow, edges[pre_v[vertex]][pre_e[vertex]].capacity);
    }
    flow -= minimum_flow;
    
    total += minimum_flow * std::get<0>(costs[flow_target]);
    for(int vertex = flow_target; vertex != flow_source; vertex = pre_v[vertex]){
      Edge &e = edges[pre_v[vertex]][pre_e[vertex]];
      e.capacity -= minimum_flow;
      edges[vertex][e.reversed_index].capacity += minimum_flow;
    }
  }
  return total + negative_loop_cost;
}
 
template <class T> 
void MinCostFlow<T>::terminateNegativeLoop(){
  std::vector<int> pre_v(vertex_num);
  std::vector<int> pre_e(vertex_num);
  std::vector<int> used(vertex_num);
  std::vector<T> distances(vertex_num);
 
  while(true){
    int vertex_in_loop = -1;
    for(int i = 0; i < vertex_num; i++) used[i] = distances[i] = 0;
    for(int step = 0; step <= vertex_num; ++step){
      bool updated=false;
      for(int vertex = 0; vertex < vertex_num; ++vertex){
        for(int edge_index = 0; edge_index < edges[vertex].size(); ++edge_index){
          Edge &e = edges[vertex][edge_index];
          if(e.capacity == 0 || distances[e.dest] <= distances[vertex] + e.cost) continue;
          distances[e.dest] = distances[vertex] + e.cost;
          pre_v[e.dest] = vertex;
          pre_e[e.dest] = edge_index;
          vertex_in_loop = e.dest;
          updated = true;
        }
      }
      if(!updated) return;
    }
 
    for(; !used[vertex_in_loop]; vertex_in_loop = pre_v[vertex_in_loop]) used[vertex_in_loop] = true;
    
    T total_cost = 0;
    int minimum_capacity = edges[pre_v[vertex_in_loop]][pre_e[vertex_in_loop]].capacity;
    int cur = vertex_in_loop;
    do{
      total_cost += edges[pre_v[cur]][pre_e[cur]].cost;
      minimum_capacity = std::min(minimum_capacity, edges[pre_v[cur]][pre_e[cur]].capacity);
      cur = pre_v[cur];
    }while(cur != vertex_in_loop);
 
    negative_loop_cost += total_cost * minimum_capacity;
    
    cur = vertex_in_loop;
    do{
      Edge &e = edges[pre_v[cur]][pre_e[cur]];
      e.capacity -= minimum_capacity;
      edges[cur][e.reversed_index].capacity += minimum_capacity;
      cur = pre_v[cur];
    }while(cur != vertex_in_loop);
  }
}
void mainmain(){
    int n;
    cin>>n;
    vvint wcost,ecost;
    initvv(ecost,n,n);
    initvv(wcost,n,n);
    rep(i,n) rep(j,n) cin>>wcost[i][j];
    rep(i,n) rep(j,n) cin>>ecost[i][j];
    vector<string> vs(n);
    rep(i,n) cin>>vs[i];
    MinCostFlow<int> mf(300);
    int start=2*n+1;
    int goal=2*n+2;
    rep(i,n){
        mf.addEdge(start,i,1,0);
        mf.addEdge(n+i,goal,1,0);
    }
    rep(i,n){
        int tt=0;
        rep(j,n) if(vs[i][j]=='o') tt+=ecost[i][j];
        rep(j,n){
            int t;
            if(vs[i][j]=='o'){
                t=tt-ecost[i][j];
            }
            else{
                t=tt+wcost[i][j];
            }
            // cout<<i<<" "<<j<<" "<<t<<endl;
            mf.addEdge(i,n+j,1,t);
        }
    }
    int ans=mf.minCostFlow(start,goal,n);
    vector<pair<pii,string>> tmp;
    rep(i,n){
        rep(j,n){
            bool f=false;
            for(auto x:mf.edges[i]){
                if(x.capacity==0&&x.dest==j+n) f=true;
            }
            if(vs[i][j]=='o'&&!f){
                tmp.PB(mkp(pii(i+1,j+1),"erase"));
            }
            if(vs[i][j]=='.'&&f){
                tmp.PB(mkp(pii(i+1,j+1),"write"));
            }
        }
    }
    cout<<ans<<endl;
    cout<<tmp.size()<<endl;
    rep(i,tmp.size()){
        cout<<tmp[i].F.F<<" "<<tmp[i].F.S<<" "<<tmp[i].S<<endl;
    }
    // cout<<mf.minCostFlow(start,goal,n)<<endl;
}


signed main() {
    ios_base::sync_with_stdio(false);
    cout<<fixed<<setprecision(0);
    mainmain();
}

Measured memory_bytes: 1900