#include <bits/stdc++.h>
template <typename Ty>
inline Ty min(const Ty& a, const Ty& b) {
  return a < b ? a : b;
}
template <typename Ty>
inline Ty max(const Ty& a, const Ty& b) {
  return a > b ? a : b;
}
template <typename Ty>
inline void cmax(Ty& a, const Ty& b) {
  if (b > a) a = b;
}
template <typename Ty>
inline void cmin(Ty& a, const Ty& b) {
  if (b < a) a = b;
}
template <typename Ty>
inline void swap(Ty& a, Ty& b) {
  Ty t = a;
  a = b;
  b = t;
}
template <typename Ty>
inline void swap(Ty*& a, Ty*& b) {
  Ty* t = a;
  a = b;
  b = t;
}
namespace io {
const int MaxBuff = 1 << 15;
const int MaxOut = 1 << 24;
char b[MaxBuff], *S = b, *T = b;
inline char getc() {
  return S == T && (T = (S = b) + fread(b, 1, MaxBuff, stdin), S == T) ? 0
                                                                       : *S++;
}
inline int in() {
  char ch;
  int ans = 0;
  bool neg = 0;
  while (ch = getc(), (ch < '0' || ch > '9') && ch != '-')
    ;
  ch == '-' ? neg = 1 : ans = ch - '0';
  while (ch = getc(), '0' <= ch && ch <= '9') ans = ans * 10 + ch - '0';
  return neg ? -ans : ans;
}
inline int gets(char* s) {
  char* iter = s;
  while (*iter = getc(), *iter == ' ' || *iter == '\n' || *iter == '\r')
    ;
  while (*++iter = getc(),
         *iter && *iter != ' ' && *iter != '\n' && *iter != '\r')
    ;
  *iter = 0;
  return iter - s;
}
char buff[MaxOut], *iter = buff;
inline void pc(char s) { *iter++ = s; }
inline void fflush() { fwrite(buff, 1, iter - buff, stdout); }
}  // namespace io
using io::pc;
class DSU {
 private:
  int f[401];

 public:
  inline void init(int n) {
    for (int i = 0; i <= n; ++i) f[i] = i;
  }
  inline int find(int x) {
    while (x != f[x]) x = f[x] = f[f[x]];
    return x;
  }
  inline void merge(int x, int y) { f[find(x)] = find(y); }
} dsu;
class Matroid {
 private:
  const int fx[4] = {-1, 0, 0, 1};
  const int fy[4] = {0, -1, 1, 0};
  struct tuple {
    int x, y;
  };
  int n0, n1, n, m, demands;
  int count[801], dist[801], prev[801], que[801];
  bool vis[805], ok1[801], ok2[801];
  char grid[21][21], ans[41][41];
  tuple E[801];
  inline void get_edges(int i, int j) {
    for (int k = 0; k < 4; ++k) {
      int u = i + fx[k], v = j + fy[k];
      if ((u >= 0 && u < n0) && (v >= 0 && v < n1) && grid[u][v] == 'O')
        E[m++] = ((tuple){((i)*n1 + j), ((u)*n1 + v)});
    }
  }
  void debugPlan(int* prev, int u) {
    for (int i = 0; i < n0 * 2 - 1; ++i)
      for (int j = 0; j < n1 * 2 - 1; ++j) ans[i][j] = ' ';
    for (int i = 0; i < n0; ++i)
      for (int j = 0; j < n1; ++j)
        ans[i * 2][j * 2] = ((i + j) > 0 && (i + j) % 2 == 0)
                                ? ('0' + count[((i)*n1 + j)])
                                : '?';
    for (int i = 0; i < m; ++i)
      if (vis[i]) {
        int s = min(E[i].x, E[i].y);
        int s1 = max(E[i].x, E[i].y);
        if (s + 1 == s1)
          ans[s / n1 * 2][s % n1 * 2 + 1] = '-';
        else
          ans[s / n1 * 2 + 1][s % n1 * 2] = '|';
      }
    for (; ~u; u = prev[u]) {
      printf("%d %d %d\n", u, E[u].x, E[u].y);
      int s = min(E[u].x, E[u].y);
      int s1 = max(E[u].x, E[u].y);
      char symbol = vis[u] ? '#' : '%';
      if (s + 1 == s1)
        ans[s / n1 * 2][s % n1 * 2 + 1] = symbol;
      else
        ans[s / n1 * 2 + 1][s % n1 * 2] = symbol;
    }
    for (int i = 0; i < n0 * 2 - 1; ++i, putchar('\n'))
      for (int j = 0; j < n1 * 2 - 1; ++j) putchar(ans[i][j]);
    putchar('\n');
  }
  bool augument() {
    dsu.init(n);
    memset(count, 0, sizeof(count));
    memset(dist, -1, sizeof(dist));
    for (int i = 0; i < m; ++i)
      if (vis[i]) {
        dsu.merge(E[i].x, E[i].y);
        ++count[E[i].x];
      }
    int tail = 0;
    for (int i = 0; i < m; ++i) {
      ok1[i] = !vis[i] && dsu.find(E[i].x) != dsu.find(E[i].y);
      ok2[i] = !vis[i] && count[E[i].x] < 2;
      if (ok1[i]) {
        dist[i] = 0, prev[i] = -1, que[tail++] = i;
        if (ok2[i]) {
          vis[i] = true;
          return true;
        }
      }
    }
    for (int head = 0; head < tail; ++head) {
      int u = que[head];
      if (ok2[u]) {
        while (~u) vis[u] ^= 1, u = prev[u];
        return true;
      }
      if (vis[u]) {
        dsu.init(n);
        for (int i = 0; i < m; ++i)
          if (vis[i] && i != u) dsu.merge(E[i].x, E[i].y);
        for (int v = 0; v < m; ++v)
          if (!vis[v] && dsu.find(E[v].x) != dsu.find(E[v].y) && dist[v] == -1)
            dist[v] = dist[u] + 1, prev[v] = u, que[tail++] = v;
      } else
        for (int v = 0; v < m; ++v)
          if (vis[v] && count[E[u].x] - (E[u].x == E[v].x) < 2 && dist[v] == -1)
            dist[v] = dist[u] + 1, prev[v] = u, que[tail++] = v;
    }
    return false;
  }

 public:
  void solve() {
    n0 = io::in(), n1 = io::in();
    for (int i = 0; i < n0; ++i) io::gets(grid[i]);
    n = n0 * n1, m = demands = 0;
    for (int i = 0; i < n0; ++i)
      for (int j = 0; j < n1; ++j)
        if (grid[i][j] == 'O' && ((i + j) > 0 && (i + j) % 2 == 0))
          demands += 2, get_edges(i, j);
    while (augument()) --demands;
    if (demands)
      pc('N'), pc('O'), pc('\n');
    else {
      pc('Y'), pc('E'), pc('S'), pc('\n');
      get_edges(0, 0);
      dsu.init(n);
      for (int t = 0; t < 2; ++t)
        for (int i = 0; i < m; ++i) {
          bool connected = dsu.find(E[i].x) == dsu.find(E[i].y);
          if (t && !connected) vis[i] = true;
          if (vis[i] && !connected) dsu.merge(E[i].x, E[i].y);
        }
      for (int i = 0; i < n0 * 2 - 1; ++i)
        for (int j = 0; j < n1 * 2 - 1; ++j) ans[i][j] = ' ';
      for (int i = 0; i < n0; ++i)
        for (int j = 0; j < n1; ++j) ans[i * 2][j * 2] = grid[i][j];
      for (int i = 0; i < m; ++i)
        if (vis[i]) {
          int s = min(E[i].x, E[i].y);
          int s1 = max(E[i].x, E[i].y);
          if (s + 1 == s1)
            ans[s / n1 * 2][s % n1 * 2 + 1] = 'i';
          else
            ans[s / n1 * 2 + 1][s % n1 * 2] = '!';
        }
      for (int i = 0; i < n0 * 2 - 1; ++i) {
        for (int j = 0; j < n1 * 2 - 1; ++j) pc(ans[i][j]);
        pc('\n');
      }
    }
  }
} stp[100];
int main() {
  int T = io::in();
  for (int i = 0; i < T; ++i) stp[i].solve();
  io::fflush();
  return 0;
}
