#include <bits/stdc++.h>
using namespace std;
const long long int MOD = 1000000007;
const long double PI = 2 * acos(0.0);
const vector<long long int> dx = {1, -1, 0, 0};
const vector<long long int> dy = {0, 0, 1, -1};
vector<long long int> ga(long long int n, bool oneIndexed = false) {
  vector<long long int> a;
  if (oneIndexed) a.push_back(0ll);
  for (long long int i = 0; i < n; i++) {
    long long int p;
    cin >> p;
    a.push_back(p);
  }
  return move(a);
}
vector<unsigned long long int> gau(unsigned long long int n,
                                   bool oneIndexed = false) {
  vector<unsigned long long int> a;
  if (oneIndexed) a.push_back(0llu);
  for (unsigned long long int i = 0; i < n; i++) {
    unsigned long long int p;
    cin >> p;
    a.push_back(p);
  }
  return move(a);
}
vector<string> gas(unsigned long long int n, bool oneIndexed = false) {
  vector<string> a;
  if (oneIndexed) a.push_back("");
  for (unsigned long long int i = 0; i < n; i++) {
    string p;
    cin >> p;
    a.push_back(p);
  }
  return move(a);
}
template <typename T, typename A>
void pa(vector<T, A> const &a, long long int begin = 0,
        long long int end = -1) {
  if (end == -1) end = (long long int)a.size() - 1;
  for (long long int i = begin; i <= end; i++) {
    cout << a[i] << " ";
  }
  cout << "\n";
}
template <typename T, typename A>
void papair(vector<T, A> const &a, long long int begin = 0,
            long long int end = -1) {
  if (end == -1) end = (long long int)a.size() - 1;
  for (long long int i = begin; i <= end; i++) {
    cout << a[i].first << " " << a[i].second << "\n";
  }
  cout << "\n";
}
void yes() { cout << "YES\n"; }
void no() { cout << "NO\n"; }
void yesno(int f) {
  if (f)
    yes();
  else
    no();
}
void solve() {
  long long int n, m;
  cin >> n >> m;
  vector<string> grid = gas(n);
  vector<set<long long int>> adjList(200);
  long long int largestchar = 0;
  set<long long int> charsused;
  map<long long int, vector<long long int>> coords;
  vector<long long int> spottedrow(200, -1), spottedcol(200, -1);
  vector<long long int> spottedrowcount(200, 0), spottedcolcount(200, 0);
  for (long long int i = 0; i < n; i++) {
    for (long long int j = 0; j < m; j++) {
      char c = grid[i][j];
      if (c != '.') {
        charsused.insert(c);
        if (spottedcol[c] != j) spottedcolcount[c]++;
        spottedcol[c] = j;
        if (spottedrow[c] != i) spottedrowcount[c]++;
        spottedrow[c] = i;
        if (spottedcolcount[c] >= 2 && spottedrowcount[c] >= 2) {
          no();
          return;
        };
      }
    }
  }
  if ((long long int)charsused.size() == 0) {
    yes();
    cout << 0 << "\n";
    return;
  }
  vector<long long int> indeg(200, 0);
  for (auto ch : charsused) {
    long long int spots = 0,
                  count = max(spottedcolcount[ch], spottedrowcount[ch]), ch2;
    if (spottedcolcount[ch] > spottedrowcount[ch]) {
      long long int row = spottedrow[ch], col = spottedcol[ch], first = col;
      while (spots < count) {
        ch2 = grid[row][col];
        if (ch2 == '.') {
          no();
          return;
        };
        if (ch2 != ch) {
          adjList[ch].insert(ch2);
        } else
          spots++;
        col--;
      }
      long long int last = col + 1;
      coords[ch] = {row, last, row, first};
    } else {
      long long int row = spottedrow[ch], col = spottedcol[ch],
                    first = spottedrow[ch];
      while (spots < count) {
        ch2 = grid[row][col];
        if (ch2 == '.') {
          no();
          return;
        };
        if (ch2 != ch) {
          adjList[ch].insert(ch2);
        } else
          spots++;
        row--;
      }
      long long int last = row + 1;
      coords[ch] = {last, col, first, col};
    }
  }
  for (auto ch : charsused) {
    for (auto neigh : adjList[ch]) indeg[neigh]++;
  }
  priority_queue<long long int, vector<long long int>, greater<long long int>>
      degrees;
  for (auto ch : charsused)
    if (!indeg[ch]) degrees.push(ch);
  vector<long long int> toposort = {};
  while (!degrees.empty()) {
    auto node = degrees.top();
    degrees.pop();
    toposort.push_back(node);
    for (auto neigh : adjList[node]) {
      indeg[neigh]--;
      if (!indeg[neigh]) degrees.push(neigh);
    }
  }
  if ((long long int)toposort.size() != (long long int)charsused.size()) {
    no();
    return;
  };
  for (long long int i = 1; i < (long long int)toposort.size(); i++) {
    if (toposort[i] < toposort[i - 1]) {
      no();
      return;
    };
  }
  yes();
  long long int largest = *max_element(charsused.begin(), charsused.end());
  cout << largest - 'a' + 1 << "\n";
  long long int curr = 'a';
  for (auto ch : toposort) {
    while (curr <= ch) {
      for (auto x : coords[ch]) cout << x + 1 << " ";
      cout << "\n";
      curr++;
    }
  }
}
int main(void) {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  long long int t;
  cin >> t;
  while (t--) solve();
  return 0;
}
