#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
 #define int long long

#define all(X) (X).begin(), (X).end()
#define reset(X) memset(X, 0, sizeof(X))
#define mp(a, b) make_pair(a, b)
#define pb push_back
#define endl '\n'
#define fi first
#define se second



using namespace __gnu_pbds;
using namespace std;
const int mod=1e9+7;
 // const int mod=998244353;
 // const int mod=1e9+9;
const int INF=4e18+10;
template <typename T>
using ordered_set = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;

#define read(n) int n; cin>>n;
#define readv(x, n) vector<int> x(n); for(auto &i:x) cin>>i; 
int multiply(int a, int b, int in_mod){return (a*b)%in_mod;} 
int mult_identity(int a){return 1;}


auto power(auto a, int b, int in_mod)
{
    auto prod=mult_identity(a);
    auto mult=a%in_mod;
    while(b!=0)
    {
        if(b%2)
        {
            prod=multiply(prod,mult, in_mod);

        }
        mult=multiply(mult, mult,in_mod);
        b/=2;
    }
    return prod;
}
int mod_inv(int q, int in_mod)
{

    return power(q, in_mod-2,in_mod);
}
int n;
vector<char> moves;
const int MAXN=2e5+100;
bool dp[6][2][2][MAXN];
int find(char a , char b)
{
    if(a=='A')
    {
        if(b=='B')
            return 0;
        else
        {
            return 1;
        }
        
    }
    if(a=='B')
    {
        if(b=='A')
            return 2;
        else
        {
            return 3;
        }
        
    }
    if(a=='C')
    {
        if(b=='B')
            return 4;
        else
        {
            return 5;
        }
        
    }
}
bool solving(int index, vector<pair<int, char>> triplet, const vector<string>& queries)
{
    if(triplet[0].fi<0 || triplet[1].fi<0 || triplet[2].fi<0)
        return false;
    if(index==n)
    {
        cout<<"Yes"<<endl;
        for(auto i:moves)
        {
            cout<<i<<endl;
        }
        return true;
    }
    //if altest 2 values greater than requires just brute

    vector<pair<int, int> > useful_double;
    for(auto &i:triplet)
    {
        for(auto j:queries[index])
        {
            if(j==i.se)
            {
                useful_double.pb({i.fi, i.se});
            }
        }
    }

    int cnt=0;
    for(auto i:triplet)
        if(i.fi>=2)
            cnt++;
    if(cnt>=2)
    {

    //just do what is needed
        if(useful_double[0]>useful_double[1])

            swap(useful_double[0], useful_double[1]);
        for(auto &i:triplet) 
        {
            if(i.se ==useful_double[0].se)
            {

                i.fi++;;
            }
        }

        for(auto &i:triplet) 
        {
            if(i.se ==useful_double[1].se)
            {

                i.fi--;;
            }
        }
        sort(all(triplet));
        moves.pb(useful_double[0].se);
        if(solving(index+1, triplet, queries))
            return true;
        moves.pop_back();

        assert(false);
        return true;

    }

     int indexe =find(triplet[1].se, triplet[2].se);

    // if(dp[indexe][triplet[0].fi][triplet[1].fi][triplet[2].fi])
    //     return false;
    //all three options
    //otherwise 2 cases :(

    for(auto &i:triplet) 
    {
        if(i.se ==useful_double[0].se)
        {

            i.fi--;;
        }
    }

    for(auto &i:triplet) 
    {
        if(i.se ==useful_double[1].se)
        {

            i.fi++;;
        }
    }
    sort(all(triplet));
    moves.pb(useful_double[1].se);
    if(solving(index+1, triplet, queries))
        return true;
    moves.pop_back();
    for(auto &i:triplet) 
    {
        if(i.se ==useful_double[0].se)
        {

            i.fi+=2;;
        }
    }

    for(auto &i:triplet) 
    {
        if(i.se ==useful_double[1].se)
        {

            i.fi-=2;;
        }
    }
    sort(all(triplet));
    moves.pb(useful_double[0].se);
    if(solving(index+1, triplet, queries))
        return true;
    
    moves.pop_back();

      for(auto &i:triplet) 
    {
        if(i.se ==useful_double[0].se)
        {

            i.fi--;;
        }
    }

    for(auto &i:triplet) 
    {
        if(i.se ==useful_double[1].se)
        {

            i.fi++;;
        }
    } 


    sort(all(triplet));
    indexe =find(triplet[1].se, triplet[2].se);
    dp[indexe][triplet[0].fi][triplet[1].fi][triplet[2].fi]=true;
    return false;
}


void solve()
{
    cin>>n;
    int a, b, c;
    cin>>a>>b>>c;
    //if altest 2 values great than 2 than yeas


    vector<string> queries;
    for(int i=0;i<n;i++)
    {
        string s;
        cin>>s;
        queries.pb(s);
    }
    //otherwise there can be issures
    vector<pair<int, char> > triplet;
    triplet.pb({a, 'A'});
    triplet.pb({b, 'B'});
    triplet.pb({c, 'C'});


    sort(all(triplet));
    triplet[2].fi = min(triplet[2].fi, MAXN-1);
    triplet[1].fi = min(triplet[1].fi, MAXN-1);
    triplet[0].fi = min(triplet[0].fi, MAXN-1);
    //solve using dp
    if(!solving(0, triplet, queries))
        cout<<"No"<<endl;
    
}



signed main()

{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);  
    cout.tie(NULL);
    #ifndef ONLINE_JUDGE
    if(fopen("INPUT.txt","r"))
    {
        freopen ("INPUT.txt" , "r" , stdin);
        freopen ("OUTPUT.txt" , "w" , stdout);
    }
    #endif
    auto clk=clock(); 
    mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
    // -------------------------------------Code starts here---------------------------------------------------------------------     

    int t=1;
    // cin>>t;
    for(int test=1;test<=t;test++)
    {
        // cout<<"Case #"<<test<<": ";
        solve();
        // cout<<endl;

    }

    // -------------------------------------Code ends here------------------------------------------------------------------


    clk = clock() - clk;
    cerr << fixed << setprecision(6) << "Time: " << ((double)clk)/CLOCKS_PER_SEC << "\n";
    return 0;
}


Measured memory_bytes: 33028