#include <bits/stdc++.h>
#pragma GCC optimize("O3")
using namespace std;
template <class c>
struct rge {
  c h, n;
};
template <class c>
rge<c> range(c h, c n) {
  return rge<c>{h, n};
}
template <class c, class F>
struct rgm {
  c h, n;
  F f;
};
template <class c, class F>
rgm<c, F> map_range(c b, c e, F f) {
  return rgm<c, F>{b, e, f};
}
template <class c, class F>
rgm<typename c::const_iterator, F> map_range(const c &x, F f) {
  return map_range(x.begin(), x.end(), f);
}
template <class c>
auto dud(c *r) -> decltype(cerr << *r);
template <class c>
char dud(...);
struct muu {
  template <class c>
  muu &operator<<(const c &) {
    return *this;
  }
  muu &operator()() { return *this; }
};
const int nax = 1e6 + 44, A = 26;
char s[nax], a[nax], b[nax];
char per[A];
bool used[A];
int n, k;
void fill_any() {
  for (int i = 0; i < k; ++i)
    if (!used[i]) {
      (muu() << __FUNCTION__ << "#" << 67 << ": ")
          << (char)('a' + i) << " is unused";
      for (int j = 0; j < k; ++j)
        if (per[j] == -1) {
          per[j] = i;
          break;
        }
    }
}
bool can_a(int pos) {
  (muu() << __FUNCTION__ << "#" << 76 << ": ") << "["
                                                  "pos"
                                                  ": "
                                               << (pos) << "] ";
  if (pos == n) return true;
  if (per[s[pos]] != -1) {
    if (per[s[pos]] > a[pos])
      return true;
    else if (per[s[pos]] == a[pos])
      return can_a(pos + 1);
    else
      return false;
  }
  for (int j = a[pos] + 1; j < k; ++j)
    if (!used[j]) {
      per[s[pos]] = j;
      used[j] = true;
      return true;
    }
  if (used[a[pos]]) return false;
  per[s[pos]] = a[pos];
  used[a[pos]] = true;
  bool r = can_a(pos + 1);
  if (r) return true;
  per[s[pos]] = -1;
  used[a[pos]] = false;
  return false;
}
bool can_b(int pos) {
  (muu() << __FUNCTION__ << "#" << 102 << ": ") << "["
                                                   "pos"
                                                   ": "
                                                << (pos) << "] ";
  if (pos == n) return true;
  if (per[s[pos]] != -1) {
    (muu() << __FUNCTION__ << "#" << 105 << ": ")
        << "given " << (char)(s[pos] + 'a');
    if (per[s[pos]] < b[pos])
      return true;
    else if (per[s[pos]] == b[pos])
      return can_b(pos + 1);
    else
      return false;
  }
  for (int j = 0; j < b[pos]; ++j)
    if (!used[j]) {
      per[s[pos]] = j;
      used[j] = true;
      return true;
    }
  if (used[b[pos]]) return false;
  per[s[pos]] = b[pos];
  used[b[pos]] = true;
  bool r = can_b(pos + 1);
  if (r) return true;
  per[s[pos]] = -1;
  used[b[pos]] = false;
  return false;
}
bool can_both(int pos) {
  (muu() << __FUNCTION__ << "#" << 129 << ": ") << "["
                                                   "pos"
                                                   ": "
                                                << (pos) << "] ";
  if (pos == n) {
    return true;
  }
  if (per[s[pos]] != -1) {
    (muu() << __FUNCTION__ << "#" << 134 << ": ")
        << "found " << (char)(per[s[pos]] + 'a');
    if (per[s[pos]] < a[pos]) return false;
    if (per[s[pos]] > b[pos]) return false;
    if (per[s[pos]] == a[pos]) {
      if (per[s[pos]] == b[pos]) {
        (muu() << __FUNCTION__ << "#" << 139 << ": ") << "must fit both";
        return can_both(pos + 1);
      } else {
        (muu() << __FUNCTION__ << "#" << 142 << ": ") << "must fit a only";
        return can_a(pos + 1);
      }
    } else {
      if (per[s[pos]] == b[pos]) {
        (muu() << __FUNCTION__ << "#" << 147 << ": ") << "must fit b only";
        return can_b(pos + 1);
      } else {
        (muu() << __FUNCTION__ << "#" << 150 << ": ") << "fits automatically";
        return true;
      }
    }
  }
  for (int j = a[pos] + 1; j < b[pos]; ++j) {
    if (!used[j]) {
      (muu() << __FUNCTION__ << "#" << 157 << ": ")
          << (char)('a' + j) << " is good";
      per[s[pos]] = j;
      used[j] = true;
      return true;
    }
  }
  (muu() << __FUNCTION__ << "#" << 163 << ": ") << "no good found :(";
  if (a[pos] == b[pos]) {
    (muu() << __FUNCTION__ << "#" << 165 << ": ") << "must fit exactly";
    if (used[a[pos]]) {
      (muu() << __FUNCTION__ << "#" << 167 << ": ") << "is already used";
      return false;
    }
    per[s[pos]] = a[pos];
    used[a[pos]] = true;
    return can_both(pos + 1);
  } else {
    if (!used[a[pos]]) {
      (muu() << __FUNCTION__ << "#" << 175 << ": ")
          << "can try " << (char)('a' + a[pos]) << " from a";
      per[s[pos]] = a[pos];
      used[a[pos]] = true;
      bool r = can_a(pos + 1);
      if (r) {
        (muu() << __FUNCTION__ << "#" << 180 << ": ") << "succeed";
        return true;
      } else
        (muu() << __FUNCTION__ << "#" << 183 << ": ") << "failed";
      per[s[pos]] = -1;
      used[a[pos]] = false;
    }
    if (!used[b[pos]]) {
      (muu() << __FUNCTION__ << "#" << 188 << ": ")
          << "can try " << (char)('a' + b[pos]) << " from b";
      per[s[pos]] = b[pos];
      used[b[pos]] = true;
      bool r = can_b(pos + 1);
      if (r) {
        (muu() << __FUNCTION__ << "#" << 193 << ": ") << "succeed";
        return true;
      } else
        (muu() << __FUNCTION__ << "#" << 196 << ": ") << "failed";
      per[s[pos]] = -1;
      used[b[pos]] = false;
    }
  }
  return false;
}
void solve() {
  memset(used, 0, sizeof(used));
  memset(per, -1, sizeof(per));
  scanf("%d%s%s%s", &k, s, a, b);
  n = strlen(s);
  for (int i = 0; i < n; ++i) {
    a[i] -= 'a';
    b[i] -= 'a';
    s[i] -= 'a';
  }
  bool poss = can_both(0);
  if (poss) {
    (muu() << __FUNCTION__ << "#" << 215 << ": ")
        << map_range(per, per + k, [](muu &d, char c) {
             if (c == -1)
               d << "?";
             else
               d << (char)(c + 'a');
           });
    printf("YES\n");
    fill_any();
    for (int i = 0; i < k; ++i) putchar('a' + per[i]);
    printf("\n");
  } else {
    printf("NO\n");
  }
}
int main() {
  int t;
  scanf("%d", &t);
  while (t--) solve();
}
