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 Rust (1.42.0) (judge verdict: Accepted)

use std::io::{stdin, Read};

macro_rules! parse {
    ($it: ident ) => {};
    ($it: ident, ) => {};
    ($it: ident, $var:ident : $t:tt $($r:tt)*) => {
        let $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
    ($it: ident, mut $var:ident : $t:tt $($r:tt)*) => {
        let mut $var = parse_val!($it, $t);
        parse!($it $($r)*);
    };
}

macro_rules! parse_val {
    ($it: ident, [$t:tt; $len:expr]) => {
        (0..$len).map(|_| parse_val!($it, $t)).collect::<Vec<_>>();
    };
    ($it: ident, ($($t: ty),*)) => {
        ($(parse_val!($it, $t)),*)
    };
    ($it: ident, $t: ty) => {
        $it.next().unwrap().parse::<$t>().unwrap()
    };
}

fn solve(s: &str) {
    let mut it = s.split_whitespace();
    parse!(it, mut n: usize, a: usize, b: usize, c: usize);
    let mut s = [a, b, c];
    let abc = ["A", "B", "C"];
    let mut ret = vec![];
    let mut take = || match it.next().unwrap() {
        "AB" => (0, 1),
        "BC" => (1, 2),
        "AC" => (2, 0),
        _ => unreachable!(),
    };
    let m = s[0] + s[1] + s[2];
    let check = |s: [usize; 3]| assert!(s[0] <= m && s[1] <= m && s[2] <= m);
    while n > 0 {
        if s == [0, 1, 1] || s == [1, 1, 0] || s == [1, 0, 1] {
            break;
        }
        let (i, j) = take();
        n -= 1;
        if s[i] == s[j] && s[i] == 0 {
            println!("No");
            return;
        }
        if s[i] > s[j] {
            s[i] -= 1;
            s[j] += 1;
            ret.push(j);
        } else {
            s[j] -= 1;
            s[i] += 1;
            ret.push(i);
        }
        check(s);
    }

    while n > 1 {
        assert!(s == [0, 1, 1] || s == [1, 1, 0] || s == [1, 0, 1]);
        let (i, j) = take();
        n -= 1;
        if s[i] == 1 && s[j] == 1 {
            let (k, l) = take();
            n -= 1;
            if k != i && k != j {
                if i == l {
                    ret.push(i);
                    ret.push(k);
                    s[i] = 1;
                    s[j] = 0;
                    s[k] = 1;
                } else {
                    ret.push(j);
                    ret.push(k);
                    s[i] = 0;
                    s[j] = 1;
                    s[k] = 1;
                }
            } else if l != i && l != j {
                if i == k {
                    ret.push(i);
                    ret.push(l);
                    s[i] = 1;
                    s[j] = 0;
                    s[l] = 1;
                } else {
                    ret.push(j);
                    ret.push(l);
                    s[i] = 0;
                    s[j] = 1;
                    s[l] = 1;
                }
            } else {
                assert_eq!((i, j), (k, l));
                ret.push(i);
                ret.push(j);
            }
        } else {
            if s[i] > s[j] {
                s[i] -= 1;
                s[j] += 1;
                ret.push(j);
            } else {
                s[j] -= 1;
                s[i] += 1;
                ret.push(i);
            }
        }
        check(s);
    }

    if n == 1 {
        let (i, j) = take();
        if s[i] > s[j] {
            s[i] -= 1;
            s[j] += 1;
            ret.push(j);
        } else {
            s[j] -= 1;
            s[i] += 1;
            ret.push(i);
        }
        n -= 1;
    } else if n > 1 {
        unreachable!()
    }

    println!("Yes");
    for r in ret {
        println!("{}", abc[r]);
    }
}

fn main() {
    let mut s = String::new();
    stdin().read_to_string(&mut s).unwrap();
    solve(&s);
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn test_input() {
        let s = "
        ";
        solve(s);
    }
}