#include <bits/stdc++.h>
#pragma GCC optimize("O3", "unroll-loops")
using namespace std;
using pii = pair<long long, long long>;
template <typename T>
using prior = priority_queue<T, vector<T>, greater<T>>;
template <typename T>
using Prior = priority_queue<T>;
const long long INF = 1E18;
const long long mod = 1E9 + 7;
const long long maxn = 2000 + 5;
const long double log_2 = log10(2);
const long double log_3 = log10(3);
long long pre[maxn][maxn][4];
long long dir[maxn][maxn][4];
long long max_cnt2 = 0, max_cnt3 = 0;
long double max_log_Ans = 0;
vector<string> st(maxn);
long long getVal(long long x, long long y, long long len, long long val) {
  long long d0 = pre[x][y - 1][val] - pre[x - 1][y - 1][val] -
                 pre[x][y - len][val] + pre[x - 1][y - len][val];
  long long d1 = pre[x][y + len - 1][val] - pre[x - 1][y + len - 1][val] -
                 pre[x][y][val] + pre[x - 1][y][val];
  long long d2 = pre[x - 1][y][val] - pre[x - 1][y - 1][val] -
                 pre[x - len][y][val] + pre[x - len][y - 1][val];
  long long d3 = pre[x + len - 1][y][val] - pre[x + len - 1][y - 1][val] -
                 pre[x][y][val] + pre[x][y - 1][val];
  return d0 + d1 + d2 + d3 + (st[x][y] - '0' == val);
}
void solve(long long n, long long step, long long tr) {
  for (long long i = 0; i < maxn; ++i) {
    for (long long j = 0; j < maxn; ++j) {
      pre[i][j][0] = pre[i][j][1] = pre[i][j][2] = pre[i][j][3] = 0;
      dir[i][j][0] = dir[i][j][1] = dir[i][j][2] = dir[i][j][3] = 0;
    }
  }
  for (long long i = 1; i <= n; ++i) {
    for (long long j = 1; j <= n; ++j) {
      for (long long k = 0; k < 4; ++k) {
        pre[i][j][k] = pre[i - 1][j][k] + pre[i][j - 1][k] -
                       pre[i - 1][j - 1][k] + (st[i][j] - '0' == k);
      }
    }
  }
  for (long long i = 1; i <= n; ++i) {
    long long lst_L = 0;
    for (long long j = 1; j <= n; ++j) {
      if (st[i][j] == '0') lst_L = j;
      dir[i][j][0] = j - lst_L;
    }
    long long lst_R = n + 1;
    for (long long j = n; j >= 1; --j) {
      if (st[i][j] == '0') lst_R = j;
      dir[i][j][1] = lst_R - j;
    }
    long long lst_U = 0;
    for (long long j = 1; j <= n; ++j) {
      if (st[j][i] == '0') lst_U = j;
      dir[j][i][2] = j - lst_U;
    }
    long long lst_D = n + 1;
    for (long long j = n; j >= 1; --j) {
      if (st[j][i] == '0') lst_D = j;
      dir[j][i][3] = lst_D - j;
    }
  }
  for (long long i = 1; i <= n; ++i) {
    for (long long j = 1; j <= n; ++j) {
      if ((i + j + tr) % step) continue;
      long long dis =
          min({dir[i][j][0], dir[i][j][1], dir[i][j][2], dir[i][j][3]});
      long long cnt2 = getVal(i, j, dis, 2);
      long long cnt3 = getVal(i, j, dis, 3);
      if (log_2 * cnt2 + log_3 * cnt3 > max_log_Ans) {
        max_log_Ans = log_2 * cnt2 + log_3 * cnt3;
        max_cnt2 = cnt2, max_cnt3 = cnt3;
      }
    }
  }
}
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  long long n, fl = 0;
  cin >> n;
  for (long long i = 1; i <= n; ++i) cin >> st[i], st[i] = '0' + st[i];
  for (long long i = 1; i <= n; ++i) {
    for (long long j = 1; j <= n; ++j) {
      if (st[i][j] != '0') fl = 1;
    }
  }
  solve(n, 1, 0);
  vector<string> tmp(maxn, string(maxn, '0'));
  for (long long i = 1; i <= n; ++i) {
    for (long long j = 1; j <= n; ++j) tmp[i + j - 1][n - i + j] = st[i][j];
    if (i < n) {
      for (long long j = 1; j < n; ++j) tmp[i + j][n - i + j] = '1';
    }
  }
  st = tmp;
  solve(2 * n - 1, 2, n % 2 == 0);
  long long max_Ans = 1;
  if (!fl) max_Ans = 0;
  while (max_cnt2--) max_Ans = max_Ans * 2 % mod;
  while (max_cnt3--) max_Ans = max_Ans * 3 % mod;
  cout << max_Ans << "\n";
  return 0;
}
