#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

using namespace std;

class Tarjan {
public:
  int n;
  vector<vector<int>> graph;

  stack<int> S;
  int clock;
  vector<int> timestamp;
  vector<int> low;
  vector<bool> on_stack;
  vector<vector<int>> blocks;
  vector<int> belongs;
  int n_blocks;
  vector<vector<int>> block_graph;

  void init(int n_) {
    n = n_;
    graph.resize(n);
    for (int i = 0; i < n; ++i) {
      graph[i].clear();
    }
  }

  void add_edge(int u, int v) { graph[u].push_back(v); }

  void dfs(int u) {
    timestamp[u] = clock;
    low[u] = clock;
    ++clock;

    S.push(u);
    on_stack[u] = true;

    for (int v : graph[u]) {
      if (timestamp[v] == -1) {
        dfs(v);
        low[u] = min(low[u], low[v]);
      } else if (on_stack[v]) {
        low[u] = min(low[u], timestamp[v]);
      }
    }

    if (low[u] == timestamp[u]) {
      vector<int> nodes;
      for (;;) {
        int w = S.top();
        S.pop();
        on_stack[w] = false;
        nodes.push_back(w);
        if (w == u) {
          break;
        }
      }
      blocks.push_back(nodes);
    }
  }

  void calc_blocks() {
    clock = 0;
    timestamp.resize(n, -1);
    low.resize(n, -1);
    on_stack.resize(n, false);
    blocks.clear();
    for (int i = 0; i < n; ++i) {
      if (timestamp[i] == -1) {
        dfs(i);
      }
    }
  }

  void build_block_graph() {
    n_blocks = blocks.size();
    belongs.resize(n, -1);
    for (int i = 0; i < n_blocks; ++i) {
      for (int u : blocks[i]) {
        belongs[u] = i;
      }
    }
    vector<unordered_set<int>> uniq_edge_graph(n_blocks);
    for (int u = 0; u < n; ++u) {
      for (int v : graph[u]) {
        if (belongs[u] != belongs[v]) {
          uniq_edge_graph[belongs[u]].insert(belongs[v]);
        }
      }
    }
    block_graph.resize(n_blocks);
    for (int i = 0; i < n_blocks; ++i) {
      block_graph[i].clear();
      for (int u : uniq_edge_graph[i]) {
        block_graph[i].push_back(u);
      }
    }
  }

  long double topological_sort() {
    vector<int> in_degree(n_blocks, 0);
    vector<int> size(n_blocks, 0);
    vector<bitset<100>> ancestors(n_blocks);

    for (int u = 0; u < n_blocks; ++u) {
      size[u] = blocks[u].size();
      ancestors[u].reset();
      for (int v : block_graph[u]) {
        in_degree[v]++;
      }
    }
    queue<int> Q;
    for (int i = 0; i < n_blocks; ++i) {
      if (in_degree[i] == 0) {
        Q.push(i);
      }
    }
    long double expected_val = 0;
    while (!Q.empty()) {
      int u = Q.front();
      Q.pop();
      int count = 0;
      for (int i = 0; i < n_blocks; ++i) {
        if (ancestors[u][i]) {
          count += size[i];
        }
      }
      expected_val += 1.0 * size[u] / (size[u] + count);
      for (int v : block_graph[u]) {
        ancestors[v] |= ancestors[u];
        ancestors[v].set(u);
        in_degree[v]--;
        if (in_degree[v] == 0) {
          Q.push(v);
        }
      }
    }
    return expected_val;
  }
};

Tarjan tarjan;

int main() {

  ios::sync_with_stdio(false);
  cin.tie(0);
  cout << setprecision(20);

  int n;
  cin >> n;
  vector<string> s(n);
  for (int i = 0; i < n; ++i) {
    cin >> s[i];
  }

  tarjan.init(n);
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < n; ++j) {
      if (s[i][j] == '1') {
        tarjan.add_edge(i, j);
      }
    }
  }

  tarjan.calc_blocks();
  tarjan.build_block_graph();
  cout << tarjan.topological_sort() << endl;
  return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int max_n = 111, inf = 1000111222;

int n, f[max_n][max_n];
string s;

int main() {
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> s;
        for (int j = 0; j < n; ++j) {
            f[i][j] = s[j] - '0';
        }
        f[i][i] = 1;
    }
    for (int k = 0; k < n; ++k) {
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                f[i][j] |= f[i][k] & f[k][j];
            }
        }
    }
    long double ans = 0;
    for (int i = 0; i < n; ++i) {
        int cnt = 0;
        for (int j = 0; j < n; ++j) {
            cnt += f[j][i];
        }
        ans += 1.0l / cnt;
    }
    cout << fixed << setprecision(20) << ans << endl;
    return 0;
}
