import java.util.*;
public class main
{
static final int[] DR = {0, 1, -1, 0, 0};
static final int[] DC = {0, 0, 0, 1, -1};
private static ArrayList<Integer> move_rows, move_cols;
private static int[][] tiles;
private static int h, w;
private static boolean check(int r1, int c1, int r2, int c2)
{
if(r1 < 0 || h <= r1 || c1 < 0 || w <= c1)
return false;
if(r2 < 0 || h <= r2 || c2 < 0 || w <= c2)
return false;
if(r1 == r2 && c1 == c2)
return true;
if(r1 != r2 && c1 != c2)
return false;
int len = Math.abs(r1 - r2) + Math.abs(c1 - c2);
int dr = (r2 - r1)/len;
int dc = (c2 - c1)/len;
while(r1 != r2 || c1 != c2)
{
if(tiles[r1][c1] < 0)
return false;
r1 += dr;
c1 += dc;
}
return tiles[r1][c1] >= 0;
}
private static void shift(int r1, int c1, int r2, int c2)
{
if(r1 == r2 && c1 == c2)
return;
int len = Math.abs(r1 - r2) + Math.abs(c1 - c2);
int dr = (r2 - r1)/len;
int dc = (c2 - c1)/len;
int tile = tiles[r1][c1];
while(r1 != r2 || c1 != c2)
{
tiles[r1][c1] = tiles[r1 + dr][c1 + dc];
r1 += dr;
c1 += dc;
}
tiles[r1][c1] = tile;
move_rows.add(r2);
move_cols.add(c2);
}
private static void slide(int r1, int c1, int r2, int c2)
{
for(int i = 0; i < 5; ++i)
for(int j = 0; j < 5; ++j)
{
int rs = r1 + DR[i];
int cs = c1 + DC[i];
int rf = r2 + DR[j];
int cf = c2 + DC[j];
int[] rm = {rs, rf};
int[] cm = {cf, cs};
int way = 0;
while(way < 2 && (!check(rs, cs, rm[way], cm[way]) || !check(rm[way], cm[way], rf, cf)))
++way;
if(way < 2)
{
shift(r1, c1, rs, cs);
shift(rs, cs, rm[way], cm[way]);
shift(rm[way], cm[way], rf, cf);
shift(rf, cf, r2, c2);
return;
}
}
}
private static void move(int r1, int c1, int r2, int c2)
{
if(r1 == r2 && c1 == c2)
return;
int rs = -1, cs = -1;
for(int i = 0; i < h; ++i)
for(int j = 0; j < w; ++j)
if(tiles[i][j] == 0)
{
rs = i;
cs = j;
}
int len = Math.abs(r1 - r2) + Math.abs(c1 - c2);
int dr = (r2 - r1)/len;
int dc = (c2 - c1)/len;
while(r1 != r2 || c1 != c2)
{
tiles[r1][c1] = -tiles[r1][c1];
slide(rs, cs, r1 + dr, c1 + dc);
tiles[r1][c1] = -tiles[r1][c1];
shift(r1 + dr, c1 + dc, r1, c1);
rs = r1;
cs = c1;
r1 += dr;
c1 += dc;
}
}
private static void move(int label, int row, int col)
{
int rs = -1, cs = -1;
for(int i = 0; i < h; ++i)
for(int j = 0; j < w; ++j)
if(tiles[i][j] == label)
{
rs = i;
cs = j;
}
int[] rm = {rs, row};
int[] cm = {col, cs};
int way = 0;
while(way < 2 && (!check(rs, cs, rm[way], cm[way]) || !check(rm[way], cm[way], row, col)))
++way;
move(rs, cs, rm[way], cm[way]);
move(rm[way], cm[way], row, col);
}
private static boolean build()
{
move_rows = new ArrayList<Integer>();
move_cols = new ArrayList<Integer>();
for(int i = 0; i < h - 2; ++i)
{
for(int j = 0; j < w - 2; ++j)
{
move(i*w + j + 1, i, j);
tiles[i][j] = -tiles[i][j];
}
move(i*w + w - 1, i, w - 1);
if(tiles[i][w - 2] == 0)
shift(i, w - 2, i + 1, w - 2);
if(tiles[i][w - 2] == i*w + w)
{
move(i, w - 2, i + 1, w - 2);
shift(i, w - 2, i, w - 1);
shift(i, w - 1, i + 2, w - 1);
shift(i + 2, w - 1, i + 2, w - 2);
shift(i + 2, w - 2, i + 1, w - 2);
shift(i + 1, w - 2, i + 1, w - 1);
shift(i + 1, w - 1, i, w - 1);
shift(i, w - 1, i, w - 2);
shift(i, w - 2, i + 1, w - 2);
}
move(i*w + w, i + 1, w - 1);
tiles[i + 1][w - 1] = -tiles[i + 1][w - 1];
move(i, w - 1, i, w - 2);
tiles[i + 1][w - 1] = -tiles[i + 1][w - 1];
shift(i, w - 1, i + 1, w - 1);
tiles[i][w - 2] = -tiles[i][w - 2];
tiles[i][w - 1] = -tiles[i][w - 1];
}
for(int j = 0; j < w - 2; ++j)
{
move((h - 2)*w + j + 1, h - 1, j);
if(tiles[h - 2][j] == 0)
shift(h - 2, j, h - 2, j + 1);
if(tiles[h - 2][j] == (h - 1)*w + j + 1)
{
move(h - 2, j, h - 2, j + 1);
shift(h - 2, j, h - 1, j);
shift(h - 1, j, h - 1, j + 2);
shift(h - 1, j + 2, h - 2, j + 2);
shift(h - 2, j + 2, h - 2, j + 1);
shift(h - 2, j + 1, h - 1, j + 1);
shift(h - 1, j + 1, h - 1, j);
shift(h - 1, j, h - 2, j);
shift(h - 2, j, h - 2, j + 1);
}
move((h - 1)*w + j + 1, h - 1, j + 1);
tiles[h - 1][j + 1] = -tiles[h - 1][j + 1];
move(h - 1, j, h - 2, j);
tiles[h - 1][j + 1] = -tiles[h - 1][j + 1];
shift(h - 1, j, h - 1, j + 1);
tiles[h - 2][j] = -tiles[h - 2][j];
tiles[h - 1][j] = -tiles[h - 1][j];
}
final int[] rows = {h - 1, h - 2, h - 2, h - 1};
final int[] cols = {w - 1, w - 1, w - 2, w - 2};
for(int i = 0; i < 4; ++i)
{
int cnt = 0;
for(int j = 1; j < 4; ++j)
if(tiles[rows[j]][cols[j]] == rows[j]*w + cols[j] + 1)
++cnt;
if(cnt == 3)
return true;
for(int j = 0; j < 4; ++j)
if(tiles[rows[j]][cols[j]] == 0)
slide(rows[j], cols[j], rows[(j + 1) % 4], cols[(j + 1) % 4]);
}
return false;
}
private static boolean solve()
{
Scanner in = new Scanner(System.in);
h = in.nextInt();
w = in.nextInt();
in.nextLine();
String[] puzzle = new String[h];
for(int i = 0; i < h; ++i)
puzzle[i] = in.nextLine();
ArrayList<Integer> rows = new ArrayList<Integer>(), cols = new ArrayList<Integer>();
ArrayList<Character> chars = new ArrayList<Character>();
for(char c = 'a'; c <= 'z'; ++c)
for(int i = 0; i < h; ++i)
for(int j = 0; j < w; ++j)
if(puzzle[i].charAt(j) == c)
{
rows.add(i);
cols.add(j);
chars.add(c);
}
for(int i = 0; i < 2; ++i)
{
tiles = new int[h][w];
for(int j = 0; j < chars.size(); ++j)
tiles[rows.get(j)][cols.get(j)] = j + 1;
if(build())
return true;
for(int j = 1; j < chars.size(); ++j)
if(chars.get(j) == chars.get(j - 1))
{
int temp = rows.get(j);
rows.set(j, rows.get(j - 1));
rows.set(j - 1, temp);
temp = cols.get(j);
cols.set(j, cols.get(j - 1));
cols.set(j - 1, temp);
break;
}
}
return false;
}
public static void main(String[] args)
{
solve();
System.out.println(move_rows.size());
for(int i = 0; i < move_rows.size(); ++i)
System.out.println("" + (move_rows.get(i) + 1) + " " + (move_cols.get(i) + 1));
}
}