#include <bits/stdc++.h>
using namespace std;
const int Nmax = 2005;
bitset<Nmax> S[Nmax], nonS[Nmax];
string Str;
int need[Nmax][Nmax], sz[Nmax];
vector<pair<int, int> > edges;
queue<pair<int, int> > Q;
int n, m;
bool used[Nmax];
void Clear(int id, int x) {
  S[x][id] = 0;
  int i;
  for (i = 0; i < n; ++i)
    if (!S[i][id]) {
      --need[x][i];
      if (!used[x] && !used[i] && !need[x][i]) Q.push({x, i});
    }
}
void solve() {
  int i, j;
  cin >> n >> m;
  for (i = 0; i < n; ++i) S[i].reset(), nonS[i].reset(), used[i] = 0;
  edges.clear();
  for (i = 0; i < m; ++i) {
    cin >> Str;
    sz[i] = 0;
    for (j = 0; j < n; ++j)
      if (Str[j] == '1') ++sz[i];
    if (sz[i] == 1) {
      sz[i] = 0;
      continue;
    }
    for (j = 0; j < n; ++j)
      if (Str[j] == '1')
        S[j][i] = 1;
      else
        nonS[j][i] = 1;
  }
  for (i = 0; i < n; ++i)
    for (j = 0; j < n; ++j)
      if (i != j) need[i][j] = (S[i] & nonS[j]).count();
  for (i = 0; i < n; ++i)
    for (j = 0; j < n; ++j)
      if (i != j && !need[i][j]) Q.push({i, j});
  int x, y;
  while (Q.size()) {
    x = Q.front().first;
    y = Q.front().second;
    Q.pop();
    if (used[x] || used[y]) continue;
    edges.push_back({x + 1, y + 1});
    used[x] = 1;
    for (j = 0; j < m; ++j)
      if (S[x][j]) --sz[j];
    for (j = 0; j < m; ++j)
      if (sz[j] == 1) {
        Clear(j, y);
        sz[j] = 0;
      }
  }
  if (edges.size() != n - 1) {
    cout << "NO\n";
    return;
  }
  cout << "YES\n";
  for (auto it : edges) cout << it.first << ' ' << it.second << '\n';
}
int main() {
  cin.sync_with_stdio(false);
  int tests;
  cin >> tests;
  while (tests--) solve();
  return 0;
}
