#include<bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
int n,vis[210],sum=0,sumn[1010],fa[100010];
double path[210][210],max_d=0,min_d=INF,max_distance[100010],diameter[100010];
char s[10010];
struct node{
int x,y;
}f[210];
double distance(int xa,int ya,int xb,int yb){
return sqrt(pow(abs(xa-xb),2)+pow(abs(ya-yb),2));
}
int find(int x){
if(fa[x]==x) return x;
return fa[x]=find(fa[x]);
}
void dfs(int g){
for(int i=1;i<=n;i++)
if(path[g][i]<INF&&!vis[i])
vis[i]=1,fa[i]=find(g),dfs(i);
}
int main(){
cin>>n;
for(int i=1;i<=n;i++) cin>>f[i].x>>f[i].y,fa[i]=i;
for(int i=1;i<=n;i++)
{
cin>>s;
for(int j=0;j<n;j++){
if(s[j]=='1'||i==j)
path[i][j+1]=distance(f[i].x,f[i].y,f[j+1].x,f[j+1].y);
else
path[i][j+1]=INF;
}
}
for(int i=1;i<=n;i++)
if(!vis[i]) vis[i]=1,dfs(i);
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
path[i][j]=min(path[i][j],path[i][k]+path[k][j]);
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++)
if(path[i][j]<INF)
max_distance[i]=max(max_distance[i],path[i][j]);
diameter[find(i)]=max(diameter[find(i)],max_distance[i]);
}
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++){
int o=find(i),p=find(j);
if(o!=p){
max_d=max(max(max(diameter[o],diameter[p]),max_distance[i]+max_distance[j]+distance(f[o].x,f[o].y,f[p].x,f[p].y)),max_d);
min_d=min(min_d,max_d);
}
}
printf("%.6lf",min_d);
return 0;
}