← Home
package main

import (
	"bufio"
	"os"
)

type FastScanner struct {
	r *bufio.Reader
}

func NewFastScanner() *FastScanner {
	return &FastScanner{r: bufio.NewReaderSize(os.Stdin, 1<<20)}
}

func (fs *FastScanner) next() string {
	b, err := fs.r.ReadByte()
	for err == nil && (b == ' ' || b == '\n' || b == '\r' || b == '\t') {
		b, err = fs.r.ReadByte()
	}
	if err != nil {
		return ""
	}
	buf := make([]byte, 0, 16)
	for err == nil && b != ' ' && b != '\n' && b != '\r' && b != '\t' {
		buf = append(buf, b)
		b, err = fs.r.ReadByte()
	}
	return string(buf)
}

func parseInt(s string) int {
	sign := 1
	i := 0
	if len(s) > 0 && (s[0] == '-' || s[0] == '+') {
		if s[0] == '-' {
			sign = -1
		}
		i++
	}
	val := 0
	for i < len(s) {
		val = val*10 + int(s[i]-'0')
		i++
	}
	return sign * val
}

type state struct {
	f    []int
	used []bool
	i    int
	exL  bool
	exU  bool
}

func cloneIntSlice(a []int) []int {
	b := make([]int, len(a))
	copy(b, a)
	return b
}
func cloneBoolSlice(a []bool) []bool {
	b := make([]bool, len(a))
	copy(b, a)
	return b
}

func firstFreeGe(used []bool, from, k int) int {
	for y := from; y < k; y++ {
		if !used[y] {
			return y
		}
	}
	return -1
}
func lastFreeLe(used []bool, to int) int {
	for y := to; y >= 0; y-- {
		if !used[y] {
			return y
		}
	}
	return -1
}
func firstFree(used []bool, k int) int {
	for y := 0; y < k; y++ {
		if !used[y] {
			return y
		}
	}
	return -1
}
func firstFreeInRange(used []bool, l, r int) int {
	for y := l; y <= r; y++ {
		if !used[y] {
			return y
		}
	}
	return -1
}

func solveOne(k int, s, a, b string) (bool, string) {
	n := len(s)
	sb := []byte(s)
	ab := []byte(a)
	bb := []byte(b)

	f := make([]int, k)
	for i := range f {
		f[i] = -1
	}
	used := make([]bool, k)

	type Stack = []state
	var st Stack

	i := 0
	exL := true
	exU := true

	for {
		needBT := false
		for i < n {
			c := int(sb[i] - 'a')
			low := int(ab[i] - 'a')
			high := int(bb[i] - 'a')

			if f[c] != -1 {
				y := f[c]
				if exL && y < low {
					needBT = true
					break
				}
				if exU && y > high {
					needBT = true
					break
				}
				if exL && y > low {
					exL = false
				}
				if exU && y < high {
					exU = false
				}
				i++
				continue
			}

			if exL && exU {
				if low+1 <= high-1 {
					y := firstFreeInRange(used, low+1, high-1)
					if y != -1 {
						f[c] = y
						used[y] = true
						exL = false
						exU = false
						i++
						continue
					}
				}
				opts := make([]struct {
					y    int
					nL   bool
					nU   bool
					exst bool
				}, 0, 2)
				if !used[low] {
					opts = append(opts, struct {
						y    int
						nL   bool
						nU   bool
						exst bool
					}{y: low, nL: true, nU: low == high})
				}
				if high != low && !used[high] {
					opts = append(opts, struct {
						y    int
						nL   bool
						nU   bool
						exst bool
					}{y: high, nL: false, nU: true})
				}
				if len(opts) == 0 {
					needBT = true
					break
				}
				if len(opts) == 2 {
					af := cloneIntSlice(f)
					au := cloneBoolSlice(used)
					af[c] = opts[1].y
					au[opts[1].y] = true
					st = append(st, state{
						f:    af,
						used: au,
						i:    i + 1,
						exL:  opts[1].nL,
						exU:  opts[1].nU,
					})
				}
				f[c] = opts[0].y
				used[opts[0].y] = true
				exL = opts[0].nL
				exU = opts[0].nU
				i++
				continue
			}

			if exL {
				y := firstFreeGe(used, low, k)
				if y == -1 {
					needBT = true
					break
				}
				f[c] = y
				used[y] = true
				if y > low {
					exL = false
				}
				i++
				continue
			}

			if exU {
				y := lastFreeLe(used, high)
				if y == -1 {
					needBT = true
					break
				}
				f[c] = y
				used[y] = true
				if y < high {
					exU = false
				}
				i++
				continue
			}

			y := firstFree(used, k)
			if y == -1 {
				needBT = true
				break
			}
			f[c] = y
			used[y] = true
			i++
		}

		if needBT {
			if len(st) == 0 {
				return false, ""
			}
			last := st[len(st)-1]
			st = st[:len(st)-1]
			f = last.f
			used = last.used
			i = last.i
			exL = last.exL
			exU = last.exU
			continue
		}

		free := make([]int, 0, k)
		for y := 0; y < k; y++ {
			if !used[y] {
				free = append(free, y)
			}
		}
		ptr := 0
		for x := 0; x < k; x++ {
			if f[x] == -1 {
				f[x] = free[ptr]
				ptr++
			}
		}
		out := make([]byte, k)
		for x := 0; x < k; x++ {
			out[x] = byte('a' + f[x])
		}
		return true, string(out)
	}
}

func main() {
	in := NewFastScanner()
	out := bufio.NewWriterSize(os.Stdout, 1<<20)
	defer out.Flush()

	t := parseInt(in.next())
	for ; t > 0; t-- {
		k := parseInt(in.next())
		s := in.next()
		a := in.next()
		b := in.next()

		ok, tmpl := solveOne(k, s, a, b)
		if !ok {
			out.WriteString("NO\n")
		} else {
			out.WriteString("YES\n")
			out.WriteString(tmpl)
			out.WriteByte('\n')
		}
	}
}