#include <bits/stdc++.h>

using namespace std;
#define int long long
const int maxn=105;
int a[maxn][maxn];
int b[maxn][maxn];
int cn[maxn];
bool used[maxn];
int cnt;
void dfs(int x)
{
    ++cnt;
    used[x]=true;
    for(int i=0;i<maxn;++i)
    {
        if(b[x][i] && !used[i])
        {
            dfs(i);
        }
    }
}
double c(int n,int k)
{
    double ans=1;
    for(int i=(n-k+1);i<=n;++i) ans*=i;
    for(int i=1;i<=k;++i) ans/=i;
    return ans;
}
int32_t main()
{
    ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=0;i<n;++i)
    {
        string s;
        cin>>s;
        for(int j=0;j<n;++j) {a[i][j]=(s[j]-'0');b[j][i]=a[i][j];}
    }
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<maxn;++j) used[j]=false;
        cnt=0;
        dfs(i);
        cn[i]=cnt;
    }
    double ans=0;
    for(int i=0;i<n;++i)
    {
        for(int j=0;j<n;++j)
        {
            ans+=c(n-cn[i],j)/c(n-1,j);
        }
    }
    cout<<setprecision(25)<<ans/(n+0.0);
    return 0;
}

#define _USE_MATH_DEFINES
#include <iostream>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <queue>
#include <algorithm>
#include <climits>
#include <cstring>
#include <cmath>
#include <stack>
#include <iomanip>
#include <tuple>
#include <functional>
#include <cfloat>
#include <map>
#include <set>
#include <array>
#include <stdio.h>
#include <string.h>
#include <random>
#include <cassert>
using ll = long long;
using ull = unsigned long long;
using uint = unsigned int;
using namespace std;
#define int long long
#define CONTAINS_VEC(v,n) (find((v).begin(), (v).end(), (n)) != (v).end())
#define SORT(v) sort((v).begin(), (v).end())
#define RSORT(v) sort((v).rbegin(), (v).rend())
#define ARY_SORT(a, size) sort((a), (a)+(size))
#define REMOVE(v,a) (v.erase(remove((v).begin(), (v).end(), (a)), (v).end()))
#define REVERSE(v) (reverse((v).begin(), (v).end()))
#define ARY_REVERSE(v,a) (reverse((v), (v)+(a)))
#define REP(i, n) for (int (i)=0; (i) < (n); (i)++)
#define REPE(i, n) for (int (i)=0; (i) <= (n); (i)++)
#define CONTAINS_MAP(m, a) ((m).find((a)) != m.end())
#define CONTAINS_SET(m, a) ((m).find((a)) != m.end())
void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; exit(0); }
void Yes() { cout << "Yes" << endl; exit(0); }
void No() { cout << "No" << endl; exit(0); }



//---------- セグ木 ----------
const int  SEG_MAX = (1 << 18); //1<<18 = 2^18 = 262144
struct SegTree
{
	vector<int> seg;

	SegTree() : seg(SEG_MAX * 2, 0) {}

	//[a,b]にxを加算 (節点kをベースに[l,r]に足す)
	void add(int a, int b, int x, int k = 0, int l = 0, int r = SEG_MAX - 1)
	{
		if (a <= l && r <= b)
		{
			seg[k] += x;
		}
		else
		{
			int l0 = l;
			int r0 = l + (r - l) / 2;
			int l1 = r0 + 1;
			int r1 = r;
			if (a <= r0)
			{
				int kk = 2 * k + 1;
				add(a, b, x, kk, l0, r0);
			}
			if (l1 <= b)
			{
				int kk = 2 * k + 2;
				add(a, b, x, kk, l1, r1);
			}
		}
	}

	int get(int index)
	{
		int sum = 0;
		int k = SEG_MAX - 1 + index; //根
		while (true)
		{
			sum += seg[k];
			if (k == 0) break;
			k = (k - 1) / 2;
		}
		return sum;
	}
};



struct St
{
	int index;
	int n;
	bool operator < (const St& st) const
	{
		return (index > st.index); //(昇順)
	}
};

int N;
map<int, priority_queue<St>> _m;
int B[200010];

signed main()
{
	cin >> N;
	REP(i, N)
	{
		St st;
		cin >> st.n;
		st.n += i;
		st.index = i;
		_m[st.n].push(st);
	}

	REP(i, N)
	{
		cin >> B[i];
	}

	SegTree offset;

	int ans = 0;
	for (int i = 0; i < N; i++)
	{
		int b = B[i] + i;
		if (_m[b].size() == 0)
		{
			cout << -1 << endl;
			return 0;
		}

		St st = _m[b].top();
		_m[b].pop();

		int a = st.index + offset.get(st.index);
		int sub = a - i;
		ans += sub;

		offset.add(0, st.index, 1);

	//	//for (int i = 0; i < N; i++)
	//	//{
	//	//	cout << offset.get(i) << " ";
	//	//}
	//	//cout << endl;
	}
	cout << ans << endl;
}



