Vasya owns three strings s , a and b, each of them consists only of first k Latin letters.

Let a template be such a string of length k that each of the first k Latin letters appears in it exactly once (thus there are k! distinct templates). Application of template p to the string s is the replacement of each character in string s with p_i, i is the index of this letter in the alphabet. For example, applying template "bdca" to a string "aabccd" yields string "bbdcca".

Vasya wants to know if there exists such a template which yields a string lexicographically greater than or equal to string a and lexicographically less than or equal to string b after applying it to s.

If there exist multiple suitable templates, print any of them.

String a is lexicographically less than string b if there is some i (1 ≤ i ≤ n) that a_i < b_i and for any j (1 ≤ j < i) a_j = b_j.

You are required to answer t testcases independently.

Input

The first line contains a single integer t (1 ≤ t ≤ 10^6) — the number of testcases.

In hacks you can only use t = 1.

Each of the next t lines contains the description of the testcase in the following form:

The first line of the testcase contains a single integer k (1 ≤ k ≤ 26) — the length of the template.

The second line of the testcase contains the string s (1 ≤ |s| ≤ 10^6).

The third line of the testcase contains the string a.

The fourth line of the testcase contains the string b.

Strings s, a and b have the same length (|s| = |a| = |b|) and consist only of the first k Latin letters, all letters are lowercase.

It is guaranteed that string a is lexicographically less than or equal to string b.

It is also guaranteed that the total length of strings over all testcase won't exceed 3 ⋅ 10^6.

Output

Print the answers to all testcases in the following form:

If there exists no suitable template then print "NO" in the first line.

Otherwise print "YES" in the first line and the template itself in the second line (k lowercase letters, each of the first k Latin letters should appear exactly once).

If there exist multiple suitable templates, print any of them.

Example

Input

2
4
bbcb
aada
aada
3
abc
bbb
bbb


Output

YES
badc
NO
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Arrays;
/*
2
4
bbcb
aada
aada
3
abc
bbb
bbb


1
7
ggeefff
aabbfeg
aabbgef

1
7
ggeefff
aabbfgg
aabbgef

1
6
bcdfefdd
dbbccdef
dbcccbcb
 */
public class C2 {

	static int N,K;
	static char[] s,a,b;
	static boolean isMapped[];
	static int mapsTo[];
	
	public static void main(String args[]){
		new Thread(null, ()->asdf(args), "", 1<<28).start();
	}
	public static void asdf(String[] args) {
		JS in = new JS();
		PrintWriter out = new PrintWriter(System.out);
		
		int T = in.nextInt();
		for(int runs = 1; runs <= T; runs++) {
			K = in.nextInt();
			s = in.next().toCharArray();
			a = in.next().toCharArray();
			b = in.next().toCharArray();
			N = s.length;
			
			mapsTo = new int[K];
			isMapped = new boolean[K];

			Arrays.fill(mapsTo, -1);
			Arrays.fill(isMapped, false);
			//try going low then hi
			boolean b = loHi(0, false, false);
			if(b) {
				out.println("YES");
				ArrayDeque<Character> q = new ArrayDeque<Character>();
				for(int i = 0; i < K; i++) {
					if(!isMapped[i]) q.add((char)('a'+i));
				}
				
				char ar[] = new char[K];
				for(int i = 0; i < K; i++) {
					if(mapsTo[i] != -1) {
						ar[i] = (char)('a'+mapsTo[i]);
					}
					else {
						ar[i] = q.poll();
					}
				}
				for(int i = 0; i < K; i++) out.print(ar[i]);
				out.println();
				continue;
			}
			
			Arrays.fill(mapsTo, -1);
			Arrays.fill(isMapped, false);
			b = hiLo(0, false, false);
			if(b) {
				out.println("YES");
				ArrayDeque<Character> q = new ArrayDeque<Character>();
				for(int i = 0; i < K; i++) {
					if(!isMapped[i]) q.add((char)('a'+i));
				}
				
				char ar[] = new char[K];
				for(int i = 0; i < K; i++) {
					if(mapsTo[i] != -1) {
						ar[i] = (char)('a'+mapsTo[i]);
					}
					else {
						ar[i] = q.poll();
					}
				}
				for(int i = 0; i < K; i++) out.print(ar[i]);
				out.println();
				continue;
			}
			out.println("NO");
		}
		out.close();

	}
	
	static boolean loHi(int id, boolean greaterA, boolean lessB) {
		if(id >= N || (greaterA && lessB)) return true;
		int ss = s[id]-'a';
		int aa = a[id]-'a';
		int bb = b[id]-'a';
		if(mapsTo[ss] != -1) {
			//ss is already mapped
			if(mapsTo[ss] < aa && !greaterA) return false;
			if(mapsTo[ss] > bb && !lessB) return false;
			
			boolean gg = greaterA|mapsTo[ss] > aa;
			boolean ll = lessB|mapsTo[ss]<bb;
			return loHi(id+1, gg, ll);
		}
		else {
			//find something to map ss to
			if(!greaterA && !lessB) {
				//we are equal. Try to find something in the middle first
				for(int i = aa+1; i < bb; i++) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				//If something is not found, try endpoints. (Try lo first)
				if(isMapped[aa] && isMapped[bb]) return false;
				if(!isMapped[aa]) map(ss, aa);	
				else map(ss, bb);
				
				boolean gg = greaterA|mapsTo[ss] > aa;
				boolean ll = lessB|mapsTo[ss]<bb;
				return loHi(id+1, gg, ll);
			}
			else if(greaterA) {
				//try all values up to bb
				for(int i = 0; i < bb; i++) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				if(isMapped[bb]) return false;
				map(ss,bb);
				return loHi(id+1, greaterA, lessB);
			}
			else {
				//try all values down to aa
				for(int i = K-1; i > aa; i--) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				if(isMapped[aa]) return false;
				map(ss,aa);
				return loHi(id+1, greaterA, lessB);
			}
		}	
	}
	
	static void map(int a, int b) {
		mapsTo[a] = b;
		isMapped[b] = true;
	}
	static boolean hiLo(int id, boolean greaterA, boolean lessB) {
		if(id >= N || (greaterA && lessB)) return true;
		int ss = s[id]-'a';
		int aa = a[id]-'a';
		int bb = b[id]-'a';
		if(mapsTo[ss] != -1) {
			//ss is already mapped
			if(mapsTo[ss] < aa && !greaterA) return false;
			if(mapsTo[ss] > bb && !lessB) return false;
			
			boolean gg = greaterA|mapsTo[ss] > aa;
			boolean ll = lessB|mapsTo[ss]<bb;
			return hiLo(id+1, gg, ll);
		}
		else {
			//find something to map ss to
			if(!greaterA && !lessB) {
				//we are equal. Try to find something in the middle first
				for(int i = aa+1; i < bb; i++) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				//If something is not found, try endpoints. (Try hi first)
				if(isMapped[aa] && isMapped[bb]) return false;
				if(!isMapped[bb]) map(ss, bb);	
				else map(ss, aa);
				
				boolean gg = greaterA|mapsTo[ss] > aa;
				boolean ll = lessB|mapsTo[ss]<bb;
				return hiLo(id+1, gg, ll);
			}
			else if(greaterA) {
				//try all values up to bb
				for(int i = 0; i < bb; i++) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				if(isMapped[bb]) return false;
				map(ss, bb);
				return hiLo(id+1, greaterA, lessB);
			}
			else {
				//try all values down to aa
				for(int i = K-1; i > aa; i--) {
					if(!isMapped[i]) {
						map(ss, i);
						return true;
					}
				}
				if(isMapped[aa]) return false;
				map(ss,aa);
				return hiLo(id+1, greaterA, lessB);
			}
		}	
	}
	
	

	static class JS{
		public int BS = 1<<16;
		public char NC = (char)0;
		byte[] buf = new byte[BS];
		int bId = 0, size = 0;
		char c = NC;
		double num = 1;
		BufferedInputStream in;
		
		public JS() {
			in = new BufferedInputStream(System.in, BS);
		}
		
		public JS(String s) throws FileNotFoundException {
			in = new BufferedInputStream(new FileInputStream(new File(s)), BS);
		}
		
		public char nextChar(){
			while(bId==size) {
				try {
					size = in.read(buf);
				}catch(Exception e) {
					return NC;
				}				
				if(size==-1)return NC;
				bId=0;
			}
			return (char)buf[bId++];
		}
		
		public int nextInt() {
			return (int)nextLong();
		}
		
		public long nextLong() {
			num=1;
			boolean neg = false;
			if(c==NC)c=nextChar();
			for(;(c<'0' || c>'9'); c = nextChar()) {
				if(c=='-')neg=true;
			}
			long res = 0;
			for(; c>='0' && c <='9'; c=nextChar()) {
				res = (res<<3)+(res<<1)+c-'0';
				num*=10;
			}
			return neg?-res:res;
		}
		
		public double nextDouble() {
		    while(c!='.'&&c!='-'&&(c <'0' || c>'9')) c = nextChar();
		    boolean neg = c=='-';
		    if(neg)c=nextChar();
		    boolean fl = c=='.';
		    double cur = nextLong();
		    if(fl) return neg ? -cur/num : cur/num;
		    if(c == '.') {
			double next = nextLong();
			return neg ? -cur-next/num : cur+next/num;
		    }
		    else return neg ? -cur : cur;
		}
		
		public String next() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c>32) {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}
		
		public String nextLine() {
			StringBuilder res = new StringBuilder();
			while(c<=32)c=nextChar();
			while(c!='\n') {
				res.append(c);
				c=nextChar();
			}
			return res.toString();
		}

		public boolean hasNext() {
			if(c>32)return true;
			while(true) {
				c=nextChar();
				if(c==NC)return false;
				else if(c>32)return true;
			}
		}
	}
	
}
