Problem: Vasya has a multiset s consisting of n integer numbers. Vasya calls some number x nice if it appears in the multiset exactly once. For example, multiset \{1, 1, 2, 3, 3, 3, 4\} contains nice numbers 2 and 4.

Vasya wants to split multiset s into two multisets a and b (one of which may be empty) in such a way that the quantity of nice numbers in multiset a would be the same as the quantity of nice numbers in multiset b (the quantity of numbers to appear exactly once in multiset a and the quantity of numbers to appear exactly once in multiset b).

Input

The first line contains a single integer n~(2 ≤ n ≤ 100).

The second line contains n integers s_1, s_2, ... s_n~(1 ≤ s_i ≤ 100) — the multiset s.

Output

If there exists no split of s to satisfy the given requirements, then print "NO" in the first line.

Otherwise print "YES" in the first line.

The second line should contain a string, consisting of n characters. i-th character should be equal to 'A' if the i-th element of multiset s goes to multiset a and 'B' if if the i-th element of multiset s goes to multiset b. Elements are numbered from 1 to n in the order they are given in the input.

If there exist multiple solutions, then print any of them.

Examples

Input

4
3 5 7 1


Output

YES
BABA


Input

3
3 5 1


Output

NO

Solution (in JAVA):

Solution:
var len = +readline();
var originSet = readline().split(' ');

var countMap = {}
originSet.forEach((num) => {
    if (!countMap[num]) {
        countMap[num] = 0;
    }
    countMap[num]++;
});

var niceGroupIndex = 0;
var niceDiff = 0;

var groupLabel = ['A', 'B'];
var label = groupLabel[0];

var result = [];
var isGood = {};
var goodCount = 0;
var labelForNum = {}
originSet.forEach((num, index) => {
    if (countMap[num] === 1) {
        result.push(label);
        // nice
        var group = niceGroupIndex % 2;
        niceDiff += group === 0 ? 1 : -1;

        niceGroupIndex++;

        group = niceGroupIndex % 2;
        label = groupLabel[group];
    } else {
        if (!labelForNum[num]) {
            labelForNum[num] = label;
        }
        result.push(labelForNum[num] ? labelForNum[num] : label);
    }
    if (countMap[num] > 2 && !isGood[num]) {
        isGood[num] = true;
        goodCount++;
    }
});
labelForNum = null;

if (niceDiff === 0) {
    print('YES');
    print(result.join(''));
} else {
    var rest = Math.abs(niceDiff)
    if (rest <= goodCount) {
        print('YES');
        var labelNeeded = niceDiff < 0 ? 'A' : 'B';
        for (var i = 0, len = originSet.length; i < len; i++) {
            var num = originSet[i];
            if (labelNeeded !== result[i]) {
                if (countMap[num] === 1 && rest >= 2) {
                    result[i] = labelNeeded;
                    rest -= 2;
                } else if (isGood[num]) {
                    result[i] = labelNeeded;
                    isGood[num] = false;
                    rest--;
                }
            }
            if (rest === 0) {
                break;
            }
        }
        if (rest !== 0) {
            var replaceMap = {};
            var replaceLabel = labelNeeded === 'A' ? 'B' : 'A';
            for (var i = 0, len = originSet.length; i < len; i++) {
                var num = originSet[i];
                if (replaceMap[num]) {
                    result[i] = replaceLabel;
                }
                if (labelNeeded === result[i] && rest > 0 && countMap[num] > 2) {
                    replaceMap[num] = true;
                    rest--;
                }
            }
        }
        print(result.join(''));
    } else {
        print('NO');
    }
}