#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cassert>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <set>
#include <map>

using namespace std;

#define mp(a, b) make_pair(a, b)
#define szof(a) ((int)(a).size())
#define all(a) (a).begin(), (a).end()

typedef signed long long int int64;
typedef long double real;
typedef pair<int, int> pii;

const int INF = INT_MAX;
const int64 LINF = LLONG_MAX;
const real EPS = 1e-9;
const int MAXN = 100001;
const int ALPH = 26;

#ifdef DEBUG
  #define _show(a) cerr << #a << " = " << a << endl;
#else
  #define _show(a) (void)42
#endif

struct pt {
  int x, y;
  
  pt()
  : x(0), y(0) {
  }
  
  pt(int x, int y)
  : x(x), y(y) {
  }
  
  pt(const pt &src)
  : x(src.x), y(src.y) {
  }
};

const pt dir[] = { pt(1, 0), pt(0, 1), pt(-1, 0), pt(0, -1) };

pt operator + (const pt &p1, const pt &p2) {
  return pt(p1.x + p2.x, p1.y + p2.y);
}

bool operator == (const pt &p1, const pt &p2) {
  return p1.x == p2.x && p1.y == p2.y;
}

bool operator != (const pt &p1, const pt &p2) {
  return !(p1 == p2);
}

inline pt rotate(const pt &p) {
  if (p == dir[0]) {
    return pt(0, -1);
  }
  
  if (p == dir[1]) {
    return pt(-1, 0);
  }
  
  if (p == dir[2]) {
    return pt(0, 1);
  }
  
  if (p == dir[3]) {
    return pt(1, 0);
  }
  
  return pt();
}

ostream& operator << (ostream &out, const pt &p) {
  return out << "(" << p.x << ", " << p.y << ")";
}

int n;
vector< vector<int> > F;
vector< vector<int> > M[4];
vector< vector<int> > maxw[2];

inline bool is_valid(const pt &p) {
  return 0 <= p.x && p.x < n && 0 <= p.y && p.y < n;
}

pt ans(-1, -1);
int width = 0;
  
void process(const pt &p) {
  pt r = p;
  pt l = r;
  
  while (is_valid(l)) {
    while (l != r) {
      if (r.x - l.x + 1 > maxw[1][r.x][r.y]) {
        r = r + pt(-1, -1);
      } else {
        break;
      }
    }
    
    int w = r.x - l.x + 1;
    if (w <= maxw[1][r.x][r.y] && w <= maxw[0][l.x][l.y]) {
      if (w > width) {
        width = w;
        ans = l + pt(1, 1);
      }
    }
    
    l = l + pt(-1, -1);
  }
}

int main() {
  ios_base::sync_with_stdio(false);

  cin >> n;
  F.resize(n, vector<int> (n));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      cin >> F[i][j];
    }
  }
  
  for (int k = 0; k < 4; ++k) {
    M[k].resize(n, vector<int> (n));
  }
  
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      for (int k = 0; k < 4; ++k) {
        pt p(i, j);
        pt rd = rotate(dir[k]);
        
        if (!is_valid(p + rd)) {
          continue;
        }
        
        int res = 0;
        while (is_valid(p)) {
          pt tmp = p + rd;
          
          if (F[p.x][p.y] == F[tmp.x][tmp.y]) {
            break;
          }
          
          ++res;
          p = p + dir[k];
        }
        
        M[k][i][j] = res;
      }
    }
  }
  
  for (int i = 0; i < 2; ++i) {
    maxw[i].resize(n, vector<int> (n));
  }
  
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      maxw[0][i][j] = min(M[0][i][j], M[1][i][j]);
      maxw[1][i][j] = min(M[2][i][j], M[3][i][j]);
    }
  }
  
  for (int i = 0; i < n; ++i) {
    process(pt(i, n - 1));
  }
  
  for (int i = 0; i < n - 1; ++i) {
    process(pt(n - 1, i));
  }
  
  cout << width << " " << ans.x << " " << ans.y << endl;
}
