#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("fast-math")
#pragma GCC optimize("trapv")
#pragma GCC target("sse4")
using namespace std;
void __print(int x) { cerr << x; }
void __print(long x) { cerr << x; }
void __print(long long x) { cerr << x; }
void __print(unsigned x) { cerr << x; }
void __print(unsigned long x) { cerr << x; }
void __print(unsigned long long x) { cerr << x; }
void __print(float x) { cerr << x; }
void __print(double x) { cerr << x; }
void __print(long double x) { cerr << x; }
void __print(char x) { cerr << '\'' << x << '\''; }
void __print(const char* x) { cerr << '\"' << x << '\"'; }
void __print(const string& x) { cerr << '\"' << x << '\"'; }
void __print(bool x) { cerr << (x ? "true" : "false"); }
template <typename T, typename V>
void __print(const pair<T, V>& x) {
  cerr << '{';
  __print(x.first);
  cerr << ',';
  __print(x.second);
  cerr << '}';
}
template <typename T>
void __print(const T& x) {
  int f = 0;
  cerr << '{';
  for (auto& i : x) cerr << (f++ ? "," : ""), __print(i);
  cerr << "}";
}
void _print() { cerr << "]\n"; }
template <typename T, typename... V>
void _print(T t, V... v) {
  __print(t);
  if (sizeof...(v)) cerr << ", ";
  _print(v...);
}
void IO() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
}
long long int n, m;
long long int a[] = {3, 2, 1, 4};
long long int cost[] = {0, 3, 2, 1, 4};
vector<string> vs;
vector<vector<long long> > ansMain;
void invt(char& c) {
  if (c == '1')
    c = '0';
  else
    c = '1';
}
void addV(int j, int k, int cor) {
  vector<long long> ans;
  if (cor == 1) {
    ans.push_back(j);
    ans.push_back(k);
    invt(vs[j][k]);
    ans.push_back(j);
    ans.push_back(k + 1);
    invt(vs[j][k + 1]);
    ans.push_back(j + 1);
    ans.push_back(k);
    invt(vs[j + 1][k]);
  } else if (cor == 2) {
    ans.push_back(j);
    ans.push_back(k);
    invt(vs[j][k]);
    ans.push_back(j);
    ans.push_back(k + 1);
    invt(vs[j][k + 1]);
    ans.push_back(j + 1);
    ans.push_back(k + 1);
    invt(vs[j + 1][k + 1]);
  } else if (cor == 3) {
    ans.push_back(j);
    ans.push_back(k);
    invt(vs[j][k]);
    ans.push_back(j + 1);
    ans.push_back(k);
    invt(vs[j + 1][k]);
    ans.push_back(j + 1);
    ans.push_back(k + 1);
    invt(vs[j + 1][k + 1]);
  } else {
    ans.push_back(j + 1);
    ans.push_back(k + 1);
    invt(vs[j + 1][k + 1]);
    ans.push_back(j + 1);
    ans.push_back(k);
    invt(vs[j + 1][k]);
    ans.push_back(j);
    ans.push_back(k + 1);
    invt(vs[j][k + 1]);
  }
  ansMain.push_back(ans);
}
void make3(int j, int k) {
  vector<vector<long long> > ans;
  if (vs[j][k] == '1') {
    if (vs[j + 1][k] == vs[j][k + 1])
      addV(j, k, 1);
    else if (vs[j + 1][k] == '1')
      addV(j, k, 3);
    else
      addV(j, k, 2);
  } else {
    addV(j, k, 4);
  }
}
void make2(int j, int k) {
  if (vs[j][k] == vs[j + 1][k + 1]) {
    if (vs[j][k] == '1') {
      addV(j, k, 1);
      addV(j, k, 4);
    } else {
      addV(j, k, 2);
      addV(j, k, 3);
    }
  } else {
    for (int i1 = j; ((j < j + 1) ? (i1 <= j + 1) : (i1 >= j + 1));
         ((j < j + 1) ? ++i1 : --i1)) {
      for (int i2 = k; ((k < k + 1) ? (i2 <= k + 1) : (i2 >= k + 1));
           ((k < k + 1) ? ++i2 : --i2)) {
        long long int cor;
        if (i1 == j) {
          if (i2 == k)
            cor = 1;
          else
            cor = 2;
        } else {
          if (i2 == k)
            cor = 3;
          else
            cor = 4;
        }
        if (vs[i1][i2] == '0') {
          addV(j, k, cor);
          make3(j, k);
          return;
        }
      }
    }
  }
}
void make1(int j, int k) {
  if (vs[j][k] == '1' || vs[j + 1][k] == '1') {
    if (vs[j][k] == '1') addV(j, k, 2);
    if (vs[j + 1][k] == '1') addV(j, k, 4);
    make2(j, k);
  } else {
    if (vs[j][k + 1] == '1') addV(j, k, 1);
    if (vs[j + 1][k + 1] == '1') addV(j, k, 3);
    make2(j, k);
  }
}
void make4(int j, int k) {
  addV(j, k, 1);
  vs[j + 1][k + 1] = '1';
  make1(j, k);
}
void solve() {
  cin >> n >> m;
  vs.clear();
  ansMain.clear();
  vs.resize(n);
  for (int i = 0; ((0 < n - 1) ? (i <= n - 1) : (i >= n - 1));
       ((0 < n - 1) ? ++i : --i)) {
    cin >> vs[i];
  }
  if (n > 2) {
    for (int i = n - 1; ((n - 1 < 2) ? (i <= 2) : (i >= 2));
         ((n - 1 < 2) ? ++i : --i)) {
      for (int j = 0; j <= m - 3; j++) {
        if (vs[i][j] == '1') {
          addV(i - 1, j, 1);
        }
      }
      if (vs[i][m - 2] == vs[i][m - 1]) {
        if (vs[i][m - 2] == '1') {
          addV(i - 1, m - 2, 3);
        }
      } else {
        if (vs[i][m - 2] == '1') {
          addV(i - 1, m - 2, 1);
        } else {
          addV(i - 1, m - 2, 2);
        }
      }
    }
  }
  if (m > 2) {
    for (int j = m - 1; ((m - 1 < 2) ? (j <= 2) : (j >= 2));
         ((m - 1 < 2) ? ++j : --j)) {
      if (vs[0][j] == vs[1][j]) {
        if (vs[0][j] == '1') {
          addV(0, j - 1, 2);
        }
      } else {
        if (vs[0][j] == '1') {
          addV(0, j - 1, 1);
        } else {
          addV(0, j - 1, 3);
        }
      }
    }
  }
  long long int cnt = 0;
  for (int i = 0; ((0 < 1) ? (i <= 1) : (i >= 1)); ((0 < 1) ? ++i : --i)) {
    for (int j = 0; ((0 < 1) ? (j <= 1) : (j >= 1)); ((0 < 1) ? ++j : --j)) {
      if (vs[i][j] == '1') cnt++;
    }
  }
  if (cnt == 1) make1(0, 0);
  if (cnt == 2) make2(0, 0);
  if (cnt == 3) make3(0, 0);
  if (cnt == 4) make4(0, 0);
  cout << ansMain.size() << "\n";
  for (auto v : ansMain) {
    for (int i = 0; ((0 < 5) ? (i <= 5) : (i >= 5)); ((0 < 5) ? ++i : --i)) {
      cout << v[i] + 1 << " ";
    }
    cout << "\n";
  }
}
int main() {
  IO();
  int t = 1;
  cin >> t;
  while (t--) {
    solve();
  }
  return 0;
}
