/**
*@task: window.cpp
*@competition: Autumn 2014, Shumen
*@author: Vasil Sarafov
*@time: 23.11.2014, Shumen
**/
#include <iostream>
#include <utility>

#define space " "
#define ln "\n"

typedef std::pair <int, int> PII;

const int MAX_N = (int)(1 << 11);
const PII UNINIT = std::make_pair(0, 0);

struct Brick {
	PII a;
	PII b;
	
	Brick() {
		a = UNINIT;
		b = UNINIT;
	}
	
	void addCube(int row, int col) {
		PII addition = std::make_pair(row, col);
		if (a == UNINIT)
			a = addition;
		else
			b = addition;
		return;
	}
	
	bool isLying(int x1, int x2, 
		int y1, int y2) {
		bool ret = false, 
			lsat = false, rsat = false;
		if (a.first >= x1 && a.first <= x2 && a.second >= y1 && a.second <= y2)
			lsat = true;
		if (b.first >= x1 && b.first <= x2 && b.second >= y1 && b.second <= y2)
			rsat = true;
		ret = (rsat && lsat);
		return ret;
	}	
};

int n, grid[MAX_N][MAX_N];
bool bad[MAX_N * MAX_N];
Brick b[MAX_N * MAX_N];

int main(int argc, char **argv) {
//	std::ios::sync_with_stdio(false);
//	std::cin.tie(NULL);
	std::cin >> n;
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			std::cin >> grid[i][j];
			b[grid[i][j]].addCube(i, j);	
		}
	}
	
//	condition 2
	for (int i = 1; i <= n; i++) {
		bad[ grid[1][i] ] = true;
		bad[ grid[n][i] ] = true;
		bad[ grid[i][1] ] = true;
		bad[ grid[i][n] ] = true;
	}
	
//	std::cout << "Bads: " << space;
//	for (int i = 1; i <= (n * n / 2); i++) {
//		if (bad[i])
//			std::cout << i << space; 
//	}
//	std::cout << ln;
//	std::cout << b[6].isLying(2, 3, 2, 3) << ln;
	for (int len = n; len >= 2; len--) {
		if (len & 1)
			continue;
		for (int i = 1; i + len - 1 <= n; i++) {
			for (int j = 1; j + len - 1 <= n; j++) {
				bool possible = true;
				int current = grid[i][j];
				if (bad[current])
					continue;
				
				for (int row = i; row <= i + len - 1; row++) {
					int lvalue = grid[row][j],
						rvalue = grid[row][j + len - 1];
					bool lsat = b[lvalue].isLying(i, i + len - 1, j, j + len - 1),
						 rsat = b[rvalue].isLying(i, i + len - 1, j, j + len - 1);
					if (lsat == false || rsat == false || bad[lvalue] || bad[rvalue]) {
						possible = false;
						break;
					}
				}
				
				if (!possible)
					continue;
				
				for (int col = j; col <= j + len - 1; col++) {
					int lvalue = grid[i][col],
						rvalue = grid[i + len - 1][col];
					bool lsat = b[lvalue].isLying(i, i + len - 1, j, j + len - 1),
						 rsat = b[rvalue].isLying(i, i + len - 1, j, j + len - 1);
					
					if (lsat == false || rsat == false || bad[lvalue] || bad [rvalue]) {
						possible = false;
						break;
					}
				}
				
				if (!possible) 
					continue;
					
				if (possible) {
					std::cout << len << space;
					std::cout << i << space;
					std::cout << j << ln;
					return 0;
				}
			} 
		}
	}
	return 0;
}

/*
6
1 1 4 4 13 14
2 3 3 5 13 14
2 6 7 5 12 12
9 6 7 10 10 15
9 8 8 11 11 15
16 16 17 17 18 18

6
1 8 8 9 9 7
1 10 10 13 12 7
2 11 15 13 12 6
2 11 15 14 14 6
3 3 4 4 5 5
16 16 17 17 18 18
*/

















