#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 double D;
typedef complex<D> P;
struct L{P a, b;};
typedef vector<P> Pol;

const D EPS = 1e-8;

// テヲツッツ氾ィツシツεゥツ鳴「テヲツ閉ー
inline int sig(const D &a, const D &b = 0) {return a < b - EPS ? -1 : a > b + EPS ? 1 : 0;}
inline bool near(const P &a, const P &b) {return !sig(norm(a - b));}
namespace std {
  inline bool operator<(const P &a, const P &b) {return sig(a.X, b.X) ? a.X < b.X : a.Y < b.Y;}
}

// テ・ツ??ァツゥツ?
inline D dot(const P &a, const P &b) {return a.X * b.X + a.Y * b.Y;}
// テ・ツ、ツ姪ァツゥツ?
inline D det(const P &a, const P &b) {return a.X * b.Y - a.Y * b.X;}

// テァツキツ堙・ツ按?」ツ?ョテ」ツδ凖」ツつッテ」ツδ暗」ツδォ
inline P vec(const L &a) {return a.b - a.a;}

// テァツキツ堙・ツ按?bテ」ツ?ォテ・ツッツセテ」ツ?凖」ツつ凝ァツつケcテ」ツ?ョテ、ツスツ催ァツスツョ
enum CCW{FRONT = 1, RIGHT = 2, BACK = 4, LEFT = 8, ON = 16};
inline int ccw(const P &a, const P &b, const 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;
}

// テ・ツーツ?・ツスツア
inline P proj(const P &a, const P &b) {return a * dot(a, b) / norm(a);}
inline P perp(const L &l, const P &p) {return l.a + proj(vec(l), p - l.a);}

// テ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
inline bool iLSs(L a, L b) {return sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) < 0;}
inline bool iSSs(const L &a, const L &b) {
  if (sig(det(vec(a), b.a - a.a)) * sig(det(vec(a), b.b - a.a)) >= 0) return false;
  if (sig(det(vec(b), a.a - b.a)) * sig(det(vec(b), a.b - b.a)) >= 0) return false;
  return true;
}

// テ、ツコツ、テァツつケ
inline P pLL(const L &a, const L &b) {return a.a + vec(a) * (det(vec(b), b.a - a.a) / det(vec(b), vec(a)));}

// テ・ツ、ツ堙ィツァツ津・ツスツ「テ」ツ?ョテ・ツ??・ツ、ツ姪・ツ按、テ・ツョツ?テ・ツ??ゥツδィ:1テ」ツ??・ツ堕ィテ、ツクツ?0テ」ツ??・ツ、ツ姪ゥツδィ:-1
inline int sGP(const Pol &pol, const P &p) {
  int side = -1;
  rep (i, pol.size()) {
    P p0 = pol[i] - p, p1 = at(pol, i + 1) - p;
    if (ccw(p0, p1, 0) == ON) return 0;
    if (p0.Y > p1.Y) swap(p0, p1);
    if (sig(p0.Y) <= 0 && 0 < sig(p1.Y) && sig(det(p0, p1)) > 0) side *= -1;
  }
  return side;
}

vector<Pol> vpol;
vector<P> vp;

inline bool cross(const P &a, const P &b) {
  rep (i, vpol.size()) rep (j, vpol[i].size()) {
    if (iSSs((L){a, b}, (L){vpol[i][j], at(vpol[i], j + 1)})) return true;
  }
  rep (i, vpol.size()) if (sGP(vpol[i], (a + b) / (D)2) > 0) return true;
  rep (i, vp.size()) if (!near(a, vp[i]) && !near(b, vp[i]) && ccw(a, b , vp[i]) == ON) return true;
  return false;
}

typedef pair<D, pair<int,int> > State;
#define COST first
#define TO second.first
#define FROM second.second

int main() {
  while (true) {
    int n;
    cin >> n;
    if (n == 0) break;
    P b;
    cin >> b.X >> b.Y;
    vp.clear();
    vp.push_back(0);
    vpol.clear();
    rep (i, n) {
      int m;
      cin >> m;
      Pol pol(m);
      rep (i, m) cin >> pol[i].X >> pol[i].Y;
      rep (i, m) vp.push_back(pol[i]);
      vpol.push_back(pol);
    }
    priority_queue<State, vector<State>, greater<State> > que;
    State s;
    s.COST = s.TO = s.FROM = 0;
    que.push(s);
    D dis[vp.size()];
    rep (i, vp.size()) dis[i] = 1e9;
    while (!que.empty()) {
      State now = que.top();
      que.pop();
      if (sig(dis[now.TO], now.COST) <= 0) continue;
      if (cross(vp[now.FROM], vp[now.TO])) continue;
      dis[now.TO] = now.COST;
      rep (i, vp.size()) {
	State next;
	next.COST = now.COST + abs(vp[now.TO] - vp[i]);
	next.TO = i;
	next.FROM = now.TO;
	que.push(next);
      }
    }
    D res = 1e9;
    if (cross(0, b)) res = 0;
    rep (i, vpol.size()) rep (j, vpol[i].size()) {
      if (ccw(b, vpol[i][j], at(vpol[i], j + 1)) == ccw(b, vpol[i][j], at(vpol[i], j - 1 + vpol[i].size()))) {
	rep (k, vp.size()) if (sig(res, dis[k]) > 0 && near(vpol[i][j], vp[k])) {
	  res = dis[k];
	}
      }
      P p = perp((L){b, vpol[i][j]}, 0);
      rep (k, vp.size()) if (sig(res, dis[k] + abs(p - vp[k])) > 0 && ccw(b, vpol[i][j], p) == FRONT && !cross(vp[k], p)) {
	res = dis[k] + abs(p - vp[k]);
      }
      rep (ii, vpol.size()) rep (jj, vpol[ii].size()) {
	if (iLSs((L){b, vpol[i][j]}, (L){vpol[ii][jj], at(vpol[ii], jj + 1)})) {
	  p = pLL((L){b, vpol[i][j]}, (L){vpol[ii][jj], at(vpol[ii], jj + 1)});
	  if (ccw(b, vpol[i][j], p) == FRONT && !cross(vpol[i][j], p)) {
	    rep (k, vp.size()) if (sig(res, dis[k] + abs(p - vp[k])) > 0 && !cross(vp[k], p)) {
	      res = dis[k] + abs(p - vp[k]);
	    }
	  }
	}
      }
    }
    printf("%.12f\n", res);
  }
  return 0;
}

Measured memory_bytes: 9272