#include<bits/stdc++.h>
using namespace std;
const double inf = 1e20;
char ch[160][160];
int n,fa[160];
double mdis[160],dis[160][160],maxn,minn=inf,religion[160];
struct ndoe{
int x,y;
}a[160];
inline int read(){
int s=0;
char ch=getchar();
while(ch<'0'||ch>'9')ch=getchar();
while(ch<='9'&&ch>='0'){
s=s*10+ch-'0';
ch=getchar();
}
return s;
}
double length(int x,int y){
return sqrt((a[x].x -a[y].x )*(a[x].x -a[y].x )+(a[x].y -a[y].y )*(a[x].y -a[y].y ));
}
int find(int x){
if(fa[x]==x)return x;
else return fa[x]=find(fa[x]);
}
double my_max(double a,double b){
if(a>b)return a;
else return b;
}
int main(){
n=read();
for(int i=1;i<=n;i++){
a[i].x =read();a[i].y =read();
fa[i]=i;
}
memset(mdis,-1,sizeof(mdis));
for(int i=1;i<=n;i++){
scanf("%s",ch[i]+1);
//for(int j=1;j<=n;j++)cout<<ch[i][j];cout<<endl;//
for(int j=1;j<=n;j++){
if(ch[i][j]=='1'||i==j){
dis[i][j]=length(i,j);
fa[j]=find(fa[i]);
//cout<<j<<" "<<fa[j]<<endl;//
}else dis[i][j]=inf;
}
}
/*for(int i=1;i<=n;i++){//
for(int j=1;j<=n;j++)cout<<dis[i][j]<<" ";//
cout<<endl;//
}//*/
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
if(dis[i][j]>dis[i][k]+dis[k][j])dis[i][j]=dis[i][k]+dis[k][j];
}
}
}
for(int i=1;i<=n;i++){
int jz=fa[i];
for(int j=1;j<=n;j++){
if(fa[j]==jz){
mdis[i]=my_max(mdis[i],dis[i][j]);
religion[jz]=my_max(religion[jz],mdis[i]);
}
}
}
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
if(fa[i]!=fa[j]){
maxn=my_max(my_max(religion[fa[i]],religion[fa[j]]),mdis[i]+mdis[j]+length(i,j));
minn=min(minn,maxn);
}
}
}
for(int i=1;i<=n;i++){
minn=my_max(minn,religion[fa[i]]);
}
printf("%.6lf",minn);
return 0;
}