#include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const double INF = DBL_MAX / 100;
const double EPS = 1.0e-10;

class Point
{
public:
    double y, x;
    Point(){
        y = x = 0.0;
    }
    Point(double y0, double x0){
        y = y0;
        x = x0;
    }
    Point operator+(const Point& p) const{
        return Point(y + p.y, x + p.x);
    }
    Point operator-(const Point& p) const{
        return Point(y - p.y, x - p.x);
    }
    Point operator*(double a) const{
        return Point(y * a, x * a);
    }
    Point operator/(double a) const{
        return Point(y / a, x / a);
    }
    double length() const{
        return sqrt(y * y + x * x);
    }
    double dist(const Point& p) const{
        return sqrt(pow(y - p.y, 2) + pow(x - p.x, 2));
    }
    double dot(const Point& p) const{
        return y * p.y + x * p.x; // |a|*|b|*cosθ
    }
    double cross(const Point& p) const{
        return x * p.y - y * p.x; // |a|*|b|*sinθ
    }
};

class Line
{
public:
    double a, b, c; // a*x + b*y + c = 0
    Line(){
        a = c = 0.0;
        b = 1.0;
    }
    Line(double a0, double b0, double c0){
        a = a0;
        b = b0;
        c = c0;
    }
    Line(const Point& p1, const Point& p2){ // 2点を結ぶ直線
        double dy = p2.y - p1.y;
        double dx = p2.x - p1.x;
        if(abs(dy / dx) < EPS){
            a = 0.0;
            b = 1.0;
            c = -p1.y;
        }else if(abs(dx / dy) < EPS){
            a = 1.0;
            b = 0.0;
            c = -p1.x;
        }else{
            a = - dy / dx;
            b = 1.0;
            c = dy / dx * p1.x - p1.y;
        }
    }
};

Point footOfPerpendicular(const Line& l, const Point& p)
{
    double t = (l.a * p.x + l.b * p.y + l.c) / (l.a * l.a + l.b * l.b);
    return p + Point(l.a, l.b) * t;
}

bool segmentsCollide(const Point& a1, const Point& a2, const Point& b1, const Point& b2)
{
    if(min(a1.x, a2.x) > max(b1.x, b2.x) || min(b1.x, b2.x) > max(a1.x, a2.x) || min(a1.y, a2.y) > max(b1.y, b2.y) || min(b1.y, b2.y) > max(a1.y, a2.y))
        return false;

    return ((a2-a1).cross(b1-a1) * (a2-a1).cross(b2-a1) < -EPS) && ((b2-b1).cross(a1-b1) * (b2-b1).cross(a2-b1) < -EPS);
}

int n;
vector<int> m;
vector<vector<Point> > polygon;

bool isAccess(const Point& p1, const Point& p2)
{
    for(int i=1; i<=n; ++i){
        for(int j=0; j<m[i]; ++j){
            if(segmentsCollide(p1, p2, polygon[i][j], polygon[i][(j+1)%m[i]]))
                return false;
        }
    }
    return true;
}

int main()
{
    for(;;){
        cin >> n;
        if(n == 0)
            return 0;

        Point bomb;
        cin >> bomb.x >> bomb.y;

        m.resize(n+1);
        polygon.assign(n+1, vector<Point>());
        m[0] = 1;
        polygon[0].assign(1, Point(0, 0));
        for(int i=1; i<=n; ++i){
            cin >> m[i];
            polygon[i].resize(m[i]);
            for(int j=0; j<m[i]; ++j)
                cin >> polygon[i][j].x >> polygon[i][j].y;
        }

        if(!isAccess(Point(0, 0), bomb)){
            cout << 0 << endl;
            continue;
        }

        vector<vector<bool> > alive(n+1);
        alive[0].assign(1, false);
        for(int i=1; i<=n; ++i){
            alive[i].assign(m[i], false);
            for(int j=0; j<m[i]; ++j){
                if((polygon[i][(j+1)%m[i]] - bomb).cross(polygon[i][j] - bomb) < -EPS)
                    alive[i][j] = alive[i][(j+1)%m[i]] = true;
            }
        }

        vector<vector<double> > dp(n+1);
        multimap<double, pair<int, int> > mm;
        for(int i=0; i<=n; ++i)
            dp[i].assign(m[i], INF);
        dp[0][0] = 0.0;
        mm.insert(make_pair(0.0, make_pair(0, 0)));
        for(;;){
            double cost = mm.begin()->first;
            int a = mm.begin()->second.first;
            int b = mm.begin()->second.second;
            mm.erase(mm.begin());
            if(a == -1 || alive[a][b]){
                printf("%.10f\n", cost);
                break;
            }

            for(int c=0; c<=n; ++c){
                for(int d=0; d<m[c]; ++d){
                    if(isAccess(polygon[a][b], polygon[c][d])){
                        double cost2 = cost + polygon[a][b].dist(polygon[c][d]);
                        if(cost2 < dp[c][d] - EPS){
                            dp[c][d] = cost2;
                            mm.insert(make_pair(cost2, make_pair(c, d)));
                        }
                    }

                    if(alive[c][d]){
                        Point p = footOfPerpendicular(Line(bomb, polygon[c][d]), polygon[a][b]);
                        if(p.dist(bomb) >= polygon[c][d].dist(bomb) - EPS && isAccess(polygon[a][b], p)){
                            double cost3 = cost + polygon[a][b].dist(p);
                            mm.insert(make_pair(cost3, make_pair(-1, -1)));
                        }
                    }
                }
            }
        }
    }
}

Measured memory_bytes: 1140