//牛的旅行Cow Tours
//至少两个牧区不连通
//新增一条路径使新牧场的直径尽可能小
//求新牧场直径的最小值
//无向图
//数字保留小数点后6位
//一个牧区的直径是牧场中最大的最短路
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int N = 150;
const double INF = 1e7;
int n;//牧区数(点数)
double x[N],y[N];//牧区坐标(点的坐标)
int m[N][N];//邻接矩阵
double g[N][N];//两点之间的权值
int p[N];//并查集祖先节点
double sz[N];//所在牧场的直径
double dist[N][N];//两点之间的最短距离
double d[N];//从各点到其他点的最长最短路
double ans = INF;
//初始化并查集
void init(){
for(int i = 1;i <= n;i++){
p[i] = i;
}
}
//查找祖先节点
int find(int x){
if(p[x] != x){
p[x] = find(p[x]);
}
return p[x];
}
//Floyd算法
void floyd(){
for(int k = 1;k <= n;k++){
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
dist[i][j] = min(dist[i][j],dist[i][k] + dist[k][j]);
}
}
}
}
int main(){
//输入
//scanf("%d",&n);
cin >> n;
//初始化邻接矩阵
//memset(g,0x3f,sizeof(g));
for(int i = 1;i <= n;i++){
//scanf("%lf %lf",&x[i],&y[i]);
cin >> x[i] >> y[i];
}
//初始化并查集
init();
//初始化距离
//memset(dist,0x3f,sizeof(dist));
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
dist[i][j] = INF;
}
}
char op;
for(int i = 1;i <= n;i++){
//char s[N];
//scanf("%s",s);
//string s;
//cin >> s;
for(int j = 1;j <= n;j++){
//scanf("%c",&m[i][j]);
//cin >> m[i][j];
//m[i][j] = s[j - 1];
//scanf("%1d",&op);
/*do{
op = getchar();
}while(op != '0' && op != '1');*/
//cin >> op;
/*do{
scanf("%c",&op);
}while(op != '0' && op != '1');*/
scanf("%1d",&m[i][j]);
if(i == j){
dist[i][j] = 0;
}else if(m[i][j] == 1){
//两点直接相连
dist[i][j] = sqrt((y[j] - y[i]) * (y[j] - y[i]) + (x[j] - x[i]) * (x[j] - x[i]));
//合并节点到同一集合中
if(find(i) != find(j)){
p[find(i)] = find(j);
}
}
}
}
/*for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
printf("%lf ",dist[i][j]);
}
printf("\n");
}*/
//求任意两点之间的距离
floyd();
//求从各点到所在牧区中其他点的最长最短路
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(dist[i][j] != INF){
d[i] = max(dist[i][j],d[i]);
sz[find(i)] = max(sz[find(i)],d[i]);
}
}
}
//枚举
for(int i = 1;i <= n;i++){
for(int j = 1;j <= n;j++){
if(find(i) != find(j)){
double ij = sqrt((y[j] - y[i]) * (y[j] - y[i]) + (x[j] - x[i]) * (x[j] - x[i]));
//不在一个集合里
ans = min(ans,max(d[i] + d[j] + ij,max(sz[find(i)],sz[find(j)])));
}
}
}
//输出
printf("%.6lf\n",ans);
return 0;
}