using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("5");
WillReturn.Add("ABCBC");
WillReturn.Add("ACAAB");
//Yes
//AC..B
//.BA.C
//C.BA.
//BA.C.
//..CBA
}
else if (InputPattern == "Input2") {
WillReturn.Add("3");
WillReturn.Add("AAA");
WillReturn.Add("BBB");
//No
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static string mR;
static string mC;
static int UB;
static List<string> mStrList = new List<string>();
static void Main()
{
List<string> InputList = GetInputList();
mR = InputList[1];
mC = InputList[2];
UB = mR.Length - 1;
var CharList = new List<char>();
CharList.Add('A');
CharList.Add('B');
CharList.Add('C');
while (CharList.Count < mR.Length) {
CharList.Add('.');
}
foreach (char[] EachCharArr in RubyPatternClass<char>.Permutation(CharList, CharList.Count)) {
mStrList.Add(new string(EachCharArr));
}
mStrList = mStrList.Distinct().ToList();
//mStrList.ForEach(pX => Console.WriteLine(pX));
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
WillPush.SelectedIndList = new List<int>();
Stk.Push(WillPush);
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
int CurrY = Popped.SelectedIndList.Count;
if (CurrY > UB) {
// クリア判定
if (IsOK(Popped)) {
return;
}
continue;
}
for (int I = 0; I <= mStrList.Count - 1; I++) {
char FirstStrChar = GetFirstStrChar(mStrList[I]);
if (FirstStrChar != mR[CurrY]) {
continue; // 枝切り
}
WillPush.SelectedIndList = new List<int>(Popped.SelectedIndList);
WillPush.SelectedIndList.Add(I);
Stk.Push(WillPush);
}
}
Console.WriteLine("No");
}
struct JyoutaiDef
{
internal List<int> SelectedIndList;
}
// 文字列の最初の.以外の文字を返す
static char GetFirstStrChar(string pStr)
{
foreach (char EachChar in pStr) {
if (EachChar != '.') return EachChar;
}
return '?';
}
// クリア判定
static bool IsOK(JyoutaiDef pJyoutai)
{
char[,] BanArr = new char[UB + 1, UB + 1];
for (int Y = 0; Y <= UB; Y++) {
int CurrInd = pJyoutai.SelectedIndList[Y];
string CurrStr = mStrList[CurrInd];
for (int X = 0; X <= UB; X++) {
BanArr[X, Y] = CurrStr[X];
}
}
for (int X = 0; X <= UB; X++) {
if (IsOKEachCharCnt(X, BanArr) == false) return false;
}
for (int X = 0; X <= UB; X++) {
char FirstRetuChar = GetFirstRetuChar(X, BanArr);
if (FirstRetuChar != mC[X]) return false;
}
Console.WriteLine("Yes");
PrintBan(BanArr);
return true;
}
// X座標を引数として、列のA,B,Cが1個ずつかを返す
static bool IsOKEachCharCnt(int pX, char[,] pBanArr)
{
int ACnt = 0;
int BCnt = 0;
int CCnt = 0;
for (int Y = 0; Y <= UB; Y++) {
if (pBanArr[pX, Y] == 'A') ACnt++;
if (pBanArr[pX, Y] == 'B') BCnt++;
if (pBanArr[pX, Y] == 'C') CCnt++;
}
return ACnt == 1 && BCnt == 1 && CCnt == 1;
}
// X座標を引数として、列の最初のA,B,Cを返す
static char GetFirstRetuChar(int pX, char[,] pBanArr)
{
for (int Y = 0; Y <= UB; Y++) {
if (pBanArr[pX, Y] != '.') return pBanArr[pX, Y];
}
return '?';
}
////////////////////////////////////////////////////////////////
// 2次元配列(char型)のデバッグ出力
////////////////////////////////////////////////////////////////
static void PrintBan(char[,] pBanArr)
{
var sb = new System.Text.StringBuilder();
for (int Y = 0; Y <= pBanArr.GetUpperBound(1); Y++) {
for (int X = 0; X <= pBanArr.GetUpperBound(0); X++) {
sb.Append(pBanArr[X, Y]);
}
sb.AppendLine();
}
Console.Write(sb.ToString());
}
}
#region RubyPatternClass
// Rubyの場合の数
internal static class RubyPatternClass<Type>
{
// 順列を返す
private struct JyoutaiDef_Permutation
{
internal List<int> SelectedIndList;
}
internal static IEnumerable<Type[]> Permutation(IEnumerable<Type> pEnum, int pR)
{
if (pR == 0) yield break;
Type[] pArr = pEnum.ToArray();
if (pArr.Length < pR) yield break;
var Stk = new Stack<JyoutaiDef_Permutation>();
JyoutaiDef_Permutation WillPush;
for (int I = pArr.GetUpperBound(0); 0 <= I; I--) {
WillPush.SelectedIndList = new List<int>() { I };
Stk.Push(WillPush);
}
while (Stk.Count > 0) {
JyoutaiDef_Permutation Popped = Stk.Pop();
// クリア判定
if (Popped.SelectedIndList.Count == pR) {
var WillReturn = new List<Type>();
Popped.SelectedIndList.ForEach(X => WillReturn.Add(pArr[X]));
yield return WillReturn.ToArray();
continue;
}
for (int I = pArr.GetUpperBound(0); 0 <= I; I--) {
if (Popped.SelectedIndList.Contains(I)) continue;
WillPush.SelectedIndList = new List<int>(Popped.SelectedIndList) { I };
Stk.Push(WillPush);
}
}
}
}
#endregion