Problem:
Score : 600 points

Problem Statement

There is a game that involves three variables, denoted A, B, and C.

As the game progresses, there will be N events where you are asked to make a choice.
Each of these choices is represented by a string s_i. If s_i is AB, you must add 1 to A or B then subtract 1 from the other; if s_i is AC, you must add 1 to A or C then subtract 1 from the other; if s_i is BC, you must add 1 to B or C then subtract 1 from the other.

After each choice, none of A, B, and C should be negative.

Determine whether it is possible to make N choices under this condition. If it is possible, also give one such way to make the choices.

Constraints

1 \leq N \leq 10^5

0 \leq A,B,C \leq 10^9

N, A, B, C are integers.

s_i is AB, AC, or BC.

Input

Input is given from Standard Input in the following format:

N A B C
s_1
s_2
:
s_N

Output

If it is possible to make N choices under the condition, print Yes; otherwise, print No.

Also, in the former case, show one such way to make the choices in the subsequent N lines. The (i+1)-th line should contain the name of the variable (A, B, or C) to which you add 1 in the i-th choice.

Sample Input 1

2 1 3 0
AB
AC

Sample Output 1

Yes
A
C

You can successfully make two choices, as follows:

In the first choice, add 1 to A and subtract 1 from B. A becomes 2, and B becomes 2.

In the second choice, add 1 to C and subtract 1 from A. C becomes 1, and A becomes 1.

Sample Input 2

3 1 0 0
AB
BC
AB

Sample Output 2

No

Sample Input 3

1 0 9 0
AC

Sample Output 3

No

Sample Input 4

8 6 9 1
AC
BC
AB
BC
AC
BC
AB
AB

Sample Output 4

Yes
C
B
B
C
C
B
A
A

Solution in C++ (GCC 9.2.1) (judge verdict: Accepted)

#define LOCAL
#define _USE_MATH_DEFINES
#include <array>
#include <cassert>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <iomanip>
#include <string>
#include <sstream>
#include <vector>
#include <queue>
#include <stack>
#include <list>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>
#include <complex>
#include <cmath>
#include <numeric>
#include <bitset>
#include <functional>
#include <random>
#include <ctime>

using namespace std;

template <typename A, typename B>
ostream& operator <<(ostream& out, const pair<A, B>& a) {
  out << "(" << a.first << "," << a.second << ")";
  return out;
}
template <typename T, size_t N>
ostream& operator <<(ostream& out, const array<T, N>& a) {
  out << "["; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]";
  return out;
}
template <typename T>
ostream& operator <<(ostream& out, const vector<T>& a) {
  out << "["; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "]";
  return out;
}
template <typename T, class Cmp>
ostream& operator <<(ostream& out, const set<T, Cmp>& a) {
  out << "{"; bool first = true;
  for (auto& v : a) { out << (first ? "" : ", "); out << v; first = 0;} out << "}";
  return out;
}
template <typename U, typename T, class Cmp>
ostream& operator <<(ostream& out, const map<U, T, Cmp>& a) {
  out << "{"; bool first = true;
  for (auto& p : a) { out << (first ? "" : ", "); out << p.first << ":" << p.second; first = 0;} out << "}";
  return out;
}
#ifdef LOCAL
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
#define trace(...) 42
#endif
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << ": " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << ": " << arg1 << " |";
  __f(comma + 1, args...);
}

typedef long long int64;
typedef pair<int, int> ii;
const int INF = 1 << 29;
const int MOD = 1e9 + 7;
mt19937 mrand(random_device{}());
int rnd(int x) { return mrand() % x; }

struct fast_ios {
  fast_ios() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);
  };
} fast_ios_;

const int N = 1e5 + 10;
const int K = 3;
const int M = K * K * K;
bool dp[N][M];
ii rec[N][M];

int main() {
  int n;
  int A, B, C;
  scanf("%d%d%d%d", &n, &A, &B, &C);
  A = min(A, K - 1); B = min(B, K - 1); C = min(C, K - 1);
  dp[0][A + B * K + C * K * K] = true;
  char s[10];
  for (int i = 1; i <= n; ++i) {
    scanf("%s", s);
    auto& e = dp[i];
    auto& pre = rec[i];
    if (string(s) == "AB") {
      for (int k = 0; k < M; ++k) {
        if (!dp[i - 1][k]) continue;
        A = k % K; B = k / K % K; C = k / (K * K);
        if (A - 1 >= 0) {
          e[(A - 1) + min(B + 1, K - 1) * K + C * K * K] = true;
          pre[(A - 1) + min(B + 1, K - 1) * K + C * K * K] = {k, 1};
        }
        if (B - 1 >= 0) {
          e[min(A + 1, K - 1) + (B - 1) * K + C * K * K] = true;
          pre[min(A + 1, K - 1) + (B - 1) * K + C * K * K] = {k, 0};
        }
      }
    } else if (string(s) == "BC") {
      for (int k = 0; k < M; ++k) {
        if (!dp[i - 1][k]) continue;
        A = k % K; B = k / K % K; C = k / (K * K);
        if (B - 1 >= 0) {
          e[A + (B - 1) * K + min(C + 1, K - 1) * K * K] = true;
          pre[A + (B - 1) * K + min(C + 1, K - 1) * K * K] = {k, 2};
        }
        if (C - 1 >= 0) {
          e[A + min(B + 1, K - 1) * K + (C - 1) * K * K] = true;
          pre[A + min(B + 1, K - 1) * K + (C - 1) * K * K] = {k, 1};
        }
      }
    } else {
      for (int k = 0; k < M; ++k) {
        if (!dp[i - 1][k]) continue;
        A = k % K; B = k / K % K; C = k / (K * K);
        if (C - 1 >= 0) {
          e[min(A + 1, K - 1) + B * K + (C - 1) * K * K] = true;
          pre[min(A + 1, K - 1) + B * K + (C - 1) * K * K] = {k, 0};
        }
        if (A - 1 >= 0) {
          e[(A - 1) + B * K + min(C + 1, K - 1) * K * K] = true;
          pre[(A - 1) + B * K + min(C + 1, K - 1) * K * K] = {k, 2};
        }
      }
    }
  }
  int best_k = -1;
  for (int k = 0; k < M; ++k) if (dp[n][k]) best_k = k;
  if (best_k < 0) {
    puts("No");
  } else {
    puts("Yes");
    string ret;
    int k = best_k;
    for (int i = n; i >= 1; --i) {
      // trace(i, k, dp[i][k], rec[i][k]);
      ret += (char)('A' + rec[i][k].second);
      k = rec[i][k].first;
    }
    // trace(k);
    reverse(ret.begin(), ret.end());
    for (auto& c : ret) {
      printf("%c\n", c);
    }
  }
  return 0;
}