#include <bits/stdc++.h>
#define IOS ios::sync_with_stdio(0) , cin.tie(0) , cout.tie(0)
#define INF 0x3f3f3f3f
#define LL long long
using namespace std;
const int N = 160;
int n , pos = 1;
double dp[N][N] , zj[N] , max_d[N];
bool vis[N];
struct node{
int x , y , id;
double d(const node & b) {
return sqrt((x - b.x) * (x - b.x) + (y - b.y) * (y - b.y));
}
} a[N];
void DFS(int i , int pos) {
a[i].id = pos;
vis[i] = 1;
for(int j = 1;j <= n;++ j){
if(!vis[j] && dp[i][j] != INF) DFS(j , pos);
}
}
int main() {
//IOS;
cin >> n;
for(int i = 1;i <= n;++ i) cin >> a[i].x >> a[i].y;
for(int i = 1;i <= n;++ i){
for(int j = 1;j <= n;++ j){
char ch;
cin >> ch;
if(ch == '1' || i == j) {
dp[i][j] = a[i].d(a[j]);
} else dp[i][j] = INF;
}
}
for(int i = 1;i <= n;++ i){
if(!vis[i]) DFS(i , pos ++);
}
for(int h = 1;h <= n;++ h){
for(int i = 1;i <= n;++ i){
for(int j = 1;j <= n;++ j){
dp[i][j] = min(dp[i][j] , dp[i][h] + dp[h][j]);
}
}
}
for(int i = 1;i <= n;++ i){
double tmp = 0;
for(int j = 1;j <= n;++ j){
if(i == j) continue;
if(dp[i][j] == INF) continue;
tmp = max(dp[i][j] , tmp);
}
max_d[i] = tmp;
}
for(int i = 1;i <= pos;++ i) zj[i] = 0;
for(int i = 1;i <= pos;++ i){
for(int s = 1;s <= n;++ s){
if(a[s].id != pos) continue;
for(int t = s + 1;t <= n;++ t){
if(a[t].id != pos) continue;
if(dp[s][t] == INF) continue;
double D = dp[s][t];
zj[i] = max(zj[i] , D);
}
}
}
double ans = INF , maxD = -INF;
for(int i = 1;i <= n;++ i){
for(int j = i + 1;j <= n;++ j){
if(dp[i][j] != INF) continue;
maxD = max(zj[a[i].id] , max(zj[a[j].id] , max_d[i] + max_d[j] + a[i].d(a[j])));
ans = min(ans , maxD);
}
}
printf("%.6lf\n" , ans);
return 0;
}
WA 7