#include <bits/stdc++.h>
using namespace std;
struct Number {
  array<int, 4> x = {{0, 0, 0, 0}};
  Number() {}
  Number(int a) {
    if (a != -1) x[a]++;
  }
  long double log_value() const {
    if (x[0] > 0) return -INFINITY;
    return x[2] * log(2L) + x[3] * log(3L);
  }
  int mod() const {
    long long result = 1;
    for (int i = 0; i < 4; i++)
      for (int j = 0; j < x[i]; j++) result = (result * i) % (int)(1e9 + 7);
    return result;
  }
  bool is_zero() const { return x[0] > 0; }
};
bool operator<(const Number& a, const Number& b) {
  return a.log_value() < b.log_value();
}
Number operator*(const Number& a, const Number& b) {
  Number result;
  for (int i = 0; i < 4; i++) result.x[i] = a.x[i] + b.x[i];
  return result;
}
Number operator/(const Number& a, const Number& b) {
  Number result;
  for (int i = 0; i < 4; i++) result.x[i] = a.x[i] - b.x[i];
  return result;
}
const int MAX = 2005;
int N;
int grid[MAX][MAX];
Number hsum[MAX][MAX];
Number vsum[MAX][MAX];
int ngrid[MAX][MAX];
void precompute() {
  for (int r = 0; r <= N; r++) {
    hsum[r][0] = Number();
    for (int c = 1; c <= N; c++)
      hsum[r][c] = hsum[r][c - 1] * Number(grid[r][c]);
  }
  for (int c = 0; c <= N; c++) {
    vsum[0][c] = Number();
    for (int r = 1; r <= N; r++)
      vsum[r][c] = vsum[r - 1][c] * Number(grid[r][c]);
  }
}
Number getv(int r, int c, int l) {
  int r1 = r - l, r2 = r + l;
  if (r1 <= 0 || r2 > N) return Number(0);
  return vsum[r2][c] / vsum[r1 - 1][c];
}
Number geth(int r, int c, int l) {
  int c1 = c - l, c2 = c + l;
  if (c1 <= 0 || c2 > N) return Number(0);
  return hsum[r][c2] / hsum[r][c1 - 1];
}
bool works(int r, int c, int l) {
  Number x = getv(r, c, l) * geth(r, c, l);
  return !x.is_zero();
}
Number solve(int r, int c) {
  if (grid[r][c] == 0 || grid[r][c] == -1) return Number(0);
  int a = 0, b = N;
  while (a < b) {
    int mid = (a + b + 1) / 2;
    if (works(r, c, mid))
      a = mid;
    else
      b = mid - 1;
  }
  return geth(r, c, a) * getv(r, c, a) / Number(grid[r][c]);
}
Number solve() {
  precompute();
  Number best(0);
  for (int r = 1; r <= N; r++)
    for (int c = 1; c <= N; c++) best = max(best, solve(r, c));
  return best;
}
void rotate() {
  for (int r = 1; r <= 2 * N - 1; r++)
    for (int c = 1; c <= 2 * N - 1; c++)
      if ((r + c) % 2 != (N - 1) % 2) ngrid[r][c] = -1;
  for (int r = 1; r <= N; r++)
    for (int c = 1; c <= N; c++) ngrid[r - c + N][r + c - 1] = grid[r][c];
  memcpy(grid, ngrid, sizeof(grid));
  N = 2 * N - 1;
}
int main() {
  cin >> N;
  for (int i = 1; i <= N; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < N; j++) grid[i][j + 1] = s[j] - '0';
  }
  Number result = solve();
  rotate();
  Number result2 = solve();
  cout << max(result, result2).mod() << endl;
}
