#include <bits/stdc++.h>
#define MAX(a,b,c) max(a,max(b,c))
#define maxn 1010
using namespace std;
const int inf = 2147483647;
int n, m, s, cnt;
struct Node {
double x, y;
} a[maxn];
struct EDGE {
int to, nxt;
double w;
} e[maxn << 1];
int c[maxn][maxn];
int head[maxn << 1];
double dis[maxn][maxn];
bool vis[maxn];
inline void add(int a, int b, double c) {
e[++cnt].to = b;
e[cnt].w = c;
e[cnt].nxt = head[a];
head[a] = cnt;
}
struct node {
int v;
double w;
friend bool operator < (node a, node b) {
return a.w > b.w;
}
} tmp;
priority_queue<node> q;
void dijkstra() {
for (int i = 1; i <= n; i++)
dis[s][i] = inf, vis[i] = false;
dis[s][s] = 0;
tmp.v = s;
tmp.w = 0;
q.push(tmp);
while (!q.empty()) {
int u = q.top().v;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
double w = e[i].w;
if (dis[s][v] > dis[s][u] + w) {
dis[s][v] = dis[s][u] + w;
tmp.w = dis[s][v];
tmp.v = v;
q.push(tmp);
}
}
}
}
double diss(int x, int y, int xx, int yy) {
return sqrt((x - xx) * (x - xx) + (y - yy) * (y - yy));
}
double dir[100100];
vector<int> Col[maxn];
double zhi[10100];
double ans = 0;
char ch[2010];
int col[maxn];
int t;
void dfs(int u, int fa) {
for (int i = head[u]; i ; i = e[i].nxt) {
int to = e[i].to;
if (fa == u) continue;
if (!col[to]) {
col[to] = cnt;
Col[cnt].push_back(to);
dfs(to, u);
}
}
}
signed main() {
scanf("%d", &n);
dijkstra();
for (int i = 1; i <= n; i++)
scanf("%lf %lf", &a[i].x, &a[i].y);
for (int i = 1; i <= n; i++) {
scanf("%s", ch + 1);
for (int j = 1; j <= n; j++) {
if (ch[j] == '1') {
double w = diss(a[i].x, a[i].y, a[j].x, a[j].y);
c[i][j] = c[j][i] = w;
add(i, j, w);
add(j, i, w);
}
}
}
for (int i = 1; i <= n; i++) {
if (!col[i]) {
cnt++;
Col[cnt].push_back(i);
col[i] = cnt;
dfs(i, 0);
}
}
s = 1;
for (int i = 1; i <= n; i++, s = i)
dijkstra();
memset(dir, 0, sizeof dir);
for (int i = 1; i <= cnt; i++) {
for (int j = 0; j < Col[i].size(); j++) {
int from = Col[i][j];
for (int h = j + 1; h < Col[i].size(); h++) {
int to = Col[i][h];
if (dis[from][to] == inf) continue;
else dir[h] = max(dir[h], dis[from][to]);
if (dis[to][from] == inf) continue;
else dir[j] = max(dir[j], dis[to][from]);
}
zhi[i] = max(dir[j], zhi[i]);
}
}
ans = 0x3f3f3f3f;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
if (col[i] == col[j]) continue;
ans = min(ans, MAX(zhi[col[i]], zhi[col[j]], dir[i] + c[i][j] + dir[j]));
}
}
cout << ans;
return 0;
}