#include<bits/stdc++.h>
#include <iomanip>
using namespace std;
#define pb push_back
#define ll long long int
#define pll pair<ll,ll>

    vector <int> g[102], gr[102];
    int comp_size[102];
    vector<bool> used;
	int num = 0;
    void dfs1 (int v) {
        used[v] = true;
        ++num;
        for (size_t i=0; i<gr[v].size(); ++i){
        	if (!used[ gr[v][i] ]){
        		dfs1 (gr[v][i]);
			}   
		}
            
    }

    int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    std::cout << std::setprecision(12) ;
    std::cout << std::fixed;
    double ans = 0.0;
    
     int n;
     cin>>n;
     string s[n];
     for(int i=0;i<n;i++){
     cin>>s[i];
     for(int j=0;j<n;j++){
       		if(s[i][j]=='1'){
       			g[i].push_back (j);
            	gr[j].push_back (i);
			   }
		   }
	 }

       
        for (int i=0; i<n; ++i){
        	 used.assign (n, false);
        	 num =0;
        	 dfs1(i);
        	 ans = ans +(1.0/(double)(num));
		}
		
		cout<<ans<<"\n";
    }

#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,sse4.1,sse4.2,popcnt,mmx,avx")
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
typedef long double ld;
#define PB push_back
#define MP make_pair
#define endl "\n"
#define fst first
#define snd second
const int UNDEF = -1;
const int INF=1<<30;
template<typename T> inline bool chkmax(T &aa, T bb) { return aa < bb ? aa = bb, true : false; }
template<typename T> inline bool chkmin(T &aa, T bb) { return aa > bb ? aa = bb, true : false; }
typedef pair<ll,ll> pll;typedef vector<ll> vll;typedef pair<int,int> pii;typedef vector<int> vi;typedef vector<vi> vvi;typedef vector<pii> vpii;typedef vector<pll> vpll;
template<typename T> void makeunique(vector<T> &vx) {sort(vx.begin(),vx.end());auto it=unique(vx.begin(),vx.end());vx.resize(std::distance(vx.begin(),it));}


vvi g;
vi vdeg;
const int n=400000+8;
void solve(long long nume, std::vector<long long> a, std::vector<long long> b){
  g.resize(n+1);
  vdeg.resize(n+1);
  for (int i=0;i<nume;i++) {
    int x=a[i],y=b[i];
    g[x].PB(y); g[y].PB(x);
  }
  queue<int> q;
  for (int x=1;x<=n;x++) {
    int deg=g[x].size();
    vdeg[x]=(deg);
    if (deg==1) q.push(x);
  }
  int ones=0;
  while(!q.empty()) {
    int x=q.front(); q.pop();
    if (vdeg[x]==1) {
      ones++;
      vdeg[x]--;
      for (auto &y:g[x]) {
        --vdeg[y];
        if (vdeg[y]==1) q.push(y);
      }
    }
  }
  int final=ones;
  for (int x=1;x<=n;x++) if(vdeg[x]>0) final++;
  printf("%d\n",final);
}

// Generated by 1.1.7.1 https://github.com/kyuridenamida/atcoder-tools  (tips: You use the default template now. You can remove this line by using your custom template)
int main(){
    long long N;
    scanf("%lld",&N);
    std::vector<long long> a(N);
    std::vector<long long> b(N);
    for(int i = 0 ; i < N ; i++){
        scanf("%lld",&a[i]);
        scanf("%lld",&b[i]);
    }
    solve(N, std::move(a), std::move(b));
    return 0;
}
