#include <functional>
#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <unordered_map>
#include <utility>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cstdio>
#include <math.h>
#include <stdio.h>
#include <deque>

using namespace std;

#define REP(i,n,m) for( long long int i = (n); i < (m); i++ )
#define REV(v) for (auto itr = v.rbegin(); itr != v.rend(); itr++)
#define ll long long
#define ALL(a) (a).begin(), (a).end()
#define SORT(v) sort( ALL(v) );
#define LAST(v) v[v.size()-1]
#define ZERO(a) memset(a,0,sizeof(a));
#define MINUS(a) memset(a,-1,sizeof(a));
#define EACH(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define pi pair<int, int>
#define MP make_pair
#define PB push_back
#define EB emplace_back
#define IIN(a) int a; cin >> a;
#define LIN(a) ll a; cin >> a;
#define SIN(a) string a; cin >> a;
#define VL(v,n) vector<ll> v(n);
#define Read_VL(v,n) vector<ll> v(n);REP(i,0,n)cin>>v[i];
#define sumV(v,n) Vl(acm,n) REP(i,0,n) acm[i] = v[i] + ( i == 0 ? 0 : acm[i - 1]);
#define EPS (1e-10)
#define INF 1000000000000LL

void YN(bool b){cout<<(b?"YES":"NO")<<"\n";}
void Yn(bool b){cout<<(b?"Yes":"No")<<"\n";}
void yn(bool b){cout<<(b?"yes":"no")<<"\n";}

template<class S>S max(vector<S>&a){return *max_element(all(a));}
template<class S>S min(vector<S>&a){return *min_element(all(a));}

template<class T>void puta(T&&t){cout<<t<<"\n";}
template<class H,class...T>void puta(H&&h,T&&...t){cout<<h<<' ';puta(t...);}


template<class T=ll>struct Graph{
	int n;
	vector<vector<tuple<ll,T>>>edge;
	Graph(int N=1):n(N){edge.resize(n);}
	void add(ll f,ll t,T c,bool d=false){
		edge[f].emplace_back(t,c);
		if(!d)edge[t].emplace_back(f,c);
	}
	void view(){
		REP(i,0,n)for(auto&e:edge[i])
			puta(i,"=>",get<0>(e),", cost :",get<1>(e));
	}
};

bool length_cmp( string &a, string &b ){
  return a.size() < b.size();
}

ll StoLL( string s )
{
	ll num=0;
  REP( i, 0, s.size() ){
    num = num * 10 + ( s[i] ^ 48 );
  }
  return num;
}

ll CtoLL( char c )
{
	if( 'a' <= c && c <= 'z'){
		return (ll)( c ^ 96 ) ;
	}
	else if( 'A' <= c && c <= 'Z'){
		return (ll)( c ^ 64 );
	}
  return 0;
}

ll MOD=1000000007;
ll dx[4] = { 1, 0, -1, 0 };
ll dy[4] = { 0, 1, 0, -1 };
//I ASCII code: '0' = 48; 'A' = 65; 'a' = 97
//
//
// template <typename T>
// class Grid
// {
// public:
//     virtual const ll get_width() = 0;
//     virtual const ll get_height() = 0;
//     virtual T get_item(const ll x, const ll y) = 0;
//
// };
//
// class util
// {
//     util() = default;
//     ~util() = default;
//
// public:
//     util(const util&) = delete;
//     util& operator=(const util&) = delete;
//     util(util&&) = delete;
//     util& operator=(util&&) = delete;
//
//     template <typename T>
//     static void for_each(Grid<T> &src, std::function<void(ll, ll, T)> func)
//     {
//         for (ll y = 0; y < src.get_height(); y++)
//         {
//             for (ll x = 0; x < src.get_width(); x++)
//             {
//                 T obj = src.get_item(x, y);
//                 func(x, y, obj);
//             }
//         }
//     }
// };
//
// ll h,w;
// class Test : public Grid<ll>
// {
//
// public:
//     const ll get_width() override
//     {
//         return w;
//     }
//
//     const ll get_height() override
//     {
//         return h;
//     }
//
//     ll get_item(const ll w, const ll h) override
//     {
//       LIN(a);
//       return a;
//     }
// };

signed main() {
    ios_base::sync_with_stdio(0); cin.tie(0);
    // Test g;

    // util::for_each<ll>(g, [](ll x, ll y, ll obj)
    // {
    //     std::cout << "(" << x << ", " << y  << ") : " << obj << std::endl;
    // // });

    //
    // deque<ll> dq;
    // REP( i, 0, 100 ){
    //   dq.push_back( rand() % 100 );
    // }
    // puta( dq.front(), dq.back()  );
    // dq.pop_front();
    // dq.pop_back();
    // puta( dq.front(), dq.back()  );
    // LIN(a) LIN(b)
    // dq.push_front(a);
    // dq.push_back(b);
    // puta( dq.front(), dq.back()  );
    // deque<ll> dq2 = {1,3,4,5};
    // dq.swap(dq2);
    // dq.shrink_to_fit();
    // for( auto x :dq ){
    //   puta( x );
    // }


    LIN(h) LIN(w)
    ll grid[500][500];
		REP(i,0,h){
			REP(j,0,w){
				cin>>grid[i][j];
      }
    }

    vector< tuple< ll,ll,ll,ll > > tt;
    for( ll i = h - 1; i >= 0; i-- ){
      if( i % 2 == 0 ){
        for( ll j = 0; j < w; j++ ){
          if( grid[i][j] % 2 == 1 ){
            grid[i][j]--;
            if( j + 1 == w ){
              if( i > 0 ){
                tt.EB( i, j, i - 1, j );
                grid[i-1][j]++;
              }
            }else{
              tt.EB( i, j, i, j + 1 );
              grid[i][j+1]++;
            }
          }
        }
      }else{
        for( ll j = w - 1; j >= 0; j-- ){
          if( grid[i][j]%2 == 1 ){
            grid[i][j]--;
            if( j == 0 ){
              if( i > 0 ){
                tt.EB( i, j, i-1, j );
                grid[i-1][j]++;
              }
            }else{
              tt.EB( i, j, i, j - 1 );
              grid[i][j-1]++;
            }
          }
        }
      }
    }
    puta( tt.size() );
    for( auto &p : tt ){
      ll a,b,c,d;
      tie(a,b,c,d) = p;
      puta(a+1,b+1,c+1,d+1);
    }

    return 0;
}


Measured memory_bytes: 8432