#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;   }