#include <bits/stdc++.h>
namespace round355d2 {
namespace e {
const int dx[] = {-1, 0, 1, -1, -1, 1, 1, 0};
const int dy[] = {-1, -1, -1, 0, 1, 0, 1, 1};
std::vector<std::vector<std::vector<int>>> p;
std::vector<std::vector<std::vector<std::tuple<int, int, int>>>> pv;
int n;
std::vector<std::vector<int>> a;
const double LOG3 = std::log(3);
const double LOG2 = std::log(2);
int calc_path(int direction, int i, int j) {
  if (i < 0 || i >= n || j < 0 || j >= n) return 0;
  if (p[direction][i][j] == -1) {
    if (a[i][j]) {
      p[direction][i][j] =
          1 + calc_path(direction, i + dy[direction], j + dx[direction]);
    } else {
      p[direction][i][j] = 0;
    }
  }
  return p[direction][i][j];
}
std::tuple<int, int, int> calc_prefix_values(int direction, int i, int j) {
  if (i < 0 || i >= n || j < 0 || j >= n) return std::make_tuple(0, 0, 0);
  if (std::get<0>(pv[direction][i][j]) == -1) {
    if (a[i][j]) {
      auto t =
          calc_prefix_values(direction, i + dy[direction], j + dx[direction]);
      int vs[] = {0, std::get<0>(t), std::get<1>(t), std::get<2>(t)};
      vs[a[i][j]]++;
      pv[direction][i][j] = std::make_tuple(vs[1], vs[2], vs[3]);
    } else {
      pv[direction][i][j] = std::make_tuple(0, 0, 0);
    }
  }
  return pv[direction][i][j];
}
std::tuple<int, int, int> get_range_sum(int direction, int i, int j, int len) {
  if (i < 0 || i >= n || j < 0 || j >= n) return std::make_tuple(0, 0, 0);
  int y = i + len * dy[direction];
  int x = j + len * dx[direction];
  if (y < 0 || y >= n || x < 0 || x >= n) return pv[direction][i][j];
  auto first = pv[direction][i][j];
  auto second = pv[direction][y][x];
  int vs[] = {0, std::get<0>(first) - std::get<0>(second),
              std::get<1>(first) - std::get<1>(second),
              std::get<2>(first) - std::get<2>(second)};
  assert(vs[1] >= 0);
  assert(vs[2] >= 0);
  assert(vs[3] >= 0);
  return std::make_tuple(vs[1], vs[2], vs[3]);
}
std::tuple<int, int, int> sum(std::tuple<int, int, int> first,
                              std::tuple<int, int, int> second) {
  int vs[] = {0, std::get<0>(first) + std::get<0>(second),
              std::get<1>(first) + std::get<1>(second),
              std::get<2>(first) + std::get<2>(second)};
  return std::make_tuple(vs[1], vs[2], vs[3]);
}
std::tuple<int, int, int> sub3(const std::tuple<int, int, int>& first,
                               int value) {
  int vs[] = {0, std::get<0>(first), std::get<1>(first), std::get<2>(first)};
  vs[value] -= 3;
  assert(vs[value] >= 0);
  return std::make_tuple(vs[1], vs[2], vs[3]);
}
int compare(const std::tuple<int, int, int>& first,
            const std::tuple<int, int, int>& second) {
  int vs1[] = {0, std::get<0>(first), std::get<1>(first), std::get<2>(first)};
  int vs2[] = {0, std::get<0>(second), std::get<1>(second),
               std::get<2>(second)};
  double fv = vs1[2] * LOG2 + vs1[3] * LOG3;
  double sv = vs2[2] * LOG2 + vs2[3] * LOG3;
  if (std::fabs(fv - sv) <= std::numeric_limits<double>::epsilon()) {
    return 0;
  }
  return fv < sv ? -1 : 1;
}
int solve(std::istream& in) {
  while (in >> n) {
    bool only_zero = true;
    a.assign(n, std::vector<int>(n, 0));
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        char c;
        in >> c;
        a[i][j] = c - '0';
        only_zero = only_zero && !a[i][j];
      }
    }
    if (only_zero) {
      std::cout << "0\n";
      continue;
    }
    p.resize(8);
    pv.resize(8);
    for (int dir = 0; dir < 8; ++dir) {
      p[dir].assign(n, std::vector<int>(n, -1));
      pv[dir].assign(n, std::vector<std::tuple<int, int, int>>(
                            n, std::make_tuple(-1, 0, 0)));
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
          void(calc_path(dir, i, j));
          void(calc_prefix_values(dir, i, j));
        }
      }
    }
    long long ans = 1;
    std::tuple<int, int, int> best = std::make_tuple(0, 0, 0);
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (a[i][j] == 0) continue;
        int diagonal_len = p[0][i][j];
        int straight_len = p[1][i][j];
        for (int d = 2; d < 8; d += 2) {
          diagonal_len = std::min(diagonal_len, p[d][i][j]);
          straight_len = std::min(straight_len, p[d + 1][i][j]);
        }
        std::tuple<int, int, int> diagonal_sum =
            get_range_sum(0, i, j, diagonal_len);
        std::tuple<int, int, int> straight_sum =
            get_range_sum(1, i, j, straight_len);
        for (int d = 2; d < 8; d += 2) {
          diagonal_sum =
              sum(diagonal_sum, get_range_sum(d, i, j, diagonal_len));
          straight_sum =
              sum(straight_sum, get_range_sum(d + 1, i, j, straight_len));
        }
        diagonal_sum = sub3(diagonal_sum, a[i][j]);
        straight_sum = sub3(straight_sum, a[i][j]);
        if (compare(diagonal_sum, straight_sum) == -1) {
          if (compare(best, straight_sum) == -1) {
            best = straight_sum;
          }
        } else {
          if (compare(best, diagonal_sum) == -1) {
            best = diagonal_sum;
          }
        }
      }
    }
    for (int i = 0; i < std::get<1>(best); ++i) {
      ans = (ans * 2) % 1000000007;
    }
    for (int i = 0; i < std::get<2>(best); ++i) {
      ans = (ans * 3) % 1000000007;
    }
    std::cout << ans << "\n";
  }
  return 0;
}
}  // namespace e
}  // namespace round355d2
int main() {
  std::ios_base::sync_with_stdio(false);
  std::cin.tie(0);
  srand((unsigned)time(0));
  int status = 0;
  do {
    status = round355d2::e::solve(std::cin);
  } while (0);
  return 0;
}
