#include<iostream>
#include<cmath>
#include<algorithm>
#include<cstring>
#include<vector>
#include<stack>
#include<cstdlib>
#include<queue>
#include<cstdio>
#include<numeric>
#include<string>
#include<iomanip>
#include<set>
#include<map>
#include<sstream>
#define PII pair<int,int>
#define x first
#define y second
#define PIII pair<int,pair<int,int>>
typedef long long ll;
using namespace std;
const double INF = 1e21;
const int N = 160,M= 3e5;
const ll mod = 1e9 + 7;
int n, m;
double dist[N][N];
double dmax[N];
char g[N][N];
PII a[N];
double get_dist(PII a, PII b)
{
int dx = a.x - b.x, dy = a.y - b.y;
return sqrt(dx * dx + dy * dy);
}
void floyd()
{
for (int k = 0; k < n; k++)
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
}
int main()
{
cin.tie(0); cout.tie(0)->ios::sync_with_stdio(false);
cin >> n;
for (int i = 0; i < n; i++)cin >> a[i].x >> a[i].y;
for (int i = 0; i < n; i++)cin >> g[i];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (i != j)
{
if(g[i][j]=='1')dist[i][j] = get_dist(a[i],a[j]);
else dist[i][j] = INF;
}
floyd();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if(dist[i][j]<INF)
dmax[i] = max(dmax[i], dist[i][j]);
double res1 = 0;
for (int i = 0; i < n; i++)res1 = max(res1, dmax[i]);
double res2 = INF;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if (dist[i][j] >= INF)
{
res2 = min(res2, get_dist(a[i], a[j]) + dmax[i] + dmax[j]);
}
cout << fixed<<setprecision(6)<<max(res1,res2);
return 0;
}