#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_ON			1										// 汎用フラグ - ON
#define D_OFF			0										// 汎用フラグ - OFF
#define D_SIZE_MAX		500										// 最大サイズ
#define D_OPE_MAX		(D_SIZE_MAX * D_SIZE_MAX / 2)			// 最大操作回数

// 内部構造体 - 操作情報
typedef struct Ope {
	int miFy, miFx;												// 移動元
	int miTy, miTx;												// 移動先
} Ope;

// 内部変数
static FILE *szpFpI;											// 入力
static int siH, siW;											// 高さ・幅
static int si2Coin[D_SIZE_MAX + 5][D_SIZE_MAX + 5];				// コイン数
static Ope sz1Ope[D_OPE_MAX];									// 操作
static int siOCnt;												// 操作数

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpA;
#endif

// 移動
int
fMove(
	int piDsp					// <I> 表示
	, Ope *pzpOpe				// <I> 操作
)
{
	char lc1Buf[1024], lc1Out[1024];

	// 現在位置
	int liNx = pzpOpe->miFx;
	int liNy = pzpOpe->miFy;

	// 移動
	int liCnt = 0;
	while (liNx != pzpOpe->miTx || liNy != pzpOpe->miTy) {

		// 移動先
		int liTx = liNx;
		int liTy = liNy;
		if (liNy % 2 == 1) {			// 奇数行
			if (liNx < siW) {
				liTx++;
			}
			else {
				liTy++;
			}
		}
		else {							// 偶数行
			if (liNx > 1) {
				liTx--;
			}
			else {
				liTy++;
			}
		}

		// 表示
		if (piDsp == D_ON) {
			sprintf(lc1Out, "%d %d %d %d\n", liNy, liNx, liTy, liTx);
#ifdef D_TEST
			fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
			if (strcmp(lc1Buf, lc1Out)) {
				siRes = -1;
			}
#else
			printf("%s", lc1Out);
#endif
		}

		// 移動
		liNx = liTx;
		liNy = liTy;
		liCnt++;
	}

	return liCnt;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1～
)
{
	int i, j;
	char lc1Buf[1024], lc1Out[1024];

	// データ - 初期化
	siOCnt = 0;													// 操作数

	// 入力 - セット
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpI = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#else
	szpFpI = stdin;
#endif

	// 高さ・幅 - 取得
	fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
	sscanf(lc1Buf, "%d%d", &siH, &siW);

	// コイン - 取得
	for (i = 1; i <= siH; i++) {
		for (j = 1; j <= siW; j++) {
			fscanf(szpFpI, "%d", &si2Coin[i][j]);
		}
		fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
	}

	// 操作 - セット
	int liFrom = D_OFF;
	int liOSum = 0;
	for (i = 1; i <= siH; i++) {

		// 検索方向 - セット
		int liSNo, liENo, liAdd;
		if (i % 2 == 1) {					// 奇数行
			liSNo = 1;
			liENo = siW + 1;
			liAdd = 1;
		}
		else {								// 偶数行
			liSNo = siW;
			liENo = 0;
			liAdd = -1;
		}

		// 検索 - 実行
		for (j = liSNo; j != liENo; j += liAdd) {

			// コイン数 - チェック
			if (si2Coin[i][j] % 2 == 0) {		// 偶数
				continue;
			}

			// 移動元 - 有無チェック
			if (liFrom == D_OFF) {				// なし
				liFrom = D_ON;
				sz1Ope[siOCnt].miFy = i;
				sz1Ope[siOCnt].miFx = j;
				continue;
			}
			liFrom = D_OFF;

			// 移動先 - セット
			sz1Ope[siOCnt].miTy = i;
			sz1Ope[siOCnt].miTx = j;
			siOCnt++;

			// 操作数合計
			liOSum += fMove(D_OFF, &sz1Ope[siOCnt - 1]);
		}
	}

	// 操作数合計 - 表示
	sprintf(lc1Out, "%d\n", liOSum);
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// 操作 - 表示
	for (i = 0; i < siOCnt; i++) {
		fMove(D_ON, &sz1Ope[i]);
	}

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpI);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}



Measured memory_bytes: 4992