import java.io.*;
import java.util.*;

public class death_ak {

    final static int[] DX = {0, 1, 0, -1};
    final static int[] DY = {1, 0, -1, 0};

    static int maxColor;
    static int n, m;
    static int[][] a;
    static int[][] c;
    static ArrayList<Integer> weight;
    static HashMap<Long, HashSet<Integer>> used = new HashMap<>();
    static HashMap<Long, ArrayList<Integer>>[] g;

    static boolean inBounds(int x, int y) {
        return 0 <= x && x < n && 0 <= y && y < m;
    }

    int dfs(int x, int y, int need, int color) {
        if (c[x][y] != -1)
            return 0;
        c[x][y] = color;
        int res = 1;
        for (int dir = 0; dir < 4; dir++) {
            int x2 = x + DX[dir];
            int y2 = y + DY[dir];
            if (inBounds(x2, y2) && a[x2][y2] == need) {
                res += dfs(x2, y2, need, color);
            }
        }
        return res;
    }

    int dfs2(int v, long pair) {
        if (used.containsKey(pair) && used.get(pair).contains(v))
            return 0;
        if (!used.containsKey(pair))
            used.put(pair, new HashSet<Integer>());
        used.get(pair).add(v);
        int res = weight.get(v);
        ArrayList<Integer> edges = g[v].get(pair);
//        for (int i = 0; i < edges.size(); i++) {
//            int to = edges.get(i);
        for (int to : edges) {
            res += dfs2(to, pair);
        }
        return res;
    }

    long pack(int c1, int c2) {
        if (c1 < c2) {
            return c1 * (long) maxColor + c2;
        } else {
            return c2 * (long) maxColor + c1;
        }
    }

    void solve() throws IOException {
        n = in.nextInt();
        m = in.nextInt();
        a = new int[n][m];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                a[i][j] = in.nextInt();
                maxColor =Math.max(maxColor, a[i][j]);
            }
        }
        maxColor++;
        c = new int[n][m];
        for (int i = 0; i < c.length; i++) {
            Arrays.fill(c[i], -1);
        }
        int colors = 0;
        weight = new ArrayList<>();
        ArrayList<Integer> cId = new ArrayList<>();
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (c[i][j] == -1) {
                    weight.add(dfs(i, j, a[i][j], colors++));
                    cId.add(a[i][j]);
                }
            }
        }

        if (colors == 1) {
            out.println(n * m);
            out.println(a[0][0] + " " + a[0][0]);
            return;
        }

        g = new HashMap[colors];
        for (int i = 0; i < colors; i++) {
            g[i] = new HashMap<>(2);
        }

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                for (int dir = 0; dir < 4; dir++) {
                    int i2 = i + DX[dir];
                    int j2 = j + DY[dir];
                    if (!inBounds(i2, j2))
                        continue;
                    int c1 = c[i][j];
                    int c2 = c[i2][j2];
                    long pair = pack(a[i][j], a[i2][j2]);
                    if (a[i][j] != a[i2][j2]) {
                        if (!g[c1].containsKey(pair)) {
                            g[c1].put(pair, new ArrayList<Integer>(1));
                        }
                        if (!g[c2].containsKey(pair)) {
                            g[c2].put(pair, new ArrayList<Integer>(1));
                        }
                        g[c1].get(pair).add(c2);
                        g[c2].get(pair).add(c1);
                    }
                }
            }
        }

        int ans = 0;
        long pans = -1;

        for (int i = 0; i < colors; i++) {
            int id1 = cId.get(i);
            for (Map.Entry<Long, ArrayList<Integer>> e : g[i].entrySet()) {
                long pair = e.getKey();
                if (used.containsKey(pair) && used.get(pair).contains(i))
                    continue;
                int now = dfs2(i, pair);
                if (now > ans) {
                    ans = now;
                    pans = pair;
                }
            }
        }

        out.println(ans);
        out.println(pans / maxColor + " " + pans % maxColor);
    }

    static MyScanner in;
    static PrintWriter out;

    public static void main(String[] args) throws IOException {
        in = new MyScanner(new FileReader("death.in"));
        out = new PrintWriter("death.out");
        new death_ak().solve();
        out.close();
    }

    static class MyScanner {
        private StringTokenizer st;
        private BufferedReader br;

        public MyScanner(Reader r) {
            br = new BufferedReader(r);
        }

        public String nextToken() throws IOException {
            while (st == null || !st.hasMoreTokens()) {
                st = new StringTokenizer(br.readLine());
            }
            return st.nextToken();
        }

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


}
