#include <bits/stdc++.h>
using namespace std;
template <typename T>
void debug_out(T t) {
  cerr << t;
}
template <typename A, typename B>
void debug_out(pair<A, B> u) {
  cerr << "(" << u.first << " " << u.second << ")";
}
template <typename T>
void debug_out(vector<T> t) {
  int sz = t.size();
  for (int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if (i != sz - 1) cerr << ", ";
  }
}
template <typename T>
void debug_out(vector<vector<T>> t) {
  int sz = t.size();
  for (int i = 0; i < sz; i++) {
    debug_out(t[i]);
    if (i != sz - 1) cerr << endl;
  }
}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  debug_out(H);
  cerr << " ";
  debug_out(T...);
}
template <typename T>
void debug_out(set<T> a) {
  vector<T> _a;
  for (T t : a) _a.push_back(t);
  debug_out(_a);
}
class dsu {
 public:
  vector<int> p;
  int n;
  dsu(int _n) : n(_n) {
    p.resize(n);
    iota(p.begin(), p.end(), 0);
  }
  inline int get(int x) { return (x == p[x] ? x : (p[x] = get(p[x]))); }
  inline bool unite(int x, int y) {
    x = get(x);
    y = get(y);
    if (x != y) {
      p[x] = y;
      return true;
    }
    return false;
  }
};
template <typename T, class F = function<T(const T&, const T&)>>
class SparseTable {
 public:
  int n;
  vector<vector<T>> mat;
  F func;
  SparseTable(){};
  SparseTable(const vector<T>& a, const F& f) : func(f) {
    n = static_cast<int>(a.size());
    int max_log = 32 - __builtin_clz(n);
    mat.resize(max_log);
    mat[0] = a;
    for (int j = 1; j < max_log; j++) {
      mat[j].resize(n - (1 << j) + 1);
      for (int i = 0; i <= n - (1 << j); i++) {
        mat[j][i] = func(mat[j - 1][i], mat[j - 1][i + (1 << (j - 1))]);
      }
    }
  }
  T get(int from, int to) const {
    assert(0 <= from && from <= to && to <= n - 1);
    int lg = 32 - __builtin_clz(to - from + 1) - 1;
    return func(mat[lg][from], mat[lg][to - (1 << lg) + 1]);
  }
};
class tree {
 public:
  ;
  int n;
  vector<vector<int>> gr;
  vector<int> in, out, tour, dep, was, to;
  SparseTable<int> st;
  tree(){};
  tree(int _n) {
    n = _n;
    gr.resize(n);
    in.resize(n);
    out.resize(n);
    dep.resize(n);
    was.resize(n);
    to.resize(n);
  }
  void add(int u, int v) {
    gr[u].push_back(v);
    gr[v].push_back(u);
  }
  void dfs(int v, int p, int root) {
    was[v] = 1;
    in[v] = tour.size();
    tour.push_back(v);
    if (~p) dep[v] = dep[p] + 1;
    to[v] = root;
    for (int i : gr[v]) {
      if (i == p) continue;
      dfs(i, v, root);
      tour.push_back(v);
    }
    out[v] = tour.size() - 1;
  }
  void prep() {
    for (int i = 0; i < n; i++)
      if (!was[i]) dfs(i, -1, i);
    st = SparseTable<int>(tour, [&](int x, int y) {
      return (dep[x] == dep[y] ? min(x, y) : (dep[x] > dep[y] ? y : x));
    });
  }
  int parent(int u, int v) {
    if (to[u] != to[v]) return -1;
    return st.get(min(in[u], in[v]), max(out[u], out[v]));
  }
};
int tt;
int main() {
  cin >> tt;
  for (int tc = 1; tc < tt + 1; tc++) {
    int n, m;
    cin >> n >> m;
    vector<vector<char>> grid(n, vector<char>(m));
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        cin >> grid[i][j];
      }
    }
    vector<int> dx = {0, 1};
    vector<int> dy = {1, 0};
    vector<vector<int>> edges;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        if (i + j == 0 || grid[i][j] == 'X') continue;
        for (int rot = 0; rot < 2; rot++) {
          int si = i + dx[rot], sj = j + dy[rot];
          if (si < 0 || si >= n || sj < 0 || sj >= m || grid[si][sj] == 'X')
            continue;
          edges.push_back({i, j, si, sj});
        }
      }
    }
    int sz = edges.size();
    vector<vector<int>> cnt(n, vector<int>(m));
    auto check = [&](int x, int y) {
      if (x + y == 0 || (x + y) & 1) return true;
      return cnt[x][y] <= 2;
    };
    tree st(n * m);
    st.prep();
    set<int> id;
    while (true) {
      vector<vector<int>> g(sz + 2);
      vector<int> re;
      for (int i = 0; i < sz; i++)
        if (id.find(i) == id.end()) re.push_back(i);
      for (int i : re) {
        int x = edges[i][0], y = edges[i][1], sx = edges[i][2],
            sy = edges[i][3];
        cnt[x][y]++;
        cnt[sx][sy]++;
        if (check(x, y) && check(sx, sy)) g[i + 1].push_back(sz + 1);
        cnt[x][y]--;
        cnt[sx][sy]--;
        int u = x * m + y, su = sx * m + sy;
        if (st.parent(u, su) == -1) g[0].push_back(i + 1);
        for (int j : id) {
          int a = edges[j][0], b = edges[j][1], sa = edges[j][2],
              sb = edges[j][3];
          int c = a * m + b, sc = sa * m + sb;
          if (st.parent(c, sc) == c) swap(c, sc);
          if ((st.parent(u, c) == c) ^ (st.parent(su, c) == c))
            g[j + 1].push_back(i + 1);
          cnt[a][b]--;
          cnt[sa][sb]--;
          cnt[x][y]++;
          cnt[sx][sy]++;
          if (check(a, b) && check(sa, sb) && check(x, y) && check(sx, sy))
            g[i + 1].push_back(j + 1);
          cnt[a][b]++;
          cnt[sa][sb]++;
          cnt[x][y]--;
          cnt[sx][sy]--;
        }
      }
      vector<int> que;
      vector<int> was(sz + 2);
      vector<int> par(sz + 2);
      was[0] = 1;
      que.push_back(0);
      for (int b = 0; b < (int)que.size(); b++) {
        for (int i : g[que[b]]) {
          if (was[i]) continue;
          que.push_back(i);
          par[i] = que[b];
          was[i] = 1;
        }
      }
      if (!was[sz + 1]) break;
      int cur = sz + 1;
      while (par[cur]) {
        if (id.find(par[cur] - 1) == id.end())
          id.insert(par[cur] - 1);
        else
          id.erase(par[cur] - 1);
        cur = par[cur];
      }
      st = tree(n * m);
      vector<vector<int>> new_cnt(n, vector<int>(m));
      for (int i : id) {
        int x = edges[i][0], y = edges[i][1], sx = edges[i][2],
            sy = edges[i][3];
        new_cnt[x][y]++;
        new_cnt[sx][sy]++;
        st.add(x * m + y, sx * m + sy);
      }
      st.prep();
      swap(cnt, new_cnt);
    }
    vector<vector<char>> res(2 * n - 1, vector<char>(2 * m - 1, ' '));
    int ans = 0;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        res[2 * i][2 * j] = grid[i][j];
        if (grid[i][j] == 'X' || i + j == 0 || (i + j) & 1) continue;
        ans++;
      }
    }
    assert((int)id.size() <= ans * 2);
    if ((int)id.size() < 2 * ans) {
      cout << "NO" << endl;
      continue;
    }
    dsu cp(n * m);
    for (int i : id) {
      int x = edges[i][0], y = edges[i][1], sx = edges[i][2], sy = edges[i][3];
      res[x + sx][y + sy] = (x != sx ? '|' : '-');
      cp.unite(x * m + y, sx * m + sy);
    }
    if (grid[0][1] != 'X') edges.insert(edges.begin(), {0, 0, 0, 1});
    if (grid[1][0] != 'X') edges.insert(edges.begin(), {0, 0, 1, 0});
    for (int i = 0; i < (int)edges.size(); i++) {
      int x = edges[i][0], y = edges[i][1], sx = edges[i][2], sy = edges[i][3];
      if (cp.unite(x * m + y, sx * m + sy))
        res[x + sx][y + sy] = (x != sx ? '|' : '-');
    }
    cout << "YES" << endl;
    for (auto i : res) {
      for (auto j : i) cout << j;
      cout << endl;
    }
  }
  return 0;
}
