#include <cstdio>
#include <algorithm>

using namespace std;

#define LEFT '<'
#define RIGHT '>'
#define UP '^'
#define DOWN 'v'

#define MAXN 2000

int N;
int bricks[MAXN][MAXN];
char dirs[MAXN][MAXN];

void init()
{
	scanf("%d", &N);
	for(int i=0; i<N; i++) for(int j=0; j<N; j++) scanf("%d", &bricks[i][j]);
	N -= 2;
	for(int i=1; i<=N; i++)
		for(int j=1; j<=N; j++)
		{
			if(bricks[i][j] == bricks[i-1][j]) dirs[i-1][j-1] = UP;
			else if(bricks[i][j] == bricks[i+1][j]) dirs[i-1][j-1] = DOWN;
			else if(bricks[i][j] == bricks[i][j-1]) dirs[i-1][j-1] = LEFT;
			else if(bricks[i][j] == bricks[i][j+1]) dirs[i-1][j-1] = RIGHT;
		}
}

int leftEdge[MAXN][MAXN],rightEdge[MAXN][MAXN],upperEdge[MAXN][MAXN],lowerEdge[MAXN][MAXN];

void precompute()
{
	for(int i=0; i<N; i++)
	{
		upperEdge[i][N-1] = (dirs[i][N-1] == UP) ? 0 : 1;
		lowerEdge[i][N-1] = (dirs[i][N-1] == DOWN) ? 0 : 1;
		for(int j=N-2; j>=0; j--)
		{
			upperEdge[i][j] = (dirs[i][j] == UP) ? 0 : upperEdge[i][j+1]+1;
			lowerEdge[i][j] = (dirs[i][j] == DOWN) ? 0 : lowerEdge[i][j+1]+1;
		}
	}
	for(int j=0; j<N; j++)
	{
		leftEdge[N-1][j] = (dirs[N-1][j] == LEFT) ? 0 : 1;
		rightEdge[N-1][j] = (dirs[N-1][j] == RIGHT) ? 0 : 1;
		for(int i=N-2; i>=0; i--)
		{
			leftEdge[i][j] = (dirs[i][j] == LEFT) ? 0 : leftEdge[i+1][j]+1;
			rightEdge[i][j] = (dirs[i][j] == RIGHT) ? 0 : rightEdge[i+1][j]+1;
		}
	}
	
	for(int i=0; i<N and false; i++)
	{
		for(int j=0; j<N; j++) printf("%d ", upperEdge[i][j]);
		printf("\n");
	}
}

void solve()
{
	int maxSize=0,maxRow,maxCol;
	
	//O(N^3)
	
	int lim;
	
	for(int i=0; i<N; i++)
	{
		for(int j=0; j<N; j++)
		{
			lim = min(upperEdge[i][j], leftEdge[i][j]);
			for(int s=maxSize+2; s<=lim; s+=2)
			{
				if(rightEdge[i][j+s-1] >= s and lowerEdge[i+s-1][j] >= s)
				{
					maxSize = s;
					maxRow = i;
					maxCol = j;
				}
			}
		}
	}
	
	printf("%d %d %d", maxSize, maxRow+2, maxCol+2);
}

int main()
{
	//freopen("window.in", "r", stdin);
	
	init();
	precompute();
	solve();
	
	
	return 0;
}
