#include <bits/stdc++.h>
using namespace std;
int n, m;
vector<pair<pair<int, int>, pair<int, int> > > ans;
bool invert;
void print(vector<vector<string> > &mat) {
  for (auto vs : mat) {
    for (string s : vs) {
      printf("|%6s| ", s.c_str());
    }
    cout << endl;
  }
}
void move(int si, int sj, int ti, int tj) {
  assert(si != ti || sj != tj);
  if (si != ti && sj != tj) {
    move(si, sj, si, tj);
    move(si, tj, ti, tj);
  } else
    ans.push_back({{si + 1, sj + 1}, {ti + 1, tj + 1}});
}
void clean(vector<vector<string> > &mat, int i, int j) {
  if (invert) reverse(mat[i][j].begin(), mat[i][j].end());
  for (char c : mat[i][j]) {
    if (c == '1') {
      move(i, j, 0, 1);
      mat[0][1].push_back(c);
    }
    if (c == '0') {
      move(i, j, 0, 0);
      mat[0][0].push_back(c);
    }
  }
  mat[i][j].clear();
}
void simulate(vector<vector<string> > mat) {
  printf("\npart 1:\n");
  print(mat);
  int cnt = 0;
  int n = ans.size();
  assert(!ans.empty());
  for (auto p : ans) {
    int si = p.first.first - 1;
    int sj = p.first.second - 1;
    int ti = p.second.first - 1;
    int tj = p.second.second - 1;
    assert(!mat[si][sj].empty());
    char c = mat[si][sj].back();
    mat[si][sj].pop_back();
    string aux;
    aux.push_back(c);
    mat[ti][tj] = aux + mat[ti][tj];
    cnt++;
    printf("step %d:\n", cnt);
    print(mat);
    if (2 * cnt == n) printf("\npart 2\n");
  }
}
void go(vector<vector<string> > &mat) {
  string z0, z1, o0, o1;
  if (invert) {
    reverse(mat[0][0].begin(), mat[0][0].end());
    reverse(mat[0][1].begin(), mat[0][1].end());
  }
  for (char c : mat[0][0]) {
    if (c == '0')
      z0.push_back(c), move(0, 0, 1, 0);
    else
      o0.push_back(c), move(0, 0, 0, 1);
  }
  for (char c : mat[0][1]) {
    if (c == '0')
      z1.push_back(c), move(0, 1, 0, 0);
    else
      o1.push_back(c), move(0, 1, 1, 1);
  }
  if (invert) {
    mat[1][0] = z0 + mat[1][0];
    mat[1][1] = o1 + mat[1][1];
  } else {
    mat[1][0] = mat[1][0] + z0;
    mat[1][1] = mat[1][1] + o1;
  }
  mat[0][0] = z1;
  mat[0][1] = o0;
  for (int i = 0; (i) < int(n); (i)++) {
    if (i == 0) continue;
    string aux;
    if (invert) reverse(mat[i][0].begin(), mat[i][0].end());
    for (char c : mat[i][0]) {
      if (c == '0') {
        move(i, 0, 0, 0);
        mat[0][0].push_back(c);
      } else {
        aux.push_back(c);
        move(i, 0, i, 1);
      }
    }
    if (invert)
      mat[i][1] = aux + mat[i][1];
    else
      mat[i][1] = mat[i][1] + aux;
    mat[i][0].clear();
  }
  for (int i = 0; (i) < int(n); (i)++)
    for (int j = 0; (j) < int(m); (j)++) {
      if (j == 0) continue;
      if (i == 0 && j == 1) continue;
      clean(mat, i, j);
    }
}
vector<vector<string> > from, to;
int main() {
  while (cin >> n >> m) {
    from.resize(n);
    for (int i = 0; (i) < int(n); (i)++) {
      from[i].resize(m);
      for (int j = 0; (j) < int(m); (j)++) cin >> from[i][j];
    }
    to.resize(n);
    for (int i = 0; (i) < int(n); (i)++) {
      to[i].resize(m);
      for (int j = 0; (j) < int(m); (j)++) cin >> to[i][j];
    }
    vector<vector<string> > aux = from;
    invert = true;
    ans.clear();
    go(from);
    auto p1 = ans;
    invert = false;
    ans.clear();
    go(to);
    auto p2 = ans;
    for (auto &pp : p2) swap(pp.first, pp.second);
    reverse(p2.begin(), p2.end());
    ans = p1;
    ans.insert(ans.end(), p2.begin(), p2.end());
    printf("%d\n", int(ans.size()));
    for (auto pp : ans) {
      printf("%d %d %d %d\n", pp.first.first, pp.first.second, pp.second.first,
             pp.second.second);
    }
  }
  return 0;
}
