#include <bits/stdc++.h>
using namespace std;
template <typename T>
T load() {
  T r;
  cin >> r;
  return r;
}
template <typename T>
vector<T> loadMany(int n) {
  vector<T> rs(n);
  generate(rs.begin(), rs.end(), &load<T>);
  return rs;
}
struct StrInt {
  StrInt(const string& ref) : ref(ref) {}
  int operator[](int i) const { return ref[i] - 'a'; }
  int size() const { return (int)ref.size(); }
  const string& ref;
};
struct Trans {
  explicit Trans(int k) : k(k), tab(k, -1), rev(k, -1) {}
  Trans() : tab() {}
  void add(int from, int to) {
    tab[from] = to;
    rev[to] = from;
  }
  int get(int i) { return tab[i]; }
  bool loose(int i) { return tab[i] == -1; }
  bool free(int j) { return rev[j] == -1; }
  bool anyRangeFree(int j1, int j2) {
    for (auto j = j1; j <= j2; ++j)
      if (free(j)) return true;
    return false;
  }
  int findRangeFree(int j1, int j2) {
    for (auto j = j1; j <= j2; ++j)
      if (free(j)) return j;
    return -1;
  }
  bool defined() { return not tab.empty(); }
  void fillWithAny() {
    auto j = 0;
    for (auto i = 0; i < k; ++i)
      if (loose(i)) {
        while (not free(j)) ++j;
        add(i, j);
      }
  }
  void print() {
    for (auto i = 0; i < k; ++i) cout << (char)('a' + tab[i]);
  }
  int k;
  vector<int> tab;
  vector<int> rev;
};
Trans solveA(int i, int k, StrInt s, StrInt a, Trans&& trans) {
  auto n = (int)s.size();
  if (trans.loose(s[i]) and trans.free(a[i]))
    trans.add(s[i], a[i]);
  else if (trans.loose(s[i]))
    return {};
  ++i;
  for (; i < n; ++i)
    if (trans.loose(s[i]) and trans.anyRangeFree(a[i] + 1, k - 1))
      return trans.add(s[i], trans.findRangeFree(a[i] + 1, k - 1)), move(trans);
    else if (trans.loose(s[i]) and trans.free(a[i]))
      trans.add(s[i], a[i]);
    else if (trans.loose(s[i]))
      return {};
    else if (trans.get(s[i]) > a[i])
      return move(trans);
    else if (trans.get(s[i]) < a[i])
      return {};
  return move(trans);
}
Trans solveB(int i, int, StrInt s, StrInt b, Trans&& trans) {
  auto n = (int)s.size();
  if (trans.loose(s[i]) and trans.free(b[i]))
    trans.add(s[i], b[i]);
  else if (trans.loose(s[i]))
    return {};
  ++i;
  for (; i < n; ++i)
    if (trans.loose(s[i]) and trans.anyRangeFree(0, b[i] - 1))
      return trans.add(s[i], trans.findRangeFree(0, b[i] - 1)), move(trans);
    else if (trans.loose(s[i]) and trans.free(b[i]))
      trans.add(s[i], b[i]);
    else if (trans.loose(s[i]))
      return {};
    else if (trans.get(s[i]) < b[i])
      return move(trans);
    else if (trans.get(s[i]) > b[i])
      return {};
  return move(trans);
}
Trans solve(int k, StrInt s, StrInt a, StrInt b) {
  auto n = s.size();
  auto trans = Trans(k);
  auto i = 0;
  for (; i < n; ++i)
    if (a[i] != b[i] and trans.loose(s[i]))
      break;
    else if (a[i] != b[i] and
             (a[i] < trans.get(s[i]) and trans.get(s[i]) < b[i]))
      return trans;
    else if (a[i] != b[i] and a[i] == trans.get(s[i]))
      return solveA(i, k, s, a, move(trans));
    else if (a[i] != b[i] and b[i] == trans.get(s[i]))
      return solveB(i, k, s, b, move(trans));
    else if (trans.loose(s[i]) and trans.free(a[i]))
      trans.add(s[i], a[i]);
    else if (trans.loose(s[i]))
      return {};
    else if (not(a[i] <= trans.get(s[i]) and trans.get(s[i]) <= b[i]))
      return {};
  if (i == n) return trans;
  if (trans.anyRangeFree(a[i] + 1, b[i] - 1))
    return trans.add(s[i], trans.findRangeFree(a[i] + 1, b[i] - 1)),
           move(trans);
  auto ans1 = solveA(i, k, s, a, Trans(trans));
  if (ans1.defined()) return ans1;
  auto ans2 = solveB(i, k, s, b, move(trans));
  return ans2;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  auto t = load<int>();
  while (t-- > 0) {
    auto k = load<int>();
    auto s = load<string>();
    auto a = load<string>();
    auto b = load<string>();
    auto ans = solve(k, s, a, b);
    if (ans.defined()) {
      ans.fillWithAny();
      cout << "YES\n";
      ans.print();
      cout << '\n';
    } else
      cout << "NO\n";
  }
}
