#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3 + 10;
ll ans;
int n;
int head[maxn], len;
int head1[maxn], a[maxn], b[maxn], len1;
char s[maxn];
int front = 1, enddd = 1;
int que[maxn], du[maxn];
struct edge{
int from;
int to;
int next;
}e[maxn * maxn >> 1], e1[maxn * maxn >> 1];
void insert(int u, int v){
e[++len].to = v;
e[len].from = u;
e[len].next = head[u];
head[u] = len;
}
void insert1(int u, int v){
e1[++len].to = v;
e1[len].from = u;
e1[len].next = head1[u];
head1[u] = len1;
}
int cnt, top, tot;
int dfn[maxn], low[maxn];
int stac[maxn], belong[maxn];
bool insta[maxn], done[maxn][maxn];
void tarjan(int u){
dfn[u] = low[u] = ++cnt;
stac[++top] = u;
insta[u] = 1;
for(int i = head[u]; i; i = e[i].next){
int v = e[i].to;
if(!dfn[v]){
tarjan(v);
low[u] = min(low[u], low[v]);
} else if(insta[v]) low[u] = min(low[u], dfn[v]);
}
if(dfn[u] == low[u]){
++tot;
while(stac[top + 1] != u){
++b[tot];
int k = stac[top --];
insta[k] = 0;
belong[k] = tot;
}
}
}
void make(){
for(int i = 1; i <= len; ++i){
int u = belong[e[i].from];
int v = belong[e[i].to];
if(u != v && !done[u][v]){
done[u][v] = 1;
insert1(v, u);
++du[v];
}
}
}
void dfs(int u){
for(int i = head1[u]; i; i = e1[i].next){
int v = e1[i].to;
a[v] += a[u];
--du[v];
if(!du[v]) que[enddd++] = v;
}
}
bool gc(){
char x = getchar();
if(x!='0'&&x!='1'){
return gc();
}
else{
return x - '0';
}
}
void sol(){
scanf("%d", &n);
for(int i = 1; i <= n; ++i){
for(int j = 1; j <= n; ++j){
if (gc()) insert(i, j);
}
}
for(int i = 1; i <= n; ++i){
if(!dfn[i]) tarjan(i);
}
make();
for(int i = 1; i <= tot; ++i)
a[i] = b[i];
for(int i = 1; i <= tot; ++i)
if(!du[i]) que[enddd++] = i;
for(; front < enddd; ++front){
int u = que[front];
dfs(u);
ans += 1LL * a[u] * b[u];
}
printf("%lld", ans);
}
int main(){
sol();
return 0;
}