#include <bits/stdc++.h>
using namespace std;
template <class L, class R>
ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}
template <class T>
ostream &operator<<(ostream &os, set<T> V) {
  os << "[";
  for (auto vv : V) os << vv << ",";
  return os << "]";
}
template <class T>
ostream &operator<<(ostream &os, vector<T> V) {
  os << "[";
  for (auto vv : V) os << vv << ",";
  return os << "]";
}
template <class K, class X>
ostream &operator<<(ostream &os, map<K, X> V) {
  os << "[";
  for (auto vv : V) os << vv << ",";
  return os << "]";
}
void debug_out() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << H;
  debug_out(T...);
}
string conv(char ch) {
  switch (ch) {
    case '0':
      return "0000";
    case '1':
      return "0001";
    case '2':
      return "0010";
    case '3':
      return "0011";
    case '4':
      return "0100";
    case '5':
      return "0101";
    case '6':
      return "0110";
    case '7':
      return "0111";
    case '8':
      return "1000";
    case '9':
      return "1001";
    case 'A':
      return "1010";
    case 'B':
      return "1011";
    case 'C':
      return "1100";
    case 'D':
      return "1101";
    case 'E':
      return "1110";
    case 'F':
      return "1111";
    default:
      return "0000";
  }
}
bool check(vector<vector<int> > &pre, int x) {
  int n = pre.size(), m = n / x;
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < m; j++) {
      int a = min(n - 1, x * (i + 1) - 1), b = min(n - 1, x * (j + 1) - 1);
      int c = x * i - 1, d = x * j - 1;
      int temp = pre[a][b];
      if (c >= 0) temp -= pre[c][b];
      if (d >= 0) temp -= pre[a][d];
      if (c >= 0 && d >= 0) temp += pre[c][d];
      if (temp == 0 || temp == (a - x * i + 1) * (b - x * j + 1))
        continue;
      else
        return false;
    }
  }
  return true;
}
int32_t main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  vector<string> mat(n);
  for (int i = 0; i < n; i++) {
    string s;
    cin >> s;
    for (char ch : s) mat[i].append(conv(ch));
  }
  vector<vector<int> > row(n, vector<int>(n, 0));
  for (int i = 0; i < n; i++) {
    row[i][0] = mat[i][0] == '0';
    for (int j = 1; j < n; j++) {
      row[i][j] = row[i][j - 1] + (mat[i][j] == '0');
    }
  }
  for (int i = 1; i < n; i++) {
    for (int j = 0; j < n; j++) {
      row[i][j] = row[i - 1][j] + row[i][j];
    }
  }
  int low = 1, high = n, mid;
  while (low < high - 1) {
    mid = (low + high) / 2;
    if (check(row, mid)) {
      low = mid;
    } else {
      high = mid - 1;
    }
  }
  if (check(row, high))
    cout << high << endl;
  else
    cout << low << endl;
  return 0;
}
