Problem: Doctor prescribed medicine to his patient. The medicine is represented by pills. Each pill consists of a shell and healing powder. The shell consists of two halves; each half has one of four colors — blue, red, white or yellow.

The doctor wants to put 28 pills in a rectangular box 7 × 8 in size. Besides, each pill occupies exactly two neighboring cells and any cell contains exactly one half of a pill. Thus, the result is a four colored picture 7 × 8 in size.

The doctor thinks that a patient will recover sooner if the picture made by the pills will be special. Unfortunately, putting the pills in the box so as to get the required picture is not a very easy task. That's why doctor asks you to help. 

Doctor has some amount of pills of each of 10 painting types. They all contain the same medicine, that's why it doesn't matter which 28 of them will be stored inside the box.

Place the pills in the box so that the required picture was formed. If it is impossible to place the pills in the required manner, then place them so that the number of matching colors in all 56 cells in the final arrangement and the doctor's picture were maximum.

Input

First 7 lines contain the doctor's picture. Each line contains 8 characters, each character can be "B", "R", "W" and "Y" that stands for blue, red, white and yellow colors correspondingly.

Next four lines contain 10 numbers that stand for, correspondingly, the number of pills painted:

"BY" "BW" "BR" "BB"

"RY" "RW" "RR"

"WY" "WW"

"YY"

Those numbers lie within range from 0 to 28 inclusively. It is guaranteed that the total number of pills in no less than 28.

Output

Print on the first line the maximal number cells for which the colors match.

Then print 13 lines each containing 15 characters — the pills' position in the optimal arrangement. The intersections of odd lines and odd columns should contain characters "B", "R", "W" and "Y". All other positions should contain characters ".", "-" and "|". Use "-" and "|" to show which halves belong to one pill. See the samples for more clarification.

If there are several possible solutions, print any of them.

Examples

Input

WWWBBWWW
WWWBBWWW
YYWBBWWW
YYWBBWRR
YYWBBWRR
YYWBBWRR
YYWBBWRR
0 0 0 8
0 1 5
1 10
5


Output

53
W.W.W.B.B.W.W.W
|.|.|.|.|.|.|.|
W.W.W.B.B.W.W.W
...............
Y.Y.W.B.B.W.W-W
|.|.|.|.|.|....
Y.Y.W.B.B.W.R.R
............|.|
Y.Y.W.B.B.R.R.R
|.|.|.|.|.|....
Y.Y.W.B.B.W.R.R
............|.|
Y-Y.B-B.B-B.R.R


Input

WWWWWWWW
WBYWRBBY
BRYRBWYY
WWBRYWBB
BWWRWBYW
RBWRBWYY
WWWWWWWW
0 0 0 1
0 0 1
0 1
25


Output

15
W.Y.Y-Y.Y-Y.Y-Y
|.|............
W.Y.Y.Y.Y.B-B.Y
....|.|.|.....|
Y-Y.Y.Y.Y.Y-Y.Y
...............
Y.Y.Y.R.Y.Y.Y-Y
|.|.|.|.|.|....
Y.Y.Y.R.Y.Y.Y.Y
............|.|
Y-Y.Y.Y-Y.Y.Y.Y
....|.....|....
Y-Y.Y.Y-Y.Y.Y-Y

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int INF = 1000000000;
vector<int> hung(const vector<vector<int> > &A) {
  int n = A.size();
  int m = A[0].size();
  vector<vector<long long> > a(n + 1);
  a[0] = vector<long long>(m + 1);
  for (int i = 0; i < n; ++i) {
    a[i + 1].push_back(100LL * INF);
    for (int j = 0; j < m; ++j) {
      a[i + 1].push_back(A[i][j]);
    }
  }
  vector<long long> u(n + 1), v(m + 1);
  vector<int> p(m + 1), way(m + 1);
  for (int i = 1; i <= n; ++i) {
    p[0] = i;
    int j0 = 0;
    vector<long long> minv(m + 1, 100LL * INF);
    vector<char> used(m + 1, false);
    do {
      used[j0] = true;
      int i0 = p[j0], j1;
      long long delta = 100LL * INF;
      for (int j = 1; j <= m; ++j)
        if (!used[j]) {
          long long cur = a[i0][j] - u[i0] - v[j];
          if (cur < minv[j]) minv[j] = cur, way[j] = j0;
          if (minv[j] < delta) delta = minv[j], j1 = j;
        }
      for (int j = 0; j <= m; ++j)
        if (used[j])
          u[p[j]] += delta, v[j] -= delta;
        else
          minv[j] -= delta;
      j0 = j1;
    } while (p[j0] != 0);
    do {
      int j1 = way[j0];
      p[j0] = p[j1];
      j0 = j1;
    } while (j0);
  }
  vector<int> rv(n);
  for (int j = 1; j <= m; ++j) {
    rv[p[j] - 1] = j - 1;
  }
  return rv;
}
struct MinCostFlow {
  struct edge {
    int b, u, c, f;
    size_t back;
  };
  int n, m;
  vector<vector<edge> > g;
  MinCostFlow(int n) : n(n), m(0), g(n) {}
  void add_edge(int a, int b, int u, int c) {
    ++m;
    edge r1 = {b, u, c, 0, g[b].size()};
    edge r2 = {a, 0, -c, 0, g[a].size()};
    g[a].push_back(r1);
    g[b].push_back(r2);
  }
  int flow(int s, int t, int k) {
    int flow = 0, cost = 0;
    while (flow < k) {
      vector<int> id(n, 0);
      vector<int> d(n, INF);
      vector<int> q(n);
      vector<int> p(n);
      vector<size_t> p_edge(n);
      int qh = 0, qt = 0;
      q[qt++] = s;
      d[s] = 0;
      while (qh != qt) {
        int v = q[qh++];
        id[v] = 2;
        if (qh == n) qh = 0;
        for (size_t i = 0; i < g[v].size(); ++i) {
          edge &r = g[v][i];
          if (r.f < r.u && d[v] + r.c < d[r.b]) {
            d[r.b] = d[v] + r.c;
            if (id[r.b] == 0) {
              q[qt++] = r.b;
              if (qt == n) qt = 0;
            } else if (id[r.b] == 2) {
              if (--qh == -1) qh = n - 1;
              q[qh] = r.b;
            }
            id[r.b] = 1;
            p[r.b] = v;
            p_edge[r.b] = i;
          }
        }
      }
      if (d[t] == INF) break;
      int addflow = k - flow;
      for (int v = t; v != s; v = p[v]) {
        int pv = p[v];
        size_t pr = p_edge[v];
        addflow = min(addflow, g[pv][pr].u - g[pv][pr].f);
      }
      for (int v = t; v != s; v = p[v]) {
        int pv = p[v];
        size_t pr = p_edge[v], r = g[pv][pr].back;
        g[pv][pr].f += addflow;
        g[v][r].f -= addflow;
        cost += g[pv][pr].c * addflow;
      }
      flow += addflow;
    }
    if (flow < k) {
      return -1;
    }
    return cost;
  }
};
const int MAXN = 30000;
struct Dinic {
  struct edge {
    int a, b, cap, flow;
  };
  int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
  vector<edge> e;
  vector<int> g[MAXN];
  Dinic(int n) : n(n) {}
  void add_edge(int a, int b, int cap) {
    edge e1 = {a, b, cap, 0};
    edge e2 = {b, a, 0, 0};
    g[a].push_back((int)e.size());
    e.push_back(e1);
    g[b].push_back((int)e.size());
    e.push_back(e2);
  }
  bool bfs() {
    int qh = 0, qt = 0;
    q[qt++] = s;
    memset(d, -1, n * sizeof d[0]);
    d[s] = 0;
    while (qh < qt && d[t] == -1) {
      int v = q[qh++];
      for (size_t i = 0; i < g[v].size(); ++i) {
        int id = g[v][i], to = e[id].b;
        if (d[to] == -1 && e[id].flow < e[id].cap) {
          q[qt++] = to;
          d[to] = d[v] + 1;
        }
      }
    }
    return d[t] != -1;
  }
  int dfs(int v, int flow) {
    if (!flow) return 0;
    if (v == t) return flow;
    for (; ptr[v] < (int)g[v].size(); ++ptr[v]) {
      int id = g[v][ptr[v]], to = e[id].b;
      if (d[to] != d[v] + 1) continue;
      int pushed = dfs(to, min(flow, e[id].cap - e[id].flow));
      if (pushed) {
        e[id].flow += pushed;
        e[id ^ 1].flow -= pushed;
        return pushed;
      }
    }
    return 0;
  }
  int flow(int S, int T) {
    s = S;
    t = T;
    int flow = 0;
    for (;;) {
      if (!bfs()) break;
      memset(ptr, 0, n * sizeof ptr[0]);
      while (int pushed = dfs(s, INF)) flow += pushed;
    }
    return flow;
  }
};
struct MaxFlow {
  struct Edge {
    int to, c, ne;
    Edge(int to, int c, int ne) : to(to), c(c), ne(ne) {}
  };
  int n;
  vector<Edge> ed;
  vector<int> fi;
  MaxFlow(int n) : n(n), ed(), fi(n, -1) {}
  void add_edge(int a, int b, int c) {
    ed.push_back(Edge(b, c, fi[a]));
    fi[a] = (int)ed.size() - 1;
    ed.push_back(Edge(a, c, fi[b]));
    fi[b] = (int)ed.size() - 1;
  }
  vector<char> us;
  int dfs(int v, int tar, int cur, int minv = 1) {
    if (v == tar) return cur;
    if (us[v]) return 0;
    us[v] = 1;
    for (int i = fi[v]; i != -1; i = ed[i].ne) {
      if (ed[i].c < minv) {
        continue;
      }
      int tmp = dfs(ed[i].to, tar, min(cur, ed[i].c), minv);
      if (tmp > 0) {
        ed[i].c -= tmp;
        ed[i ^ 1].c += tmp;
        return tmp;
      }
    }
    return 0;
  }
  int flow(int s, int t) {
    int ans = 0, cur, mv = 1;
    for (int i = 0; i < 2; ++i) {
      do {
        us = vector<char>(n);
        cur = dfs(s, t, INF, mv);
        ans += cur;
      } while (cur);
    }
    return ans;
  }
};
struct BoundedMinFlow {
  vector<int> a, b;
  vector<int> l, r;
  int n;
  BoundedMinFlow(int n) : n(n) {}
  void add_edge(int f, int t, int minc, int maxc) {
    a.push_back(f);
    b.push_back(t);
    l.push_back(minc);
    r.push_back(maxc);
  }
  bool check(int s, int t, int m) {
    MaxFlow f(n + 2);
    f.add_edge(t, s, m);
    int total = 0;
    for (int i = 0; i < (int)a.size(); ++i) {
      if (l[i] > 0) {
        f.add_edge(n, b[i], l[i]);
        f.add_edge(a[i], n + 1, l[i]);
        total += l[i];
      }
      if (r[i] > l[i]) {
        f.add_edge(a[i], b[i], r[i] - l[i]);
      }
    }
    return (f.flow(n, n + 1) == total);
  }
  int flow(int s, int t) {
    int le = -1, ri = 10000;
    if (!check(s, t, ri)) {
      return -1;
    }
    while (le + 1 < ri) {
      int mi = (le + ri);
      if (check(s, t, mi)) {
        ri = mi;
      } else {
        le = mi;
      }
    }
    return ri;
  }
};
int h, w;
string va[16] = {"BY", "BW", "BR", "BB", "RY", "RW", "RR", "WY", "WW", "YY"};
char vv[16][2];
char st[16][16][4][2];
int cnt[16];
struct pos {
  int sx, sy, ex, ey;
  int id;
  pos() {}
  pos(int SX, int SY, int EX, int EY, int ID)
      : sx(SX), sy(SY), ex(EX), ey(EY), id(ID) {}
  bool operator<(const pos &p) const { return id < p.id; }
};
map<vector<int>, vector<pos> > mp;
char t[16][16];
int lp;
vector<pos> p(28);
vector<int> cur;
bool us[16][16];
int dif[16][16];
char ou[32][32];
int gk[32][32][2];
void prec() {
  for (int r = 0; r < h; ++r) {
    for (int c = 0; c + 1 < w; ++c) {
      int k = -1;
      for (int i = 0; i < 10; ++i) {
        if ((st[r][c][0][0] == vv[i][0] && st[r][c][0][1] == vv[i][1]) ||
            (st[r][c][1][0] == vv[i][0] && st[r][c][1][1] == vv[i][1])) {
          k = i;
          break;
        }
      }
      gk[r][c][0] = k;
    }
  }
  for (int r = 0; r + 1 < h; ++r) {
    for (int c = 0; c < w; ++c) {
      int k = -1;
      for (int i = 0; i < 10; ++i) {
        if ((st[r][c][2][0] == vv[i][0] && st[r][c][2][1] == vv[i][1]) ||
            (st[r][c][3][0] == vv[i][0] && st[r][c][3][1] == vv[i][1])) {
          k = i;
          break;
        }
      }
      gk[r][c][1] = k;
    }
  }
}
void go(int r, int c) {
  if (r >= h) {
    if (mp.find(cur) != mp.end()) {
      return;
    }
    mp[cur] = p;
    return;
  }
  if (c >= w) {
    go(r + 1, 0);
    return;
  }
  if (us[r][c]) {
    go(r, c + 1);
    return;
  }
  if (!us[r][c + 1] && c + 1 < w) {
    us[r][c] = us[r][c + 1] = 1;
    int k = gk[r][c][0];
    cur[k]++;
    p[lp].sx = r;
    p[lp].sy = c;
    p[lp].ex = r;
    p[lp].ey = c + 1;
    p[lp].id = k;
    ++lp;
    go(r, c + 2);
    cur[k]--;
    --lp;
    us[r][c] = us[r][c + 1] = 0;
  }
  if (!us[r + 1][c] && r + 1 < h) {
    us[r][c] = us[r + 1][c] = 1;
    int k = gk[r][c][1];
    cur[k]++;
    p[lp].sx = r;
    p[lp].sy = c;
    p[lp].ex = r + 1;
    p[lp].ey = c;
    p[lp].id = k;
    ++lp;
    go(r, c + 1);
    cur[k]--;
    --lp;
    us[r][c] = us[r + 1][c] = 0;
  }
}
int main() {
  h = 7;
  w = 8;
  for (int i = 0; i < h; ++i) {
    scanf("%s", t[i]);
  }
  for (int i = 0; i < 10; ++i) {
    scanf("%d", &cnt[i]);
  }
  cur = vector<int>(10, 0);
  memset(us, 0, sizeof(us));
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j + 1 < w; ++j) {
      st[i][j][0][0] = t[i][j];
      st[i][j][0][1] = t[i][j + 1];
      st[i][j][1][0] = t[i][j + 1];
      st[i][j][1][1] = t[i][j];
    }
  }
  for (int i = 0; i + 1 < h; ++i) {
    for (int j = 0; j < w; ++j) {
      st[i][j][2][0] = t[i][j];
      st[i][j][2][1] = t[i + 1][j];
      st[i][j][3][0] = t[i + 1][j];
      st[i][j][3][1] = t[i][j];
    }
  }
  for (int i = 0; i < 10; ++i) {
    vv[i][0] = va[i][0];
    vv[i][1] = va[i][1];
  }
  prec();
  go(0, 0);
  memset(dif, 0, sizeof(dif));
  for (int i = 0; i < 10; ++i) {
    for (int j = 0; j < 10; ++j) {
      dif[i][j] = min((va[i][0] != va[j][0]) + (va[i][1] != va[j][1]),
                      (va[i][0] != va[j][1]) + (va[i][1] != va[j][0]));
    }
  }
  int bsol = (1 << 20);
  MinCostFlow be(1);
  vector<pos> bp;
  for (map<vector<int>, vector<pos> >::iterator it = mp.begin(); it != mp.end();
       ++it) {
    MinCostFlow f(22);
    for (int i = 0; i < 10; ++i) {
      f.add_edge(20, i, cnt[i], 0);
      f.add_edge(10 + i, 21, it->first[i], 0);
    }
    for (int i = 0; i < 10; ++i) {
      for (int j = 0; j < 10; ++j) {
        f.add_edge(i, j + 10, INF, dif[i][j]);
      }
    }
    int k = f.flow(20, 21, 28);
    if (k < bsol) {
      bsol = k;
      be = f;
      bp = it->second;
    }
  }
  printf("%d\n", 56 - bsol);
  memset(ou, '.', sizeof(ou));
  for (int i = 0; i < (int)bp.size(); ++i) {
    int nd = bp[i].id + 10;
    for (int j = 0; j < (int)be.g[nd].size(); ++j) {
      MinCostFlow::edge &ed = be.g[nd][j];
      if (ed.b < 10 && ed.f < 0) {
        ++ed.f;
        int c1 = (va[ed.b][0] != t[bp[i].sx][bp[i].sy]) +
                 (va[ed.b][1] != t[bp[i].ex][bp[i].ey]);
        int c2 = (va[ed.b][1] != t[bp[i].sx][bp[i].sy]) +
                 (va[ed.b][0] != t[bp[i].ex][bp[i].ey]);
        if (c1 <= c2) {
          ou[2 * bp[i].sx][2 * bp[i].sy] = va[ed.b][0];
          ou[2 * bp[i].ex][2 * bp[i].ey] = va[ed.b][1];
        } else {
          ou[2 * bp[i].sx][2 * bp[i].sy] = va[ed.b][1];
          ou[2 * bp[i].ex][2 * bp[i].ey] = va[ed.b][0];
        }
        if (bp[i].sx == bp[i].ex) {
          ou[2 * bp[i].sx][2 * bp[i].sy + 1] = '-';
        } else {
          ou[2 * bp[i].sx + 1][2 * bp[i].sy] = '|';
        }
        break;
      }
    }
  }
  for (int i = 0; i < 2 * h - 1; ++i) {
    ou[i][2 * w - 1] = '\0';
    printf("%s\n", ou[i]);
  }
  return 0;
}