Problem:
Score : 400 points

Problem Statement

There is a grid of square cells with H horizontal rows and W vertical columns. The cell at the i-th row and the j-th column will be denoted as Cell (i, j).

In Cell (i, j), a_{ij} coins are placed.

You can perform the following operation any number of times:

Operation: Choose a cell that was not chosen before and contains one or more coins, then move one of those coins to a vertically or horizontally adjacent cell.

Maximize the number of cells containing an even number of coins.

Constraints

All values in input are integers.

1 \leq H, W \leq 500

0 \leq a_{ij} \leq 9

Input

Input is given from Standard Input in the following format:

H W
a_{11} a_{12} ... a_{1W}
a_{21} a_{22} ... a_{2W}
:
a_{H1} a_{H2} ... a_{HW}

Output

Print a sequence of operations that maximizes the number of cells containing an even number of coins, in the following format:

N
y_1 x_1 y_1' x_1'
y_2 x_2 y_2' x_2'
:
y_N x_N y_N' x_N'

That is, in the first line, print an integer N between 0 and H \times W (inclusive), representing the number of operations.

In the (i+1)-th line (1 \leq i \leq N), print four integers y_i, x_i, y_i' and x_i' (1 \leq y_i, y_i' \leq H and 1 \leq x_i, x_i' \leq W), representing the i-th operation. These four integers represents the operation of moving one of the coins placed in Cell (y_i, x_i) to a vertically or horizontally adjacent cell, (y_i', x_i').

Note that if the specified operation violates the specification in the problem statement or the output format is invalid, it will result in Wrong Answer.

Sample Input 1

2 3
1 2 3
0 1 1

Sample Output 1

3
2 2 2 3
1 1 1 2
1 3 1 2

Every cell contains an even number of coins after the following sequence of operations:

Move the coin in Cell (2, 2) to Cell (2, 3).

Move the coin in Cell (1, 1) to Cell (1, 2).

Move one of the coins in Cell (1, 3) to Cell (1, 2).

Sample Input 2

3 2
1 0
2 1
1 0

Sample Output 2

3
1 1 1 2
1 2 2 2
3 1 3 2

Sample Input 3

1 5
9 9 9 9 9

Sample Output 3

2
1 1 1 2
1 3 1 4

Solution in C# (Mono 4.6.2.0) (judge verdict: Accepted)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using static System.Console;
using static System.Math;
 
public class Solve{
    static public int mod = 1000000007;
    public static void Main(){
        // 方針
        // 
        var n = inta();
        var map = new int[n[0],n[1]];
        for(int i=0;i<n[0];i++){
            var a = inta();
            for(int j=0;j<n[1];j++){
                map[i,j] = a[j];
            }
        }
        var ans = new List<string>();
        for(int i=0;i<n[0];i++){
            for(int j=0;j<n[1];j++){
                if(j == n[1]-1){
                    if(i == n[0]-1){
                        break;
                    }
                    if(map[i,j] %2 == 1){
                        map[i+1,j]++;
                        string temp =(i+1).ToString()+" "+(j+1).ToString()+" "+(i+2).ToString()+" "+(j+1).ToString();
                        ans.Add(temp);
                    }
                    continue;
                }
                if(map[i,j] %2 ==1){
                    map[i,j+1]++;
                    string temp =(i+1).ToString()+" "+(j+1).ToString()+" "+(i+1).ToString()+" "+(j+2).ToString();
                    ans.Add(temp);
                }
            }
        }
        WriteLine(ans.Count);
        WriteLine(string.Join("\n",ans));
        
        
        
        
        
        
    }
    static int binarysearchd(int[] a,int b){
        int leng = a.Length;
        int min = 0;
        int max = leng-1;
        while(max - min > 1){
            int mid = (min+max)/2;
            if(a[mid] < b){
                min = mid;
            }else{
                max = mid;
            }
        }
        if(a[0] >= b){
            return 0;
        }else if(a[leng-1] < b){
            return leng;
        }else{
            if(a[max] < b){
                return max+1;
            }
            return min+1;
        }
    }
    static int binarysearchu(int[] a,int b){
        int leng = a.Length;
        int min = 0;
        int max = leng-1;
        while(max - min > 1){
            int mid = (min+max)/2;
            if(a[mid] < b){
                min = mid;
            }else{
                max = mid;
            }
        }
        if(a[0] > b){
            return leng;
        }else if(a[leng-1] <= b){
            return 0;
        }else{
            if(a[max] <= b){
                return leng-(max+1);
            }
            return leng-(min+1);
        }
    }
    // 1からaまでの数字並べ替え全通り返すやつ
    static List<string> permutation(int a){var list = new List<string>();if(a == 1){list.Add("1");return list;}else{foreach(var k in permutation(a-1)){var ch = k.ToCharArray();for(int i=0;i<=ch.Length;i++){string intemp = "";if(i == 0){intemp += a.ToString();}for(int j=0;j<ch.Length;j++){intemp += ch[j].ToString();if(i == j+1){intemp += a.ToString();}}list.Add(intemp);}}}return list;}
    public static void swap(ref int a,ref int b){int temp = a;a= b;b = temp;}
    static void charswap(ref char a,ref char b){char temp = a;a= b;b = temp;}
    static int ncr(int n,int r){r = Min(r,n-r);long nn = 1;for(int i=n-r+1;i<=n;i++){nn = nn*i%mod;}long rr = 1;for(int i=1;i<=r;i++){rr = rr*i%mod;}rr = square((int)rr,mod-2);nn = nn * rr %mod;return (int)nn;}
    // a^b mod
    static int square(int a,int b){string binary = Convert.ToString(b,2);int bileng = binary.Length;long a_power = a;long value = 1;for(int i=bileng-1;i>=0;i--){if(binary[i] == '1'){value = value*a_power%mod;}a_power = a_power*a_power%mod;}return (int)value;}
    static int square2(int a,int b){long output = 1;var list = new List<long>();int sh = 1;long n = a;list.Add(a);while(sh < b){sh *= 2;n = n*n%mod;list.Add(n);}for(int i=list.Count-1;i>=0;i--){if(b > sh){b -= sh;sh /= 2;output = output*list[i]%mod;}}return (int)output;}
    //各種読取
    static string rstr(){ return ReadLine(); }
    static int rint(){ return int.Parse(ReadLine()); }
    static long rlong(){ return long.Parse(ReadLine()); }
    static string[] stra(){ return ReadLine().Split(' '); }
    static char[] chara(){ string[] a=stra();string b="";for(int i=0;i<a.Length;i++){b+=a[i];}return b.ToCharArray();}
    static int[] inta(){ string[] read_str_array = ReadLine().Split(' '); int[] return_int_array = new int[read_str_array.Length]; for(int countup_i=0;countup_i<read_str_array.Length;countup_i++){ return_int_array[countup_i] = int.Parse(read_str_array[countup_i]); } return return_int_array; }
    static int[,] inta2(int num_array,int in_array){ int[,] int_array2 = new int[num_array,in_array]; for(int i=0;i<num_array;i++){ int[] temp_array = inta(); for(int j=0;j<in_array;j++){ int_array2[i,j] = temp_array[j]; } } return int_array2; }
    static long[] longa(){ string[] read_str_array = ReadLine().Split(' '); long[] return_long_array = new long[read_str_array.Length]; for(long countup_i=0;countup_i<read_str_array.Length;countup_i++){ return_long_array[countup_i] = long.Parse(read_str_array[countup_i]); } return return_long_array; }
    static double[] doublea(){ string[] read_str_array = ReadLine().Split(' '); double[] return_double_array = new double[read_str_array.Length]; for(long countup_i=0;countup_i<read_str_array.Length;countup_i++){ return_double_array[countup_i] = long.Parse(read_str_array[countup_i]); } return return_double_array; }
    // -----------------------------
    static long divideup(long divided,long divid){ long temp_divide = divided/divid; if(divided % divid > 0){ temp_divide++; } return temp_divide; }
    static long GCD(long a,long b){ if(a < b){ long temp = a; a = b; b = temp; } if(a % b == 0){ return b; } else{ long temp = b; b = a%b; a = temp; return GCD(a,b); } }
    static long LCM(long a,long b){ return a * b / GCD(a,b); }
}


class UnionFind{
    private int[] _unionfind;
    private int[] _unionfind_size;
    
    public UnionFind(int a){
        _unionfind = new int[a];
        _unionfind_size = new int[a];
        for(int i=0;i<a;i++){
            _unionfind[i] = i;
            _unionfind_size[i] = 1;
        }
    }
    
    public int root(int x){
        if(_unionfind[x] == x) return x;
        return _unionfind[x] = root(_unionfind[x]);
    }
    
    public void unite(int a,int b){
        a = root(a);
        b = root(b);
        if(a == b) return;
        if(_unionfind_size[a] < _unionfind_size[b]){
            int temp = a;
            a = b;
            b = temp;
        }
        _unionfind[b] = a;
        _unionfind_size[a] += _unionfind_size[b];
    }
    
    public bool same(int a,int b){
        return root(a) == root(b);
    }
    
    public int size(int x){
        return _unionfind_size[root(x)];
    }
}

class PriorityQueue{
    private List<int> _priorityqueue;
    
    public void Enqueue(int a){
        _priorityqueue.Add(a);
        int num = _priorityqueue.Count-1;
        while(true){
            if(num == 0) break;
            if(_priorityqueue[(num-1)/2] < _priorityqueue[num]){ //大小逆の時弄るとこ
                int temp = _priorityqueue[(num-1)/2];
                _priorityqueue[(num-1)/2] = _priorityqueue[num];
                _priorityqueue[num] = temp;
                num = (num-1)/2;
            }else{
                break;
            }
        }
    }
    
    public int Dequeue(){
        int re = _priorityqueue[0];
        int temp = _priorityqueue[0];
        _priorityqueue[0] = _priorityqueue[_priorityqueue.Count-1];
        _priorityqueue[_priorityqueue.Count-1] = temp;
        _priorityqueue.Remove(_priorityqueue.Count-1);
        int num = 0;
        while(true){
            int swapnum = -1;
            if((num+1)*2 < _priorityqueue.Count){
                if(_priorityqueue[num*2+1] > _priorityqueue[(num+1)*2]){ //大小逆の時弄るとこ
                    swapnum = num*2+1;
                }else{
                    swapnum = (num+1)*2;
                }
            }else if(num*2+1 < _priorityqueue.Count){
                swapnum = num*2+1;
            }
            if(swapnum == -1) break;
            if(_priorityqueue[swapnum] > _priorityqueue[num]){ //大小逆の時弄るとこ
                temp = _priorityqueue[swapnum];
                _priorityqueue[swapnum] = _priorityqueue[num];
                _priorityqueue[num] = temp;
                num = swapnum;
            }else{
                break;
            }
        }
        return re;
    }
    
    public int Peek(){
        return _priorityqueue[0];
    }
    
    public int Count(){
        return _priorityqueue.Count;
    }
}



//知見
// (string) hogestr -> (char[]) hoge
    // char hoge = hogestr.ToCharArray();
// (char[]) hoge -> (string) hogestr
    // string hoge = new string(hoge);
// Dictionary hoge<string,int>
    // hoge.ContainsKey(string) -> return boolean
    // hoge[string] -> return int
    // hoge[int] -> CE
// Dictionary hoge<int1,int2>
    // hoge<int1,int2>: hoge[int1] -> return int2
    // KeyValuePair<int,int> k <-> k.Key == int1 / k.Value == int2
// SortedDictionary() > SortedList() ???
// キュー　-> 幅優先 ???
    // var queue = new Queue<int>(); queue.Enqueue() queue.Dequeue()
// スタック -> 深さ優先 ???
    // var stack = new Stack<int>(); stack.Push(hoge) stack.Pop() stackPeek() stack.Count
// if (list?.Count > 0) リストが空でもnullでもない
// ソート
    // list.Sort(StringComparer.Ordinal); listの(辞書順?)ソート
        // StringComparer.Ordinal とは
    // Array.Sort(list1,list2);
// 出力
    // foreach(var a int list){ WriteLine(a); } より
        // WriteLine(string.Join("\n", list)); が速い
    //var sw = new StreamWriter(Console.OpenStandardOutput()){AutoFlush = false};
    //    Console.SetOut(sw);
    //    出力部分
    //    Console.Out.Flush();
// 未知
    // 最小費用流
    // 二分探索の理解が浅い