#include <bits/stdc++.h>
using namespace std;
int n, m;
struct point {
  int x, y;
  point() {}
  point(int _x, int _y) { x = _x % n, y = _y % m; }
};
string S[305][305], T[305][305];
int cnt[305][305];
string mp[305][305];
vector<pair<point, point>> ans;
void init() {
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) cin >> S[i][j];
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) cin >> T[i][j];
  for (int i = 0; i < n; ++i)
    for (int j = 0; j < m; ++j) mp[i][j] = S[i][j];
}
void move(point p1, point p2) {
  if (p1.x == p2.x && p1.y == p2.y) return;
  assert((p1.x == p2.x) ^ (p1.y == p2.y));
  ++cnt[p2.x][p2.y];
  ans.emplace_back(p1, p2);
}
void S_remove() {
  point fs(0, 0), ft(0, 1);
  for (int i = 0; i < n; ++i) {
    point s(i, 0), t(i, 1);
    for (auto it = S[i][0].rbegin(); it != S[i][0].rend(); ++it)
      if (*it == '0')
        move(s, point(i + 1, 0));
      else
        move(s, t);
    for (auto it = S[i][1].rbegin(); it != S[i][1].rend(); ++it)
      if (*it == '0')
        move(t, s);
      else
        move(t, point(i + 1, 1));
    for (int j = 2; j < m; ++j) {
      point now(i, j);
      for (auto it = S[i][j].rbegin(); it != S[i][j].rend(); ++it)
        if (*it == '0')
          move(now, s);
        else
          move(now, t);
    }
  }
  for (int i = 1; i < n; ++i)
    for (int j = 0; j <= 1; ++j) {
      point now(i, j), to(0, j);
      for (int k = 0; k < cnt[i][j]; ++k) move(now, to);
    }
}
void T_remove() {
  point fs(0, 0), ft(0, 1);
  for (int i = 0; i < n; ++i) {
    point s(i, 0), t(i, 1);
    for (int j = 2; j < m; ++j) {
      point now(i, j);
      for (auto it = T[i][j].rbegin(); it != T[i][j].rend(); ++it)
        if (*it == '0')
          move(fs, s), move(s, now);
        else
          move(ft, t), move(t, now);
    }
  }
  {
    point s(1, 0), t(1, 1);
    int c0 = 0, c1 = 0;
    for (auto it = T[0][0].rbegin(); it != T[0][0].rend(); ++it)
      c0 += *it == '0';
    for (auto it = T[0][1].rbegin(); it != T[0][1].rend(); ++it)
      c1 += *it == '1';
    while (c0--) move(fs, s);
    while (c1--) move(ft, t);
    for (auto it = T[0][0].rbegin(); it != T[0][0].rend(); ++it)
      if (*it == '0')
        move(s, fs);
      else
        move(ft, fs);
    for (auto it = T[0][1].rbegin(); it != T[0][1].rend(); ++it)
      if (*it == '1')
        move(t, ft);
      else
        move(fs, ft);
  }
  for (int i = 1; i < n; ++i) {
    point s(i, 0), t(i, 1);
    int c0 = 0, c1 = 0;
    for (auto it = T[i][0].rbegin(); it != T[i][0].rend(); ++it)
      c1 += *it == '1';
    for (auto it = T[i][1].rbegin(); it != T[i][1].rend(); ++it)
      c0 += *it == '0';
    while (c0--) move(fs, s);
    while (c1--) move(ft, t);
    for (auto it = T[i][0].rbegin(); it != T[i][0].rend(); ++it)
      if (*it == '0')
        move(fs, s);
      else
        move(t, s);
    for (auto it = T[i][1].rbegin(); it != T[i][1].rend(); ++it)
      if (*it == '1')
        move(ft, t);
      else
        move(s, t);
  }
}
void my_move(point p1, point p2) {
  printf("%d %d %d %d\n", p1.x + 1, p1.y + 1, p2.x + 1, p2.y + 1);
}
void solve() {
  S_remove();
  int pos = ans.size();
  T_remove();
  printf("%d\n", ans.size());
  for (int k = 0; k < ans.size(); ++k) my_move(ans[k].first, ans[k].second);
}
int main() {
  init();
  solve();
  return 0;
}
