#include<algorithm>
#include<complex>
#include<cstdio>
#include<iostream>
#include<queue>

using namespace std;

#define rep(i, n) for (int i = 0; i < int(n); ++i)
template<class T> T at(vector<T> v, int i) {return v[i % v.size()];}

#define X real()
#define Y imag()

typedef long double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;
const D PI = acos(-1);

// 比較関数
int sig(D a, D b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
bool near(P a, P b) {return !sig(norm(a - b));}
namespace std {
  bool operator<(P a, P b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
  bool operator<(L a, L b) {return !near(a.a, b.a) ? a.a < b.a : a.b < b.b;}
}

// 平方根
D sr(D a) {return sqrt(max(a, (D)0));}

// 内積
D dot(P a, P b) {return a.X * b.X + a.Y * b.Y;}
// 外積
D det(P a, P b) {return a.X * b.Y - a.Y * b.X;}

// 線分のベクトル
P vec(L a) {return a.b - a.a;}

// 線分abに対する点cの位置
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
int ccw(P a, P b, P c) {
  if (near(a, c) || near(b, c)) return ON;
  int s = sig(det(b - a, c - a));
  if (s) return s > 0 ? LEFT : RIGHT;
  return (a < b) == (b < c) ? FRONT : (c < a) == (a < b) ? BACK : ON;
}

// 有向角度
D arg(P base, P a, P b) {return arg((b - base) / (a - base));}

// 射影
P proj(P a, P b) {return a * dot(a, b) / norm(a);}
P perp(L l, P p) {return l.a + proj(vec(l), p - l.a);}

// 交差判定
bool iLLs(L a, L b) {return sig(det(vec(a), vec(b)));}
bool iSS(L a, L b) {
  int cwa = ccw(a.a, a.b, b.a) | ccw(a.a, a.b, b.b);
  int cwb = ccw(b.a, b.b, a.a) | ccw(b.a, b.b, a.b);
  return ((cwa | cwb) & ON) || ((cwa & cwb) == (LEFT | RIGHT));
}

// 交点
P pLL(L a, L b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// 距離
D dLP(L l, P p) {return abs(det(vec(l), p - l.a) / vec(l));}
D dSP(L s, P p) {
  if (dot(vec(s), p - s.a) < 0) return abs(p - s.a);
  if (dot(vec(s), p - s.b) > 0) return abs(p - s.b);
  return dLP(s, p);
}

// 円
struct C{P c; D r;};

// 2円の位置関係
enum RELATION{SAME = 1, CONTAIN = 2, OVER = 4, NO_CROSS = 8, ONE_CROSS = 16, ONE_CONTAIN_CROSS = 32, ONE_OVER_CROSS = 64, TWO_CROSS = 128};
int cRel(C c1, C c2) {
  D d = abs(c1.c - c2.c);
  if (near(c1.c, c2.c) && !sig(c1.r, c2.r)) return SAME;
  if (sig(d, c1.r - c2.r) < 0) return OVER;
  if (sig(d, c2.r - c1.r) < 0) return CONTAIN;
  if (!sig(d, c1.r - c2.r)) return ONE_OVER_CROSS;
  if (!sig(d, c2.r - c1.r)) return ONE_CONTAIN_CROSS;
  if (!sig(d, c1.r + c2.r)) return ONE_CROSS;
  if (sig(d, c1.r + c2.r) > 0) return NO_CROSS;
  return TWO_CROSS;
}

// 交差判定
bool iCPs(C c, P p) {return sig(abs(p - c.c), c.r) < 0;}
bool iCS(C c, L s) {return sig(c.r, dSP(s, c.c)) >= 0;}
bool iCC(C a, C b) {return sig(abs(a.c - b.c), a.r + b.r) <= 0;}

// 交点
pair<P, P> pCC(C a, C b) {
  D x = (norm(a.c - b.c) + a.r * a.r - b.r * b.r) / (2 * abs(a.c - b.c));
  P e = (b.c - a.c) / abs(b.c - a.c);
  P y = e * P(0, sr(a.r * a.r - x * x));
  return make_pair(a.c + e * x - y, a.c + e * x + y);
}
pair<P, P> pCL(C c, L l) {
  P x = perp(l, c.c);
  P y = vec(l) / abs(vec(l)) * sr(c.r * c.r - norm(x - c.c));
  return make_pair(x - y, x + y);
}

// 線分をマージする
vector<L> merge(vector<L> s) {
  rep (i, s.size()) if (s[i].b < s[i].a) swap(s[i].a, s[i].b);
  sort(s.begin(), s.end());
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j]) && !iLLs(s[i], s[j])) {
    s[j].b = max(s[i].b, s[j].b);
    s.erase(s.begin() + i--);
    break;
  }
  return s;
}

// 点から円への接線 firstがp->c.cに対して左側
pair<P, P> tCP(C c, P p) {
  D d2 = norm(p - c.c);
  D x = sqrt(max(d2 - c.r * c.r, (D)0));
  P h = c.c + (p - c.c) * (c.r * c.r / d2);
  P w = (p - c.c) * (x * c.r / d2) * P(0, 1);
  return make_pair(h - w, h + w);
}

// 二円の共通接線
vector<L> tCC(C c1, C c2) {
  vector<L> res;
  pair<P, P> pcross1, pcross2;
  D d2 = norm(c2.c - c1.c);

  int rel = cRel(c1, c2);
  if (rel & (SAME | CONTAIN | OVER)) return res;
  
  if (rel & (ONE_CONTAIN_CROSS | ONE_OVER_CROSS | ONE_CROSS)) {
    P p = pCC(c1, c2).first;
    res.push_back((L){p, p + (p - c1.c) * P(0, 1)});
    if (rel & (ONE_CONTAIN_CROSS | ONE_OVER_CROSS)) return res;
  }

  //external
  pcross1 = pCC((C){c2.c, sqrt(d2 - (c2.r - c1.r) * (c2.r - c1.r) + c2.r * c2.r)}, c1);
  pcross2 = pCC((C){c1.c, sqrt(d2 - (c2.r - c1.r) * (c2.r - c1.r) + c1.r * c1.r)}, c2);
  res.push_back((L){pcross1.second, pcross2.first});
  res.push_back((L){pcross1.first, pcross2.second});
  if (rel & (TWO_CROSS | ONE_CROSS)) return res;

  //internal
  P In((c2.r * c1.c + c1.r * c2.c) / (c1.r + c2.r));
  pcross1 = pCC((C){In, sqrt(norm(c1.c - In) - c1.r * c1.r)}, c1);
  pcross2 = pCC((C){In, sqrt(norm(c2.c - In) - c2.r * c2.r)}, c2);
  res.push_back((L){pcross1.first, pcross2.first});
  res.push_back((L){pcross1.second, pcross2.second});
  return res;
}

// 最終防衛問題用秘密兵器
// 同一の円はまとめておくこと
vector<vector<pair<int, int> > > scArr(vector<L> s, vector<C> c, vector<P> &vp) {
  s = merge(s);
  rep (i, s.size()) {
    vp.push_back(s[i].a);
    vp.push_back(s[i].b);
  }
  rep (i, s.size()) rep (j, i) if (iSS(s[i], s[j])) vp.push_back(pLL(s[i], s[j]));
  rep (i, c.size()) rep (j, 4) vp.push_back(c[i].c + polar(c[i].r, PI / 2 * j));
  rep (i, c.size()) rep (j, i) if (iCC(c[i], c[j])) {
    pair<P, P> cc = pCC(c[i], c[j]);
    vp.push_back(cc.first);
    vp.push_back(cc.second);
  }
  rep (i, c.size()) rep (j, s.size()) if (iCS(c[i], s[j])) {
    pair<P, P> cs = pCL(c[i], s[j]);
    if (ccw(s[j].a, s[j].b, cs.first) == ON) vp.push_back(cs.first);
    if (ccw(s[j].a, s[j].b, cs.second) == ON) vp.push_back(cs.second);
  }
  sort(vp.begin(), vp.end());
  vp.erase(unique(vp.begin(), vp.end(), near), vp.end());
  vector<vector<pair<int, int> > > g(vp.size());
  rep (i, s.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (ccw(s[i].a, s[i].b, vp[j]) == ON) v.push_back(make_pair(norm(vp[j] - s[i].a), j));
    sort(v.begin(), v.end());
    rep (j, v.size() - 1) {
      g[v[j + 1].second].push_back(make_pair(v[j].second, -1));
      g[v[j].second].push_back(make_pair(v[j + 1].second, -1));
    }
  }
  rep (i, c.size()) {
    vector<pair<D, int> > v;
    rep (j, vp.size()) if (!sig(c[i].r, abs(c[i].c - vp[j]))) v.push_back(make_pair(arg(vp[j] - c[i].c), j));
    sort(v.begin(), v.end());
    rep (j, v.size()) {
      // 時計回り
      g[v[(j + 1) % v.size()].second].push_back(make_pair(v[j].second, i));
      // 反時計回り
      g[v[j].second].push_back(make_pair(v[(j + 1) % v.size()].second, i));
    }
  }
  return g;
}

struct Witch {C c; D v;};

int main() {
  P s = 0, g;
  int n;
  cin >> n;
  D x, y;
  cin >> x >> y;
  g = P(x, y);
  Witch w[n];
  rep (i, n) {
    cin >> x >> y;
    w[i].c = C({P(x, y), 100});
  }
  vector<C> vc;
  rep (i, n) /*if (!sig(w[i].v))*/ {
    rep (j, vc.size()) if (near(w[i].c.c, vc[j].c) && !sig(w[i].c.r, vc[j].r)) goto next1;
    vc.push_back(w[i].c);
  next1:;
  }
  vector<L> vl;
  vl.push_back((L){s, g});
  rep (i, vc.size()) {
    pair<P, P> pp = tCP(vc[i], s);
    vl.push_back((L){s, pp.first});
    vl.push_back((L){s, pp.second});
    pp = tCP(vc[i], g);
    vl.push_back((L){g, pp.first});
    vl.push_back((L){g, pp.second});
  }
  rep (i, vc.size()) rep (j, i) {
    vector<L> v = tCC(vc[i], vc[j]);
    rep (k, v.size()) vl.push_back(v[k]);
  }
  vector<P> vp;
  vector<vector<pair<int, int> > > graph = scArr(vl, vc, vp);
  int si = -1, gi = -1;
  rep (i, vp.size()) if (near(s, vp[i])) si = i;
  rep (i, vp.size()) if (near(g, vp[i])) gi = i;
  priority_queue<pair<D, int>, vector<pair<D, int> >, greater<pair<D, int> > > que;
  que.push(make_pair(0, si));
  D dis[vp.size()];
  rep (i, vp.size()) dis[i] = 1e100;
  while (!que.empty()) {
    pair<D, int> now = que.top();
    que.pop();
    if (sig(dis[now.second], now.first) <= 0) continue;
    dis[now.second] = now.first;
    rep (i, graph[now.second].size()) {
      P p;
      int next = graph[now.second][i].first;
      int cc = graph[now.second][i].second;
      D d;
      if (cc < 0) {
        p = (vp[now.second] + vp[next]) / (D)2;
        d = abs(vp[now.second] - vp[next]);
      } else {
        D a = arg(vc[cc].c, vp[now.second], vp[next]);
        p = (vp[now.second] - vc[cc].c) * polar((D)1, a / 2) + vc[cc].c;
        d = vc[cc].r * abs(a);
      }
      rep (j, vc.size()) if (iCPs(vc[j], p)) goto next2;
      que.push(make_pair(now.first + d, next));
    next2:;
    }
  }
  rep (i, n) if (dis[gi] > 1e90/* || sig(abs(w[i].c.r + dis[gi] * w[i].v), abs(w[i].c.c - g)) > 0*/) {
    cout << "0.0" << endl;
    return 0;
  }
  printf("%.10Lf\n", dis[gi]);
  return 0;
}

Measured memory_bytes: 1660