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: Wrong Answer)

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

typedef long long ll;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;
typedef vector<vector<vector<ll>>> vvvll;
typedef vector<bool> vb;
typedef vector<vector<bool>> vvb;
typedef vector<vector<vector<bool>>> vvvb;
typedef pair<ll, ll> pll;
typedef vector<pll> vpll;
typedef vector<vpll> vvpll;
typedef vector<double> vd;
typedef vector<vd> vdd;

#define FOR(i,x,y) for(ll i=(ll)x; i<(ll)y; ++i)
#define REP(i,y) FOR(i, 0, y)
#define RFOR(i,x,y) for(ll i=(ll)x; i>=(ll)y; --i)
#define RREP(i,x) RFOR(i, x, 0)
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define debug_print(x...) cerr << "line " << __LINE__ << " : "; debug_print_in(x);

template <typename First>
void debug_print_in(First first){
  cerr << first << endl;
  return;
}

template <typename First, typename... Rest>
void debug_print_in(First first, Rest... rest){
  cerr << first << " ";
  debug_print_in(rest...);
  return;
}

void IN(void){
  return;
}

template <typename First, typename... Rest>
void IN(First& first, Rest&... rest){
  cin >> first;
  IN(rest...);
  return;
}

template <typename First>
void OUT(First first){
  cout << first << endl;
  return;
}

template <typename First, typename... Rest>
void OUT(First first, Rest... rest){
  cout << first << " ";
  OUT(rest...);
  return;
}

template<class t, class u> void chmax(t&a,u b){if(a<b)a=b;};
template<class t, class u> void chmin(t&a,u b){if(a>b)a=b;};
int popcount(int t){return __builtin_popcount(t);} //GCC
int popcount(ll t){return __builtin_popcountll(t);} //GCC

template <typename T>
void vec_print(vector<T> VEC){
  REP(i, VEC.size()){
    cerr << VEC[i] << " ";
  }
  cerr << endl;
};

template <typename T>
void mat_print(vector<vector<T> > MAT){
  REP(i,MAT.size()){
    REP(j,MAT[i].size()){
      cerr << MAT[i][j] << " ";
    }
    cerr << endl;
  }
};

constexpr int INF = (1<<30);
constexpr ll INFLL = 1LL<<62;
constexpr long double EPS = 1e-12;
constexpr ll MOD = (ll)((1E+9)+7);

ll N, A, B, C;
ll ABC;
vll s;
vvll dp;

void dp_search(ll index){
  if(index>=N){
    return;
  }
  if(s.at(index)==1){
    dp[index+1][0] = dp[index][5];
    dp[index+1][1] = dp[index][5];
    dp[index+1][2] = 0;
    dp[index+1][3] = dp[index][4];
    dp[index+1][4] = dp[index][3];
    dp[index+1][5] = dp[index][0] + dp[index][1];
  }else if(s.at(index)==2){
    dp[index+1][0] = dp[index][4];
    dp[index+1][1] = 0;
    dp[index+1][2] = dp[index][4];
    dp[index+1][3] = dp[index][5];
    dp[index+1][4] = dp[index][0] + dp[index][2];
    dp[index+1][5] = dp[index][3];
  }else if(s.at(index)==3){
    dp[index+1][0] = 0;
    dp[index+1][1] = dp[index][3];
    dp[index+1][2] = dp[index][3];
    dp[index+1][3] = dp[index][1] + dp[index][2];
    dp[index+1][4] = dp[index][5];
    dp[index+1][5] = dp[index][4];
  }
  dp_search(index+1);
  return;
}

vvll hoge = {
  {2, 0, 0},
  {0, 2, 0},
  {0, 0, 2},
  {0, 1, 1},
  {1, 0, 1},
  {1, 1, 0}
};

void rev(vvll& ans, ll index, ll state){
  ans.push_back(hoge.at(state));
  if(index<0) return;
  ll new_state = -1;
  if(s.at(index)==1){
    switch(state){
      case 0:
        new_state = 5;
        break;
      case 1:
        new_state = 5;
        break;
      case 2:
        break;
      case 3:
        new_state = 4;
        break;
      case 4:
        new_state = 3;
        break;
      case 5:
        if(dp.at(index).at(0)>0){
          new_state = 0;
        }else{
          new_state = 1;
        }
        break;
    }
  }else if(s.at(index)==2){
    switch(state){
      case 0:
        new_state = 4;
        break;
      case 1:
        break;
      case 2:
        new_state = 4;
        break;
      case 3:
        new_state = 5;
        break;
      case 4:
        if(dp.at(index).at(0)>0){
          new_state = 0;
        }else{
          new_state = 2;
        }
        break;
      case 5:
        new_state = 3;
        break;
    }
  }else{
    switch(state){
      case 0:
        break;
      case 1:
        new_state = 3;
        break;
      case 2:
        new_state = 3;
        break;
      case 3:
        if(dp.at(index).at(1)>0){
          new_state = 1;
        }else{
          new_state = 2;
        }
        break;
      case 4:
        new_state = 5;
        break;
      case 5:
        new_state = 4;
        break;
    }
  }

  rev(ans, index-1, new_state);
  return;
}

vvll search(void){
  dp_search(0);
  vvll ans(0);

  ll state = -1;
  REP(i,6){
    if(dp.at(N).at(i)>0) state = i;
  }

  if(state==-1) return ans;

  rev(ans, N-1, state);
  assert(ans.size()!=0);
  reverse(ALL(ans));

  return ans;
}

int main(){
  cin.tie(0); // cut the cin and cout (default, std::flush is performed after std::cin)
  ios::sync_with_stdio(false); // cut the iostream and stdio (DON'T endl; BUT "\n";)

  IN(N,A,B,C);

  ll A_init=A;
  ll B_init=B;
  ll C_init=C;

  ABC = A+B+C;
  // ABC = 1 -> do
  // ABC >= 3 -> go lower
  // ABC == 2 -> ?

  s.resize(N+1);
  dp.resize(N+1, vll(6, 0));

  if(A==2 && B==0 && C==0){
    dp[0][0] = 1;
  }else if(A==0 && B==2 && C==0){
    dp[0][1] = 1;
  }else if(A==0 && B==0 && C==2){
    dp[0][2] = 1;
  }else if(A==0 && B==1 && C==1){
    dp[0][3] = 1;
  }else if(A==1 && B==0 && C==1){
    dp[0][4] = 1;
  }else if(A==1 && B==1 && C==0){
    dp[0][5] = 1;
  }

  REP(i,N){
    string str;
    IN(str);
    if(str=="AB"){
      s[i] = 1;
    }else if(str=="AC"){
      s[i] = 2;
    }else{
      s[i] = 3;
    }
  }

  vll ans(N, -1);

  if(ABC<=1 || ABC>=3){
    REP(i,N){
      switch(s[i]){
        case 1:
          if(A==0 && B==0){
            OUT("No");
            return 0;
          }
          if(A>B){
            A--;
            B++;
            ans[i] = 1;
          }else{
            A++;
            B--;
            ans[i] = 0;
          }
          break;
        case 2:
          if(A==0 && C==0){
            OUT("No");
            return 0;
          }
          if(A>C){
            A--;
            C++;
            ans[i] = 2;
          }else{
            A++;
            C--;
            ans[i] = 0;
          }
          break;
        case 3:
          if(B==0 && C==0){
            OUT("No");
            return 0;
          }
          if(B>C){
            B--;
            C++;
            ans[i] = 2;
          }else{
            B++;
            C--;
            ans[i] = 1;
          }
      }
    }
  }else{
    vvll tmp = search();

    if(tmp.size()<=N){
      OUT("No");
      return 0;
    }
    //mat_print(dp);
    //mat_print(tmp);
    for(ll i=0; i<N; ++i){
      REP(j,3){
        if(tmp.at(i+1).at(j)-tmp.at(i).at(j)>0){
          ans[i] = j;
          break;
        }
      }
    }
  }

  printf("Yes\n");
  //debug_print(A_init, B_init, C_init);
  REP(i,N){
    if(ans[i]==0){
      printf("A\n");
      A_init++;
      if(s[i]==1) B_init--;
      else C_init--;
    }else if(ans[i]==1){
      printf("B\n");
      B_init++;
      if(s[i]==1) A_init--;
      else C_init--;
    }else if(ans[i]==2){
      printf("C\n");
      C_init++;
      if(s[i]==2) A_init--;
      else B_init--;
    }
    //debug_print(A_init, B_init, C_init);
  }

  return 0;
}