unittest
{
//	assert( [ "2 3", "1 2 3", "0 1 1" ].solve == "3\n2 2 2 3\n1 1 1 2\n1 3 1 2" );
	assert( [ "2 3", "1 2 3", "0 1 1" ].solve == "3\n1 1 1 2\n1 2 1 3\n2 3 2 2" );		// 別解
	assert( [ "3 2", "1 0", "2 1", "1 0" ].solve == "3\n1 1 1 2\n1 2 2 2\n3 1 3 2" );
	assert( [ "1 5", "9 9 9 9 9" ].solve == "2\n1 1 1 2\n1 3 1 4" );
}



import std.algorithm;
import std.conv;
import std.format;
import std.range;
import std.stdio;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto h = 0L;
	auto w = 0L;
	input.front.formattedRead!"%s %s"( h, w );
	auto ass = new long[][]( h, w );
	foreach( ref as; ass )
	{
		input.popFront;
		as = input.front.split.to!( long[] );
	}
	
	long[ 4 ][] anss;
	foreach( y; 0L .. ass.length.signed )
	{
		auto x = 0L;
		if( y % 2 )
		{
			// 右から左に移動
			for( x = ass[ y ].length.signed - 1; 0L < x; x-- )
			{
				if( ass[ y ][ x ] % 2 )
				{
					ass[ y ][ x ]--;
					ass[ y ][ x - 1 ]++;
					anss ~= [ 1 + y, 1 + x, 1 + y, 1 + x - 1 ];
				}
			}
		}
		else
		{
			// 左から右に移動
			for( x = 0L; x < ass[ y ].length.signed - 1; x++ )
			{
				if( ass[ y ][ x ] % 2 )
				{
					ass[ y ][ x ]--;
					ass[ y ][ x + 1 ]++;
					anss ~= [ 1 + y, 1 + x, 1 + y, 1 + x + 1 ];
				}
			}
		}
		
		// 下に移動
		if( y + 1 < ass.length && ass[ y ][ x ] % 2 )
		{
			ass[ y ][ x ]--;
			ass[ y + 1 ][ x ]++;
			anss ~= [ 1 + y, 1 + x, 1 + y + 1, 1 + x ];
		}
	}
	return format( "%s\n%s", anss.length, anss.map!( ( ans ) => ans.to!( string[] ).join( " " ) ).join( "\n" ) );
}
