#include<stdio.h>
#include<string.h>
#include<math.h>
#define MAX 0x7fffffff
struct data
{
int x;
int y;
}p[155];
int fen[155][155];
int v[155];
bool g[155][155];
int yi[155],er[155],nyi,ner,n;
double map[155][155],zui[155],maxmax;
double dis(data a,data b)
{
double xx,yy,s;
xx=a.x-b.x;
yy=a.y-b.y;
s=sqrt(xx*xx+yy*yy);
return s;
}
void floyd()
{
int i,j,k;
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(i!=j)
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}
}
}
double max=0;maxmax=0;
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(map[i][j]!=MAX)
{
if(max<map[i][j])
max=map[i][j];
}
}
zui[i]=max;
if(maxmax<zui[i])
maxmax=zui[i];
max=0;
}
}
int main()
{
int i,j,k;
char a[155];
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
scanf("%d%d",&p[i].x,&p[i].y);
}
getchar();
for(i=1;i<=n;i++)
{
gets(a+1);
for(j=1;j<=n;j++)
{
if(a[j]=='1')
{
map[i][j]=dis(p[i],p[j]);
g[i][j]=1;
}
else
{
map[i][j]=MAX;
g[i][j]=0;
}
}
}
for(k=1;k<=n;k++)
{
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
{
if(g[i][j]==0&&g[i][k]==1&&g[k][j]==1)
g[i][j]=1;
}
}
}
memset(v,0,sizeof(v));
int rt,add;
add=1;
for(i=1;i<=n;i++)
{
if(v[i]==0)
{
for(j=1;j<=n;j++)
{
if(g[i][j]==1)
v[j]=add;
}
v[i]=add;
add++;
}
}
int chang=add-1,nei;
add=1;
for(i=1;i<=n;i++)
{
if(add==chang+1)break;
nei=1;
if(v[i]==add)
{
rt=0;
for(j=1;j<=n;j++)
{
if(g[i][j]==1)
{
fen[add][nei]=j;
rt=1;
nei++;
}
}
fen[add][0]=nei-1;
add++;
}
if(rt==0)
{
fen[add-1][1]=i;
fen[add-1][0]=1;
}
}
floyd();
int x,y,a,b;
double zhi,minzhi=MAX;
for(i=1;i<=chang;i++)
{
for(j=i+1;j<=chang;j++)
{
for(a=1;a<=fen[i][0];a++)
{
for(b=1;b<=fen[j][0];b++)
{
x=fen[i][a];
y=fen[j][b];
map[x][y]=dis(p[x],p[y]);
zhi=zui[x]+zui[y]+map[x][y];
if(minzhi>zhi)
minzhi=zhi;
}
}
}
}
if(maxmax<minzhi)
printf("%.6lf\n",minzhi);
else
printf("%.6lf\n",maxmax);
}
}