#include <bits/stdc++.h>
using namespace std;
auto c2 = [](int64_t a) -> int64_t {
  assert(a >= 0);
  return a * (a - 1) / 2;
};
using bs = bitset<8000>;
int64_t solveScc(int N, vector<vector<bool>> adj) {
  if (N == 0) {
    return 0;
  }
  assert(N >= 3);
  vector<int> inds(N);
  iota(inds.begin(), inds.end(), 0);
  sort(inds.begin(), inds.end(), [&adj](int a, int b) -> bool {
    if (a && b && adj[0][a] != adj[0][b]) return adj[0][b];
    return adj[a][b];
  });
  vector<int> outDeg(N);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      outDeg[i] += adj[i][j];
    }
  }
  for (int i = 0; i < N; i++) {
    assert(i + outDeg[inds[i]] <= i + 1 + outDeg[inds[(i + 1) % N]]);
    for (int j = 1; j <= outDeg[inds[i]]; j++) {
      assert(adj[inds[i]][inds[(i + j) % N]]);
    }
  }
  int ans = 0;
  for (int i = 0; i < N; i++) {
    ans += outDeg[inds[i]] * 1;
    ans +=
        3 * (N - 1 - outDeg[inds[i]]) -
        min(N - 1 - outDeg[inds[i]], outDeg[inds[(i + outDeg[inds[i]]) % N]]);
  }
  return ans;
}
void test() {
  const int N = 8000;
  vector<vector<bool>> adj(N, vector<bool>(N));
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      adj[i][j] = (i < j);
    }
  }
  cerr << solveScc(N, adj) << '\n';
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
  int N;
  scanf("%d", &N);
  vector<vector<bool>> adj(N, vector<bool>(N));
  {
    char* s = new char[N / 4 + 10];
    for (int i = 0; i < N; i++) {
      scanf("%s", s);
      for (int j = 0; j < N / 4; j++) {
        char c = s[j];
        assert(('0' <= c && c <= '9') || ('A' <= c && c <= 'F'));
        int v = ('0' <= c && c <= '9') ? (c - '0') : (10 + (c - 'A'));
        assert(0 <= v && v < 16);
        for (int z = 0; z < 4; z++) {
          adj[i][4 * j + z] = bool(v & (1 << (3 - z)));
        }
      }
    }
    delete[] s;
  }
  const int UNREACHABLE = 614 * N;
  vector<int> inDeg(N);
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (adj[i][j]) inDeg[j]++;
    }
  }
  vector<int> dead;
  dead.reserve(N);
  for (int i = 0; i < N; i++) {
    if (inDeg[i] == 0) {
      dead.push_back(i);
    }
  }
  for (int z = 0; z < int(dead.size()); z++) {
    int cur = dead[z];
    for (int v = 0; v < N; v++) {
      if (adj[cur][v]) {
        assert(inDeg[v] > 0);
        inDeg[v]--;
        if (inDeg[v] == 0) {
          dead.push_back(v);
        }
      }
    }
  }
  int64_t ans = (UNREACHABLE + 1) * (c2(N) - c2(N - int(dead.size())));
  mt19937 mt(48);
  {
    int newN = N - int(dead.size());
    vector<int> aliveInds;
    aliveInds.reserve(newN);
    for (int i = 0; i < N; i++) {
      if (inDeg[i] > 0) {
        aliveInds.push_back(i);
      }
    }
    assert(int(aliveInds.size()) == newN);
    shuffle(aliveInds.begin(), aliveInds.end(), mt);
    vector<vector<bool>> nxtAdj(newN, vector<bool>(newN));
    for (int i = 0; i < newN; i++) {
      for (int j = 0; j < newN; j++) {
        nxtAdj[i][j] = adj[aliveInds[i]][aliveInds[j]];
      }
    }
    N = newN;
    adj = nxtAdj;
  }
  ans += solveScc(N, adj);
  printf("%" PRId64 "\n", ans);
  return 0;
}
