import java.io.*;
import java.util.Arrays;
import java.util.HashMap;
import java.util.StringTokenizer;

public class death_vd {
	BufferedReader in;
	StringTokenizer str;
	PrintWriter out;
	String SK;

	String next() throws IOException {
		while ((str == null) || (!str.hasMoreTokens())) {
			SK = in.readLine();
			if (SK == null)
				return null;
			str = new StringTokenizer(SK);
		}
		return str.nextToken();
	}

	int nextInt() throws IOException {
		return Integer.parseInt(next());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(next());
	}

	long nextLong() throws IOException {
		return Long.parseLong(next());
	}

	static final int[] dx = { 1, -1, 0, 0 };
	static final int[] dy = { 0, 0, 1, -1 };

	int[][] a;
	int[][] col;
	int n, m;

	void dfs(int x, int y, int cl, int mcol) {
		if (x < 0 || y < 0 || x >= n || y >= m) {
			return;
		}
		if (col[x][y] != 0) {
			return;
		}
		if (a[x][y] != mcol) {
			return;
		}
		col[x][y] = cl;
		for (int t = 0; t < 4; t++) {
			dfs(x + dx[t], y + dy[t], cl, mcol);
		}
	}

	class Edge implements Comparable<Edge> {
		int v1, c1;
		int v2, c2;

		public Edge(int v1, int c1, int v2, int c2) {
			if (c1 > c2) {
				int t = v1;
				v1 = v2;
				v2 = t;
				t = c1;
				c1 = c2;
				c2 = t;
			}
			this.v1 = v1;
			this.c1 = c1;
			this.v2 = v2;
			this.c2 = c2;
		}

		public int compareTo(Edge o) {
			if (c1 != o.c1) {
				return c1 - o.c1;
			}
			return c2 - o.c2;
		}
	}

	int[] size;

	int[] par;
	int[] rank;
	int[] cursize;

	int curc1;
	int curc2;

	int res = 0;
	int c1 = 0;
	int c2 = 0;

	int get(int v) {
		return par[v] = (par[v] != v) ? get(par[v]) : v;
	}

	void union(int v1, int v2) {
		if (v1 == v2) {
			return;
		}
		if (cursize[v1] + cursize[v2] > res) {
			res = cursize[v1] + cursize[v2];
			c1 = curc1;
			c2 = curc2;
		}
		if (rank[v1] == rank[v2]) {
			rank[v1]++;
		}
		if (rank[v1] > rank[v2]) {
			par[v2] = v1;
			cursize[v1] += cursize[v2];
		} else {
			par[v1] = v2;
			cursize[v2] += cursize[v1];
		}
	}

	void solve() throws IOException {
		long tm = System.currentTimeMillis();
		n = nextInt();
		m = nextInt();
		a = new int[n][m];
		col = new int[n][m];

		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				a[i][j] = nextInt();
			}
		}
		int colNum = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (col[i][j] == 0) {
					dfs(i, j, ++colNum, a[i][j]);
				}
			}
		}

		size = new int[colNum];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				col[i][j]--;
				size[col[i][j]]++;
			}
		}

		par = new int[colNum];
		rank = new int[colNum];
		cursize = new int[colNum];

		for (int i = 0; i < colNum; i++) {
			par[i] = i;
			rank[i] = 0;
			cursize[i] = size[i];
		}
		res = size[col[0][0]];
		c1 = c2 = a[0][0];

		int e = 2 * (n - 1) * (m - 1) + (n - 1) + (m - 1);
		Edge[] b = new Edge[e];
		e = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				if (i + 1 < n) {
					b[e++] = new Edge(col[i][j], a[i][j], col[i + 1][j],
							a[i + 1][j]);
				}
				if (j + 1 < m) {
					b[e++] = new Edge(col[i][j], a[i][j], col[i][j + 1],
							a[i][j + 1]);
				}
			}
		}
		System.err.println(System.currentTimeMillis() - tm);
		Arrays.sort(b); 
		System.err.println(System.currentTimeMillis() - tm);
		for (int i = 0; i < e;) {
			int j = i + 1;
			while (j < e && b[j].compareTo(b[i]) == 0) {
				j++;
			}
			curc1 = b[i].c1;
			curc2 = b[i].c2;
			for (int t = i; t < j; t++) {
				union(get(b[t].v1), get(b[t].v2));
			}
			for (int t = i; t < j; t++) {
				cursize[b[t].v1] = size[b[t].v1];
				cursize[b[t].v2] = size[b[t].v2];
				rank[b[t].v1] = rank[b[t].v2] = 0;
				par[b[t].v1] = b[t].v1;
				par[b[t].v2] = b[t].v2;
			}
			i = j;
		}
		out.println(res);
		out.println(c1 + " " + c2);
		System.err.println(System.currentTimeMillis() - tm);
	}

	void run() throws IOException {
		in = new BufferedReader(new FileReader("death.in"));
		for (int i = 0; i < 1; i++) {
			out = new PrintWriter("death.out");
			solve();
			out.close();
		}
	}

	public static void main(String[] args) throws IOException {
		new death_vd().run();
	}

}