Problem:
Problem I:
Wind Passages
Wind Corridor is a covered passageway where strong wind is always blowing. It is a long corridor of
width W, and there are several pillars in it. Each pillar is a right prism and its face is a polygon (not
necessarily convex).
In this problem, we consider two-dimensional space where the positive
x
-axis points the east and the
positive
y
-axis points the north. The passageway spans from the south to the north, and its length is
infinity. Specifically, it covers the area 0 ≤
x
≤
W
. The outside of the passageway is filled with walls.
Each pillar is expressed as a polygon, and all the pillars are located within the corridor without conflicting
or touching each other.
Wind blows from the south side of the corridor to the north. For each second,
w
unit volume of air can
be flowed at most if the minimum width of the path of the wind is
w
. Note that the path may fork and
merge, but never overlaps with pillars and walls.
Your task in this problem is to write a program that calculates the maximum amount of air that can be
flowed through the corridor per second.
Input
The input consists of multiple datasets. Each dataset has the following format:
The first line of the input contains two integers
W
and
N
.
W
is the width of the corridor, and
N
is the
number of pillars.
W
and
N
satisfy the following condition: 1 ≤
W
≤ 10
4
and 0 ≤
N
≤ 200.
Then,
N
specifications of each pillar follow. Each specification starts with a line that contains a single
integer
M
, which is the number of the vertices of a polygon (3 ≤
M
≤ 40). The following
M
lines describe the shape of the polygon. The
i
-th line (1 ≤
i
≤
M
) contains two integers
x
i
and
y
i
that denote the coordinate of the
i
-th vertex (0 <
x
i
<
W
, 0 <
y
i
< 10
4
).
The last dataset is followed by a line containing two zeros. This line is not a part of any dataset and should not be processed.
Output
For each dataset, your program should print a line that contains the maximum amount of air flow per second, in unit
volume. The output may contain arbitrary number of digits after the decimal point, but the absolute error
must not exceed 10
-6
.
Sample Input
5 2
4
1 1
1 2
2 2
2 1
4
3 3
3 4
4 4
4 3
0 0
Output for the Sample Input
3.41421356

Submitted solutions:

code_snippet: #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
#include<cmath>
using namespace std;
typedef double LD;
const LD eps=1e-10;
const int maxn=210;
LD sqr(LD x){return x*x;}
int sgn(LD x){
	return (x>eps)-(x<-eps);
}
struct P{
	LD x,y;
	P(){}
	P(LD x,LD y):x(x),y(y){}
	LD len(){
		return sqrt(sqr(x)+sqr(y));
	}
	P turn90(){
		return P(y,-x);
	}
	void read(){
		double tx,ty;
		scanf("%lf%lf",&tx,&ty);
		x=tx;
		y=ty;
	}
};
bool operator==(P a,P b){
	return !sgn(a.x-b.x)&&!sgn(a.y-b.y);
}
bool operator<(P a,P b){
	return sgn(a.x-b.x)?a.x<b.x:a.y<b.y;
}
P operator+(P a,P b){
	return P(a.x+b.x,a.y+b.y);
}
P operator-(P a,P b){
	return P(a.x-b.x,a.y-b.y);
}
LD operator^(P a,P b){
	return a.x*b.x+a.y*b.y;
}
LD operator*(P a,P b){
	return a.x*b.y-a.y*b.x;
}
P operator*(P a,LD p){
	return P(a.x*p,a.y*p);
}
P operator/(P a,LD p){
	return P(a.x/p,a.y/p);
}
LD det(P a,P b,P c){
	return (b-a)*(c-a);
}
P intersect(P a,P b,P c,P d){
	LD s1=det(a,b,c);
	LD s2=det(a,b,d);
	return (d*s1-c*s2)/(s1-s2);
}
struct L{
	P a,b;
	P v(){return b-a;}
	L(){}
	L(P a,P b):a(a),b(b){}
}l[maxn],nl[maxn*maxn];
P intersect(L l1,L l2){
	return intersect(l1.a,l1.b,l2.a,l2.b);
}
bool paraell(P a,P b){
	return !sgn(a*b);
}

vector<P> convex_hull(vector<P> point){
	sort(point.begin(),point.end());
	vector<P>convex;
	vector<P>stack;
	for(int i=0;i<point.size();i++){
		while(stack.size()>=2
			&&sgn(det(stack[stack.size()-2],stack.back(),point[i]))<=0)
				stack.pop_back();
		stack.push_back(point[i]);
	}
	for(int i=0;i<stack.size();i++)
		convex.push_back(stack[i]);
	stack.clear();
	for(int i=int(point.size())-1;i>=0;i--){
		while(stack.size()>=2
			&&sgn(det(stack[stack.size()-2],stack.back(),point[i]))<=0)
				stack.pop_back();
		stack.push_back(point[i]);		
	}
	for(int i=1;i+1<stack.size();i++)
		convex.push_back(stack[i]);
	return convex;
}
bool project(P p,L l){
	return sgn((p-l.a)^(l.b-l.a))>=0&&sgn((p-l.b)^(l.a-l.b))>=0;
}
double dis(P a,P b){return (a-b).len();}
double dis(P p,L l){
	if(project(p,l)){
		return fabs((p-l.a)*l.v())/l.v().len();
	}else{
		return min(dis(p,l.a),dis(p,l.b));
	}
}
double dis(vector<P>&p1,vector<P>&p2){
	double ans=1e30;
	for(int i=0;i<p1.size();i++){
		for(int j=0;j<p2.size();j++){
			ans=min(ans,dis(p1[i],L(p2[j],p2[(j+1)%p2.size()])));
		}
	}
	swap(p1,p2);
	for(int i=0;i<p1.size();i++){
		for(int j=0;j<p2.size();j++){
			ans=min(ans,dis(p1[i],L(p2[j],p2[(j+1)%p2.size()])));
		}
	}
	swap(p1,p2);
	return ans;
}
int W,n;
vector<P>poly[maxn];
double disl[maxn],disr[maxn];
double mp[maxn][maxn];
int main(){
	while(scanf("%d%d",&W,&n)==2){
		if(!W&&!n)break;
		for(int i=1;i<=n;i++){
			int m;scanf("%d",&m);
			P p;poly[i].clear();
			while(m--){
				p.read();
				poly[i].push_back(p);
			}
			//poly[i]=convex_hull(poly[i]);
			/*for(int j=0;j<poly[i].size();j++){
				printf("(%.3f,%.3f)%c",poly[i][j].x,poly[i][j].y," \n"[j+1==poly[i].size()]);
			}*/
		}
		
		for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++)if(i!=j){
				mp[i][j]=dis(poly[i],poly[j]);
				
			}
			mp[i][i]=0;
			
		}
				
		for(int k=1;k<=n;k++)
			for(int i=1;i<=n;i++)
				for(int j=1;j<=n;j++)
					mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
		
		for(int i=1;i<=n;i++){
			disl[i]=disr[i]=1e20;
			for(int j=0;j<poly[i].size();j++){
				disl[i]=min(disl[i],poly[i][j].x);
				disr[i]=min(disr[i],W-poly[i][j].x);
			}
			
			//printf("%.3f %.3f\n",disl[i],disr[i]);
		}			
		
		/*for(int i=1;i<=n;i++){
			for(int j=1;j<=n;j++){
				printf("%.3f%c",mp[i][j]," \n"[j==n]);
			}
		}*/
		
		double ans=W;
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				ans=min(ans,disl[i]+mp[i][j]+disr[j]);
		printf("%.10f\n",ans);
	}
	return 0;
}
accuracy: 1
time_ms: 130
memory_kb: 3744
final_rank: 6

code_snippet: #include <bits/stdc++.h>
#define int long long

using namespace std;

int w, n;
const double eps = 1e-8, inf = 1e9;
int Ceil(double x) {
    if (x > eps) return 1;
    if (x < -eps) return -1;
    return 0;
}

struct point {
    point() {};
    point(double xi, double yi) {
        this->x = xi;
        this->y = yi;
    }
    point operator +(point& a) {
        return point(this->x + a.x, this->y + a.y);
    }
    point operator -(point& a) {
        return point(this->x - a.x, this->y - a.y);
    }
    double len() {
        return sqrt(x * x + y * y);
    }
    double scal(point a) {
        return x * a.x + y * a.y;
    }
    double vect(point a) {
        return x * a.y - y * a.x;
    }
    double x, y;
};

int PointInSeg(point& a, point& b, point& c) {
    int res = Ceil((b - a).vect(c - a));
    if (res) return res;
    if (Ceil((b - a).scal(c - a)) < 0) return -2;
    if (Ceil((a - b).scal(c - b)) < 0) return +2;
    return 0;
}

bool SegInSeg(point& a, point& b, point& c, point& d) {
    return (PointInSeg(a, b, c) * PointInSeg(a, b, d) <= 0 && PointInSeg(c, d, a) * PointInSeg(c, d, b) <= 0);
}

double distSegPoint(point& a, point& b, point& c) {
    if (Ceil((b - a).scal(c - a)) <= 0) return (c - a).len();
    if (Ceil((a - b).scal(c - b)) <= 0) return (c - b).len();
    return abs((b - a).vect(c - a)) / (b - a).len();
}

double distSegSeg(point& a, point& b, point& c, point& d) {
    if (SegInSeg(a, b, c, d)) return 0;
    return min(min(distSegPoint(a, b, c), distSegPoint(a, b, d)), min(distSegPoint(c, d, a), distSegPoint(c, d, b)));
}


void run_test(int w, int n) {
    int m;
    vector<vector<point>> cols(n);
    for (int i = 0; i < n; ++i) {
        cin >> m;
        cols[i].resize(m);
        for (int j = 0; j < m; ++j) {
            cin >> cols[i][j].x >> cols[i][j].y;
        }
    }
    vector<vector<double>> dist(n + 2, vector<double>(n + 2, inf));
    for (int i = 0; i < n; ++i) dist[i][i] = 0;
    dist[n][n + 1] = w;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < cols[i].size(); ++j) {
            dist[n][i] = dist[i][n] = min(dist[i][n], cols[i][j].x);
            dist[n + 1][i] = dist[i][n + 1] = min(dist[i][n + 1], w-cols[i][j].x);
        }
    }
    for (int i = 0; i < n; ++i) {
        for (int j = i + 1; j < n; ++j) {
            for (int k = 0; k < cols[i].size(); ++k) {
                for (int q = 0; q < cols[j].size(); ++q) {
                    dist[i][j] = dist[j][i] = min(dist[i][j], distSegSeg(cols[i][k], cols[i][(k + 1) % cols[i].size()], cols[j][q], cols[j][(q + 1) % cols[j].size()]));
                }
            }
        }
    }
    for (int k = 0; k < n + 2; ++k) {
        for (int i = 0; i < n + 2; ++i) {
            for (int j = 0; j < n + 2; ++j) {
                dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
            }
        }
    }
    cout << setprecision(10) << fixed << dist[n][n + 1] << '\n';
}

signed main() {
    while (true) {
        cin >> w >> n;
        if (w == 0 && n == 0) break;
        run_test(w, n);
    }
}
accuracy: 1
time_ms: 80
memory_kb: 3620
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

using T = long double;
const T eps = 1e-12;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, (T).0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, (T).0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * (T)2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw

    if (cross(b, c) < -eps)
        return -1; // cw

    if (dot(b, c) < 0)
        return 2; // c,a,b

    if (norm(b) < norm(c))
        return -2; // a,b,c

    return 0;      // a,c,b

}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), (T).0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), (T).0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return (T).0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, (T)0.) and eq(d2, (T)0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / (T)2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / (T)2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return (T).0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = (T).0;
        if (eq(f, (T).0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = (T).0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / (T)2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return (T).0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / (T)2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / (T)2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / (T)2.);
    res += b.r * b.r * (bth - sin(bth * 2) / (T)2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain

    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), (T).0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / (T)2., (a + b) / (T)2. + (b - a) * Point(0, 1));
    Line l2((b + c) / (T)2., (b + c) / (T)2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, (T)0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, (T)1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */

int main() {
while(1) {
    long double W;
    int N;
    cin >> W >> N;
    if (W == 0.0L) return 0;
    vector<vector<Point>> P(N);
    vector<vector<Segment>> S(N);
    rep(i,0,N) {
        int M;
        cin >> M;
        P[i].resize(M);
        rep(j,0,M) {
            long double x, y;
            cin >> x >> y;
            P[i][j] = Point(x,y);
        }
        S[i].resize(M);
        rep(j,0,M) {
            S[i][j] = Segment(P[i][j], P[i][(j+1)%M]);
        }
    }
    vector<vector<long double>> DP(N+2, vector<long double>(N+2,INF));
    rep(i,0,N+2) DP[i][i] = 0.0L;
    rep(i,0,N) {
        rep(j,i+1,N) {
            rep(k,0,P[i].size()) {
                rep(l,0,P[j].size()) {
                    chmin(DP[i][j], Dist(S[i][k],S[j][l]));
                }
            }
        }
    }
    rep(i,0,N) {
        rep(j,0,P[i].size()) {
            chmin(DP[i][N], P[i][j].real());
            chmin(DP[i][N+1], W - P[i][j].real());
        }
    }
    chmin(DP[N][N+1],W);
    rep(i,0,N+2) {
        rep(j,0,i) DP[i][j] = DP[j][i];
    }
    rep(k,0,N+2) {
        rep(i,0,N+2) {
            rep(j,0,N+2) {
                chmin(DP[i][j], DP[i][k] + DP[k][j]);
            }
        }
    }
    printf("%.12Lf\n", DP[N][N+1]);
}
}
accuracy: 1
time_ms: 340
memory_kb: 4052
final_rank: 12

code_snippet: #line 1 "library/Template/template.hpp"
#include <bits/stdc++.h>
using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}
#line 2 "library/Utility/fastio.hpp"
#include <unistd.h>
namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf

uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio

using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */
#line 3 "sol.cpp"

#line 2 "library/Geometry/geometry.hpp"

using T = double;
const T eps = 1e-12;
using Point = complex<T>;
using Poly = vector<Point>;
#define X real()
#define Y imag()
template <typename T> inline bool eq(const T &a, const T &b) {
    return fabs(a - b) < eps;
}
bool cmp(const Point &a, const Point &b) {
    auto sub = [&](Point a) {
        return (a.Y < 0 ? -1 : (a.Y == 0 && a.X >= 0 ? 0 : 1));
    };
    if (sub(a) != sub(b))
        return sub(a) < sub(b);
    return a.Y * b.X < a.X * b.Y;
}
struct Line {
    Point a, b, dir;
    Line() {}
    Line(Point _a, Point _b) : a(_a), b(_b), dir(b - a) {}
    Line(T A, T B, T C) {
        if (eq(A, .0)) {
            a = Point(0, C / B), b = Point(1 / C / B);
        } else if (eq(B, .0)) {
            a = Point(C / A, 0), b = Point(C / A, 1);
        } else {
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }
};
struct Segment : Line {
    Segment() {}
    Segment(Point _a, Point _b) : Line(_a, _b) {}
};
struct Circle {
    Point p;
    T r;
    Circle() {}
    Circle(Point _p, T _r) : p(_p), r(_r) {}
};

istream &operator>>(istream &is, Point &p) {
    T x, y;
    is >> x >> y;
    p = Point(x, y);
    return is;
}
ostream &operator<<(ostream &os, Point &p) {
    os << fixed << setprecision(12) << p.X << ' ' << p.Y;
    return os;
}
Point unit(const Point &a) {
    return a / abs(a);
}
T dot(const Point &a, const Point &b) {
    return a.X * b.X + a.Y * b.Y;
}
T cross(const Point &a, const Point &b) {
    return a.X * b.Y - a.Y * b.X;
}
Point rot(const Point &a, const T &theta) {
    return Point(cos(theta) * a.X - sin(theta) * a.Y,
                 sin(theta) * a.X + cos(theta) * a.Y);
}
Point rot90(const Point &a) {
    return Point(-a.Y, a.X);
}
T arg(const Point &a, const Point &b, const Point &c) {
    double ret = acos(dot(a - b, c - b) / abs(a - b) / abs(c - b));
    if (cross(a - b, c - b) < 0)
        ret = -ret;
    return ret;
}

Point Projection(const Line &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Projection(const Segment &l, const Point &p) {
    T t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}
Point Reflection(const Line &l, const Point &p) {
    return p + (Projection(l, p) - p) * 2.;
}
int ccw(const Point &a, Point b, Point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > eps)
        return 1; // ccw
    if (cross(b, c) < -eps)
        return -1; // cw
    if (dot(b, c) < 0)
        return 2; // c,a,b
    if (norm(b) < norm(c))
        return -2; // a,b,c
    return 0;      // a,c,b
}
bool isOrthogonal(const Line &a, const Line &b) {
    return eq(dot(a.b - a.a, b.b - b.a), .0);
}
bool isParallel(const Line &a, const Line &b) {
    return eq(cross(a.b - a.a, b.b - b.a), .0);
}
bool isIntersect(const Segment &a, const Segment &b) {
    return ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) <= 0 and
           ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) <= 0;
}
int isIntersect(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d > a.r + b.r + eps)
        return 4;
    if (eq(d, a.r + b.r))
        return 3;
    if (eq(d, abs(a.r - b.r)))
        return 1;
    if (d < abs(a.r - b.r) - eps)
        return 0;
    return 2;
}
T Dist(const Line &a, const Point &b) {
    Point c = Projection(a, b);
    return abs(c - b);
}
T Dist(const Segment &a, const Point &b) {
    if (dot(a.b - a.a, b - a.a) < eps)
        return abs(b - a.a);
    if (dot(a.a - a.b, b - a.b) < eps)
        return abs(b - a.b);
    return abs(cross(a.b - a.a, b - a.a)) / abs(a.b - a.a);
}
T Dist(const Segment &a, const Segment &b) {
    if (isIntersect(a, b))
        return .0;
    T res = min({Dist(a, b.a), Dist(a, b.b), Dist(b, a.a), Dist(b, a.b)});
    return res;
}
Point Intersection(const Line &a, const Line &b) {
    T d1 = cross(a.b - a.a, b.b - b.a);
    T d2 = cross(a.b - a.a, a.b - b.a);
    if (eq(d1, 0.) and eq(d2, 0.))
        return b.a;
    return b.a + (b.b - b.a) * (d2 / d1);
}
Poly Intersection(const Circle &a, const Line &b) {
    Poly res;
    T d = Dist(b, a.p);
    if (d > a.r + eps)
        return res;
    Point h = Projection(b, a.p);
    if (eq(d, a.r)) {
        res.push_back(h);
        return res;
    }
    Point e = unit(b.b - b.a);
    T ph = sqrt(a.r * a.r - d * d);
    res.push_back(h - e * ph);
    res.push_back(h + e * ph);
    return res;
}
Poly Intersection(const Circle &a, const Segment &b) {
    Line c(b.a, b.b);
    Poly sub = Intersection(a, c);
    double xmi = min(b.a.X, b.b.X), xma = max(b.a.X, b.b.X);
    double ymi = min(b.a.Y, b.b.Y), yma = max(b.a.Y, b.b.Y);
    Poly res;
    rep(i, 0, sub.size()) {
        if (xmi <= sub[i].X + eps and sub[i].X - eps <= xma and
            ymi <= sub[i].Y + eps and sub[i].Y - eps <= yma) {
            res.push_back(sub[i]);
        }
    }
    return res;
}
Poly Intersection(const Circle &a, const Circle &b) {
    Poly res;
    int mode = isIntersect(a, b);
    T d = abs(a.p - b.p);
    if (mode == 4 or mode == 0)
        return res;
    if (mode == 3) {
        T t = a.r / (a.r + b.r);
        res.push_back(a.p + (b.p - a.p) * t);
        return res;
    }
    if (mode == 1) {
        if (b.r < a.r - eps) {
            res.push_back(a.p + (b.p - a.p) * (a.r / d));
        } else {
            res.push_back(b.p + (a.p - b.p) * (b.r / d));
        }
        return res;
    }
    T rc = (a.r * a.r + d * d - b.r * b.r) / d / 2.;
    T rs = sqrt(a.r * a.r - rc * rc);
    if (a.r - abs(rc) < eps)
        rs = 0;
    Point e = unit(b.p - a.p);
    res.push_back(a.p + rc * e + rs * e * Point(0, 1));
    res.push_back(a.p + rc * e + rs * e * Point(0, -1));
    return res;
}
Poly HalfplaneIntersection(vector<Line> &H) {
    sort(ALL(H), [&](Line &l1, Line &l2) { return cmp(l1.dir, l2.dir); });
    auto outside = [&](Line &L, Point p) -> bool {
        return cross(L.dir, p - L.a) < -eps;
    };
    deque<Line> deq;
    int sz = 0;
    rep(i, 0, SZ(H)) {
        while (sz > 1 and
               outside(H[i], Intersection(deq[sz - 1], deq[sz - 2]))) {
            deq.pop_back();
            sz--;
        }
        while (sz > 1 and outside(H[i], Intersection(deq[0], deq[1]))) {
            deq.pop_front();
            sz--;
        }
        if (sz > 0 and fabs(cross(H[i].dir, deq[sz - 1].dir)) < eps) {
            if (dot(H[i].dir, deq[sz - 1].dir) < 0) {
                return {};
            }
            if (outside(H[i], deq[sz - 1].a)) {
                deq.pop_back();
                sz--;
            } else
                continue;
        }
        deq.push_back(H[i]);
        sz++;
    }

    while (sz > 2 and outside(deq[0], Intersection(deq[sz - 1], deq[sz - 2]))) {
        deq.pop_back();
        sz--;
    }
    while (sz > 2 and outside(deq[sz - 1], Intersection(deq[0], deq[1]))) {
        deq.pop_front();
        sz--;
    }
    if (sz < 3)
        return {};
    deq.push_back(deq.front());
    Poly ret;
    rep(i, 0, sz) ret.push_back(Intersection(deq[i], deq[i + 1]));
    return ret;
}

T Area(const Poly &a) {
    T res = 0;
    int n = a.size();
    rep(i, 0, n) res += cross(a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Poly &a, const Circle &b) {
    int n = a.size();
    if (n < 3)
        return .0;
    auto rec = [&](auto self, const Circle &c, const Point &p1,
                   const Point &p2) {
        Point va = c.p - p1, vb = c.p - p2;
        T f = cross(va, vb), res = .0;
        if (eq(f, .0))
            return res;
        if (max(abs(va), abs(vb)) < c.r + eps)
            return f;
        if (Dist(Segment(p1, p2), c.p) > c.r - eps)
            return c.r * c.r * arg(vb * conj(va));
        auto u = Intersection(c, Segment(p1, p2));
        Poly sub;
        sub.push_back(p1);
        for (auto &x : u)
            sub.push_back(x);
        sub.push_back(p2);
        rep(i, 0, sub.size() - 1) res += self(self, c, sub[i], sub[i + 1]);
        return res;
    };
    T res = .0;
    rep(i, 0, n) res += rec(rec, b, a[i], a[(i + 1) % n]);
    return fabs(res / 2.);
}
T Area(const Circle &a, const Circle &b) {
    T d = abs(a.p - b.p);
    if (d >= a.r + b.r - eps)
        return .0;
    if (d <= abs(a.r - b.r) + eps) {
        T r = min(a.r, b.r);
        return M_PI * r * r;
    }
    T ath = acos((a.r * a.r + d * d - b.r * b.r) / d / a.r / 2.);
    T res = a.r * a.r * (ath - sin(ath * 2) / 2.);
    T bth = acos((b.r * b.r + d * d - a.r * a.r) / d / b.r / 2.);
    res += b.r * b.r * (bth - sin(bth * 2) / 2.);
    return fabs(res);
}
bool isConvex(const Poly &a) {
    int n = a.size();
    int cur, pre, nxt;
    rep(i, 0, n) {
        pre = (i - 1 + n) % n;
        nxt = (i + 1) % n;
        cur = i;
        if (ccw(a[pre], a[cur], a[nxt]) == -1)
            return 0;
    }
    return 1;
}
int isContained(const Poly &a,
                const Point &b) { // 0:not contain,1:on edge,2:contain
    bool res = 0;
    int n = a.size();
    rep(i, 0, n) {
        Point p = a[i] - b, q = a[(i + 1) % n] - b;
        if (p.Y > q.Y)
            swap(p, q);
        if (p.Y < eps and eps < q.Y and cross(p, q) > eps)
            res ^= 1;
        if (eq(cross(p, q), .0) and dot(p, q) < eps)
            return 1;
    }
    return (res ? 2 : 0);
}
Poly ConvexHull(Poly &a) {
    sort(ALL(a), [](const Point &p, const Point &q) {
        return (eq(p.Y, q.Y) ? p.X < q.X : p.Y < q.Y);
    });
    a.erase(unique(ALL(a)), a.end());
    int n = a.size(), k = 0;
    Poly res(n * 2);
    for (int i = 0; i < n; res[k++] = a[i++]) {
        while (k >= 2 and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; res[k++] = a[i--]) {
        while (k >= t and
               cross(res[k - 1] - res[k - 2], a[i] - res[k - 1]) < eps)
            k--;
    }
    res.resize(k - 1);
    return res;
}
T Diam(const Poly &a) {
    int n = a.size();
    int x = 0, y = 0;
    rep(i, 1, n) {
        if (a[i].Y > a[x].Y)
            x = i;
        if (a[i].Y < a[y].Y)
            y = i;
    }
    T res = abs(a[x] - a[y]);
    int i = x, j = y;
    do {
        if (cross(a[(i + 1) % n] - a[i], a[(j + 1) % n] - a[j]) < 0)
            i = (i + 1) % n;
        else
            j = (j + 1) % n;
        chmax(res, abs(a[i] - a[j]));
    } while (i != x or j != y);
    return res;
}
Poly Cut(const Poly &a, const Line &l) {
    int n = a.size();
    Poly res;
    rep(i, 0, n) {
        Point p = a[i], q = a[(i + 1) % n];
        if (ccw(l.a, l.b, p) != -1)
            res.push_back(p);
        if (ccw(l.a, l.b, p) * ccw(l.a, l.b, q) < 0)
            res.push_back(Intersection(Line(p, q), l));
    }
    return res;
}

T Closest(Poly &a) {
    int n = a.size();
    if (n <= 1)
        return 0;
    sort(ALL(a), [&](Point a, Point b) {
        return (eq(a.X, b.X) ? a.Y < b.Y : a.X < b.X);
    });
    Poly buf(n);
    auto rec = [&](auto self, int lb, int rb) -> T {
        if (rb - lb <= 1)
            return (T)INF;
        int mid = (lb + rb) >> 1;
        auto x = a[mid].X;
        T res = min(self(self, lb, mid), self(self, mid, rb));
        inplace_merge(a.begin() + lb, a.begin() + mid, a.begin() + rb,
                      [&](auto p, auto q) { return p.Y < q.Y; });
        int ptr = 0;
        rep(i, lb, rb) {
            if (abs(a[i].X - x) >= res)
                continue;
            rep(j, 0, ptr) {
                auto sub = a[i] - buf[ptr - 1 - j];
                if (sub.Y >= res)
                    break;
                chmin(res, abs(sub));
            }
            buf[ptr++] = a[i];
        }
        return res;
    };
    return rec(rec, 0, n);
}

Circle Incircle(const Point &a, const Point &b, const Point &c) {
    T A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point p(A * a.X + B * b.X + C * c.X, A * a.Y + B * b.Y + C * c.Y);
    p /= (A + B + C);
    T r = Dist(Line(a, b), p);
    return Circle(p, r);
}
Circle Circumcircle(const Point &a, const Point &b, const Point &c) {
    Line l1((a + b) / 2., (a + b) / 2. + (b - a) * Point(0, 1));
    Line l2((b + c) / 2., (b + c) / 2. + (c - b) * Point(0, 1));
    Point p = Intersection(l1, l2);
    return Circle(p, abs(p - a));
}
Poly tangent(const Point &a, const Circle &b) {
    return Intersection(b, Circle(a, sqrt(norm(b.p - a) - b.r * b.r)));
}
vector<Line> tangent(const Circle &a, const Circle &b) {
    vector<Line> res;
    T d = abs(a.p - b.p);
    if (eq(d, 0.))
        return res;
    Point u = unit(b.p - a.p);
    Point v = u * Point(0, 1);
    for (int t : {-1, 1}) {
        T h = (a.r + b.r * t) / d;
        if (eq(h * h, 1.)) {
            res.push_back(Line(a.p + (h > 0 ? u : -u) * a.r,
                               a.p + (h > 0 ? u : -u) * a.r + v));
        } else if (1 > h * h) {
            Point U = u * h, V = v * sqrt(1 - h * h);
            res.push_back(Line(a.p + (U + V) * a.r, b.p - (U + V) * (b.r * t)));
            res.push_back(Line(a.p + (U - V) * a.r, b.p - (U - V) * (b.r * t)));
        }
    }
    return res;
}

/**
 * @brief Geometry
 */
#line 5 "sol.cpp"

int main() {
    for (;;) {
        int W, n;
        read(W, n);
        if (W == 0 and n == 0)
            break;
        vector<vector<Point>> a(n);
        rep(i, 0, n) {
            int m;
            read(m);
            a[i].resize(m);
            rep(j, 0, m) {
                int x, y;
                read(x, y);
                a[i][j] = Point(x, y);
            }
        }
        using Q = pair<double, int>;
        vector g(n + 2, vector<Q>());
        int S = n, T = n + 1;
        rep(i, 0, n) {
            rep(j, 0, SZ(a[i])) {
                g[S].push_back({a[i][j].X, i});
                g[i].push_back({W - a[i][j].X, T});
                rep(i2, 0, n) if (i != i2) {
                    rep(j2, 0, SZ(a[i2])) {
                        g[i].push_back(
                            {Dist(Segment(a[i][j], a[i][(j + 1) % SZ(a[i])]),
                                  Segment(a[i2][j2],
                                          a[i2][(j2 + 1) % SZ(a[i2])])),
                             i2});
                    }
                }
            }
        }
        vector<double> dist(n + 2, INF);
        dist[S] = 0;
        priority_queue<Q, vector<Q>, greater<Q>> pq;
        pq.push({0, S});
        while (!pq.empty()) {
            auto [d, v] = pq.top();
            pq.pop();
            if (abs(dist[v] - d) > 1e-12)
                continue;
            for (auto &[cost, to] : g[v])
                if (chmin(dist[to], d + cost)) {
                    pq.push({dist[to], to});
                }
        }
        print(min(W * 1., dist[T]));
    }
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 14492
final_rank: 14

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<class T>
bool chmin(T &a, const T &b) {if (a > b) {a = b; return 1;} return 0;}

template<class T>
bool chmax(T &a, const T &b) {if (a < b) {a = b; return 1;} return 0;}

using ll = long long;
using ld = long double;

using Real = long double;
using Point = complex<Real>;
const Real EPS = 1e-9, PI = acos(-1);

inline bool eq(Real a, Real b) { return fabs(b - a) < EPS; }

Point operator*(const Point &p, const Real &d)
{
	return Point(real(p) * d, imag(p) * d);
}

istream &operator>>(istream &is, Point &p)
{
	Real a, b;
	is >> a >> b;
	p = Point(a, b);
	return is;
}

ostream &operator<<(ostream &os, Point &p)
{
	return os << fixed << setprecision(10) << p.real() << " " << p.imag();
}

namespace std
{
	bool operator<(const Point &a, const Point &b)
	{
		return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
	}
}

struct Line
{
	Point a, b;

	Line() = default;

	Line(Point a, Point b) : a(a), b(b) {}

	Line(Real A, Real B, Real C) // Ax + By = C
	{
		if (eq(A, 0))
			a = Point(0, C / B), b = Point(1, C / B);
		else if (eq(B, 0))
			b = Point(C / A, 0), b = Point(C / A, 1);
		else
			a = Point(0, C / B), b = Point(C / A, 0);
	}

	friend ostream &operator<<(ostream &os, Line &p)
	{
		return os << p.a << " to " << p.b;
	}

	friend istream &operator>>(istream &is, Line &a)
	{
		return is >> a.a >> a.b;
	}
};

struct Segment : Line
{
	Segment() = default;

	Segment(Point a, Point b) : Line(a, b) {}
};

using Points = vector<Point>;
using Polygon = vector<Point>;
using Segments = vector<Segment>;
using Lines = vector<Line>;

Real cross(const Point &a, const Point &b)
{
	return real(a) * imag(b) - imag(a) * real(b);
}

Real dot(const Point &a, const Point &b)
{
	return real(a) * real(b) + imag(a) * imag(b);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
// 点の回転方向
int ccw(const Point &a, Point b, Point c)
{
	b = b - a, c = c - a;
	if (cross(b, c) > EPS)
		return +1; // "COUNTER_CLOCKWISE"
	if (cross(b, c) < -EPS)
		return -1; // "CLOCKWISE"
	if (dot(b, c) < 0)
		return +2; // "ONLINE_BACK"
	if (norm(b) < norm(c))
		return -2; // "ONLINE_FRONT"
	return 0;	   // "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
// 射影
// 直線 l に p から垂線を引いた交点を求める
Point projection(const Line &l, const Point &p)
{
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p)
{
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
// 反射
// 直線 l を対称軸として点 p  と線対称にある点を求める
Point reflection(const Line &l, const Point &p)
{
	return p + (projection(l, p) - p) * 2.0;
}

bool intersect(const Line &l, const Point &p)
{
	return abs(ccw(l.a, l.b, p)) != 1;
}

bool intersect(const Line &l, const Line &m)
{
	return abs(cross(l.b - l.a, m.b - m.a)) > EPS || abs(cross(l.b - l.a, m.b - l.a)) < EPS;
}

bool intersect(const Segment &s, const Point &p)
{
	return ccw(s.a, s.b, p) == 0;
}

bool intersect(const Line &l, const Segment &s)
{
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
bool intersect(const Segment &s, const Segment &t)
{
	return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

Real distance(const Point &a, const Point &b)
{
	return abs(a - b);
}

Real distance(const Line &l, const Point &p)
{
	return abs(p - projection(l, p));
}

Real distance(const Line &l, const Line &m)
{
	return intersect(l, m) ? 0 : distance(l, m.a);
}

Real distance(const Segment &s, const Point &p)
{
	Point r = projection(s, p);
	if (intersect(s, r))
		return abs(r - p);
	return min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b)
{
	if (intersect(a, b))
		return 0;
	return min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

bool is_end = false;

void calc()
{
	ld W; cin >> W;
	ll N; cin >> N;
	
	if (W == 0 && N == 0)
	{
		is_end = true;
		return;
	}
	
	Segment left_wall(Point(0.0, -1e5), Point(0.0, 1e5));
	Segment right_wall(Point(W, -1e5), Point(W, 1e5));
	
	vector<Polygon> pillars(N);
	for (int i = 0; i < N; ++i)
	{
		ll M; cin >> M;
		for (int j = 0; j < M; ++j)
		{
			ld x, y; cin >> x >> y;
			pillars[i].emplace_back(Point(x, y));
		}
	}
	
	const ld INF = 1e10;
	vector<vector<ld>> dist(N+2, vector<Real>(N+2, INF));
	ll S = N, T = N + 1;
	
	for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < N; ++j)
		{
			int sizi = pillars[i].size();
			int sizj = pillars[j].size();
			
			for (int pi = 0; pi < sizi; ++pi)
			{
				Segment ei(pillars[i][pi], pillars[i][(pi+1)%sizi]);
				
				for (int pj = 0; pj < sizj; ++pj)
				{
					Segment ej(pillars[j][pj], pillars[j][(pj+1)%sizj]);
					chmin(dist[i][j], distance(ei, ej));
				}				
			}
		}
		
		// S, T
		{
			int sizi = pillars[i].size();
			for (int pi = 0; pi < sizi; ++pi)
			{
				Segment ei(pillars[i][pi], pillars[i][(pi+1)%sizi]);
				
				chmin(dist[i][S], distance(ei, left_wall));
				chmin(dist[S][i], distance(ei, left_wall));
				chmin(dist[T][i], distance(ei, right_wall));
				chmin(dist[i][T], distance(ei, right_wall));
			}
		}
	}
	
	for (int i = 0; i < N+2; ++i)
	{
		dist[i][i] = 0.0;
	}
	
	{
		chmin(dist[S][T], distance(left_wall, right_wall));
		chmin(dist[T][S], distance(left_wall, right_wall));
	}
	
	vector<ld> tmp(N+2, INF);
	priority_queue<pair<ld, ll>, vector<pair<ld, ll>>, greater<pair<ld, ll>> > pq;
	tmp[S] = 0.0;
	pq.emplace(make_pair(tmp[S], S));
	
	while (pq.size())
	{
		auto [d, v] = pq.top();
		pq.pop();
		
		if (tmp[v] < d) continue;
		
		for (int nv = 0; nv < N+2; ++nv)
		{
			if (chmin(tmp[nv], tmp[v] + dist[v][nv]))
			{
				pq.emplace(make_pair(tmp[nv], nv));
			}
		}
	}
	
	cout << fixed << setprecision(20) << tmp[T] << endl;
		
	return;
}

int main()
{
	while (!is_end)
	{
		calc();
	}
	
	return 0;
}
accuracy: 1
time_ms: 1600
memory_kb: 4772
final_rank: 19

code_snippet: #include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;

class point2d {
public:
	double x, y;
	point2d() : x(0.0), y(0.0) {}
	point2d(double x_, double y_) : x(x_), y(y_) {}
	point2d& operator+=(const point2d& p) { x += p.x; y += p.y; return *this; }
	point2d& operator-=(const point2d& p) { x -= p.x; y -= p.y; return *this; }
	point2d operator+(const point2d& p) const { return point2d(*this) += p; }
	point2d operator-(const point2d& p) const { return point2d(*this) -= p; }
	double abs() const {
		return sqrt(x * x + y * y);
	}
	double dot(const point2d& p) const {
		return x * p.x + y * p.y;
	}
	double cross(const point2d& p) const {
		return x * p.y - y * p.x;
	}
};

double segment_point(const point2d& p1, const point2d& p2, const point2d& p3) {
	if ((p2 - p1).dot(p3 - p1) < 0) {
		return (p3 - p1).abs();
	}
	if ((p1 - p2).dot(p3 - p2) < 0) {
		return (p3 - p2).abs();
	}
	return abs((p2 - p1).cross(p3 - p1)) / (p2 - p1).abs();
}

double segment_segment(const point2d& p1, const point2d& p2, const point2d& p3, const point2d& p4) {
	// assume that segment does not cross!
	double res1 = segment_point(p1, p2, p3);
	double res2 = segment_point(p1, p2, p4);
	double res3 = segment_point(p3, p4, p1);
	double res4 = segment_point(p3, p4, p2);
	return min({ res1, res2, res3, res4 });
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	while (true) {
		// step #1. input
		int W, N;
		cin >> W >> N;
		if (W == 0 && N == 0) {
			break;
		}
		vector<int> M(N);
		vector<vector<point2d> > polygon(N);
		for (int i = 0; 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;
			}
		}
		
		// step #2. calculate distance
		vector<vector<double> > d(N + 2, vector<double>(N + 2, 1.0e+99));
		for (int i = 0; i < N + 2; i++) {
			for (int j = 0; j < N + 2; j++) {
				if (i == j) {
					d[i][j] = 0;
				}
				else if (i > j) {
					d[i][j] = d[j][i];
				}
				else if (j < N) {
					for (int k = 0; k < M[i]; k++) {
						for (int l = 0; l < M[j]; l++) {
							double res = segment_segment(polygon[i][k], polygon[i][(k + 1) % M[i]], polygon[j][l], polygon[j][(l + 1) % M[j]]);
							d[i][j] = min(d[i][j], res);
						}
					}
				}
				else if (i < N) {
					for (int k = 0; k < M[i]; k++) {
						d[i][j] = min(d[i][j], j == N ? polygon[i][k].x : W - polygon[i][k].x);
					}
				}
				else {
					d[i][j] = W;
				}
			}
		}

		// step #3. dijkstra
		vector<double> dist(N + 2, 1.0e+99);
		vector<bool> vis(N + 2, false);
		dist[N] = 0.0;
		while (true) {
			int u = -1;
			double best = 1.0e+99;
			for (int i = 0; i < N + 2; i++) {
				if (!vis[i] && best > dist[i]) {
					u = i;
					best = dist[i];
				}
			}
			if (u == -1) {
				break;
			}
			vis[u] = true;
			for (int i = 0; i < N + 2; i++) {
				if (!vis[i]) {
					dist[i] = min(dist[i], dist[u] + d[u][i]);
				}
			}
		}

		// step #4. output
		cout.precision(15);
		cout << fixed << dist[N + 1] << endl;
	}

	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 3696
final_rank: 1

code_snippet: #include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;

struct Point {
	double px, py;
};

Point operator-(const Point &a1, const Point &a2) {
	return Point{ a1.px - a2.px, a1.py - a2.py };
}

double ABS(Point A1) {
	return sqrt(1.0 * (A1.px * A1.px + A1.py * A1.py));
}

double dot(Point A1, Point A2) {
	return A1.px * A2.px + A1.py * A2.py;
}

double crs(Point A1, Point A2) {
	return A1.px * A2.py - A1.py * A2.px;
}

// Distance from line A1A2 to A3
double Dist_Line(Point A1, Point A2, Point A3) {
	double V1 = dot(A2 - A1, A3 - A1);
	double V2 = dot(A1 - A2, A3 - A2);
	if (V1 < 0.0 || V2 < 0.0 || ABS(A1 - A2) < 1e-6) return min(ABS(A1 - A3), ABS(A2 - A3));
	return 1.0 * abs(crs(A2 - A1, A3 - A1)) / ABS(A1 - A2);
}

int W, N;
int Verts[209]; Point P[209][209];
double dist[209][209];
double stt[209], gol[209];

double Dist_Polygon(int idx1, int idx2) {
	double minx = 1e9;
	for (int i = 0; i < Verts[idx1]; i++) {
		for (int j = 0; j < Verts[idx2]; j++) {
			Point P1 = P[idx2][(j + 0) % Verts[idx2]];
			Point P2 = P[idx2][(j + 1) % Verts[idx2]];
			Point P3 = P[idx1][i];
			double val = Dist_Line(P1, P2, P3);
			minx = min(minx, val);
		}
	}
	for (int i = 0; i < Verts[idx2]; i++) {
		for (int j = 0; j < Verts[idx1]; j++) {
			Point P1 = P[idx1][(j + 0) % Verts[idx1]];
			Point P2 = P[idx1][(j + 1) % Verts[idx1]];
			Point P3 = P[idx2][i];
			double val = Dist_Line(P1, P2, P3);
			minx = min(minx, val);
		}
	}
	return minx;
}

int main() {
	//FILE *in = freopen("in1.txt", "r", stdin);
	
	while (true) {
		// Input
		cin >> W >> N; if (W + N == 0) break;
		for (int i = 0; i < N; i++) {
			cin >> Verts[i];
			stt[i] = W; gol[i] = W;
			for (int j = 0; j < Verts[i]; j++) cin >> P[i][j].px >> P[i][j].py;
			for (int j = 0; j < Verts[i]; j++) stt[i] = min(stt[i], P[i][j].px);
			for (int j = 0; j < Verts[i]; j++) gol[i] = min(gol[i], 1.0 * W - P[i][j].px);
		}
		
		// Get Distance
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				if (i == j) dist[i][j] = 0.0;
				else dist[i][j] = Dist_Polygon(i, j);
			}
		}
		
		// Warshall-Floyd
		for (int k = 0; k < N; k++) {
			for (int i = 0; i < N; i++) {
				for (int j = 0; j < N; j++) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
			}
		}
		
		// Output
		double Answer = W;
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				Answer = min(Answer, stt[i] + gol[j] + dist[i][j]);
			}
		}
		printf("%.12lf\n", Answer);
	}
	return 0;
}
accuracy: 1
time_ms: 110
memory_kb: 4456
final_rank: 9

code_snippet: #pragma GCC optimize ("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;

struct point{
    double x,y;
    point() {}
    point(double x,double y) : x(x), y(y) {}
    point operator- (const point& p){
        return point(x-p.x, y-p.y);
    }
    double dist(point p){
        return sqrt((x-p.x)*(x-p.x) + (y-p.y)*(y-p.y));
    }
};
double dot(point a, point b){
    return a.x*b.x + a.y*b.y;
}
double cross(point a, point b){
    return a.x*b.y - a.y*b.x;
}
struct line{
    point A,B;
    line(point A,point B) : A(A), B(B) {}
    double len(){
        return A.dist(B);
    }
    // 直線と点の距離
    double l_dist(point p){
        double crs = cross(p-A, B-A);
        return abs(crs) / len();
    }
    // 線分と点の距離
    double s_dist(point p){
        if(dot(p-A, B-A) < 0) return A.dist(p);
        else if(dot(p-B, A-B) < 0) return B.dist(p);
        else return l_dist(p);
    }
};

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int w,n;
    while(cin >> w >> n,w){
        vector<vector<point>> v(n+2);
        for (int i = 0; i < n; ++i) {
            int m; cin >> m;
            for (int j = 0; j < m; ++j) {
                int x,y; cin >> x >> y;
                v[i].push_back(point(x,y));
            }
            v[i].push_back(v[i][0]);
        }
        v[n].push_back(point(0,0));
        v[n].push_back(point(0,20000));
        v[n+1].push_back(point(w,0));
        v[n+1].push_back(point(w,20000));
        const double inf = 1e9;
        vector<vector<double>> d(n+2,vector<double>(n+2, inf));
        auto dis = [&](int i,int j)->double{
            if(i == j) return 0;
            double res = inf;
            for(auto p:v[i]){
                for (int k = 0; k+1 < v[j].size(); ++k) {
                    line l = line(v[j][k], v[j][k+1]);
                    res = min(res, l.s_dist(p));
                }
            }
            swap(i, j);
            for(auto p:v[i]){
                for (int k = 0; k+1 < v[j].size(); ++k) {
                    line l = line(v[j][k], v[j][k+1]);
                    res = min(res, l.s_dist(p));
                }
            }
            return res;
        };
        for (int i = 0; i < n+2; ++i) {
            for (int j = i; j < n+2; ++j) {
                auto r = dis(i, j);
                d[i][j] = d[j][i] = r;
            }
        }
        for (int k = 0; k < n+2; ++k) {
            for (int i = 0; i < n+2; ++i) {
                for (int j = 0; j < n+2; ++j) {
                    d[i][j] = min(d[i][j], d[i][k]+d[k][j]);
                }
            }
        }
        printf("%.9f\n", d[n][n+1]);
    }
}
accuracy: 1
time_ms: 60
memory_kb: 3712
final_rank: 3

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

// Geometry Library
// written by okuraofvegetable

#define pb push_back
#define DOUBLE_INF 1e50
#define Points vector<Point>

#define EQ(a, b) (abs((a) - (b)) < eps)
#define GT(a, b) ((a) > (b))
#define GE(a, b) (EQ(a, b) || GT(a, b))
#define LT(a, b) ((a) < (b))
#define LE(a, b) (EQ(a, b) || LT(a, b))

inline double add(double a, double b) {
  if (abs(a + b) < eps * (abs(a) + abs(b))) return 0;
  return a + b;
}

// --------------------- Point -----------------------

#define Vector Point
struct Point {
  double x, y;
  Point() {}
  Point(double x, double y) : x(x), y(y) {}
  Point operator+(Point p) { return Point(add(x, p.x), add(y, p.y)); }
  Point operator-(Point p) { return Point(add(x, -p.x), add(y, -p.y)); }
  Point operator*(double d) { return Point(x * d, y * d); }
  Point operator/(double d) { return Point(x / d, y / d); }
  double dot(Point p) { return add(x * p.x, y * p.y); }
  double det(Point p) { return add(x * p.y, -y * p.x); }
  double norm() { return sqrt(x * x + y * y); }
  double norm2() { return x * x + y * y; }
  double dist(Point p) { return ((*this) - p).norm(); }
  double dist2(Point p) { return sq(x - p.x) + sq(y - p.y); }
  double arg() { return atan2(y, x); }             // [-PI,PI]
  double arg(Vector v) { return v.arg() - arg(); } // henkaku
  double angle(Vector v) {                         // [0,PI]
    return acos(cos(arg(v)));
  }
  Vector normalize() { return (*this) * (1.0 / norm()); }
  Point vert() { return Point(y, -x); }

  // Signed area of triange (0,0) (x,y) (p.x,p.y)
  double area(Point p) { return (x * p.y - p.x * y) / 2.0; }
  friend istream &operator>>(istream &is, Point &p) { return is >> p.x >> p.y; }
  friend ostream &operator<<(ostream &os, const Point &p) {
    return os << '(' << p.x << ',' << p.y << ')';
  }
};

Point divide_rate(Point a, Point b, double A, double B) {
  assert(!EQ(A + B, 0.0));
  return (a * B + b * A) * (1.0 / (A + B));
}

Vector polar(double len, double arg) {
  return Vector(cos(arg) * len, sin(arg) * len);
}

// Direction a -> b -> c
// verified AOJ CGL_1_C
enum { COUNTER_CLOCKWISE, CLOCKWISE, ONLINE_BACK, ONLINE_FRONT, ON_SEGMENT };
int ccw(Point a, Point b, Point c) {
  Vector p = b - a;
  Vector q = c - a;
  if (p.det(q) > 0.0) return COUNTER_CLOCKWISE; // counter clockwise
  if (p.det(q) < 0.0) return CLOCKWISE;         // clockwise
  if (p.dot(q) < 0.0) return ONLINE_BACK;       // c--a--b online_back
  if (p.norm() < q.norm()) return ONLINE_FRONT; // a--b--c online_front
  return ON_SEGMENT;                            // a--c--b on_segment
}

// --------------------- Line ------------------------
struct Line {
  Point a, b;
  Line() {}
  Line(Point a, Point b) : a(a), b(b) {}
  bool on(Point q) { return EQ((a - q).det(b - q), 0.0); }
  // following 2 functions verified AOJ CGL_2_A
  bool is_parallel(Line l) { return EQ((a - b).det(l.a - l.b), 0.0); }
  bool is_orthogonal(Line l) { return EQ((a - b).dot(l.a - l.b), 0.0); }
  Point intersection(Line l) {
    assert(!is_parallel(l));
    return a + (b - a) * ((l.b - l.a).det(l.a - a) / (l.b - l.a).det(b - a));
  }
  // Projection of p to this line
  // verified AOJ CGL_1_A
  Point projection(Point p) {
    return (b - a) * ((b - a).dot(p - a) / (b - a).norm2()) + a;
  }
  double distance(Point p) {
    Point q = projection(p);
    return p.dist(q);
  }
  // Reflection point of p onto this line
  // verified AOJ CGL_1_B
  Point refl(Point p) {
    Point proj = projection(p);
    return p + ((proj - p) * 2.0);
  }
  bool left(Point p) {
    if ((p - a).det(b - a) > 0.0)
      return true;
    else
      return false;
  }
  friend istream &operator>>(istream &is, Line &l) { return is >> l.a >> l.b; }
  friend ostream &operator<<(ostream &os, const Line &l) {
    return os << l.a << " -> " << l.b;
  }
};

// ------------------- Segment  ----------------------
struct Segment {
  Point a, b;
  Segment() {}
  Segment(Point a, Point b) : a(a), b(b) {}
  Line line() { return Line(a, b); }
  bool on(Point q) {
    return (EQ((a - q).det(b - q), 0.0) && LE((a - q).dot(b - q), 0.0));
  }
  // verified AOJ CGL_2_B
  bool is_intersect(Segment s) {
    if (line().is_parallel(s.line())) {
      if (on(s.a) || on(s.b)) return true;
      if (s.on(a) || s.on(b)) return true;
      return false;
    }
    Point p = line().intersection(s.line());
    if (on(p) && s.on(p))
      return true;
    else
      return false;
  }
  bool is_intersect(Line l) {
    if (line().is_parallel(l)) {
      if (l.on(a) || l.on(b))
        return true;
      else
        return false;
    }
    Point p = line().intersection(l);
    if (on(p))
      return true;
    else
      return false;
  }
  // following 2 distance functions are verified at AOJ CGL_2_D
  double distance(Point p) {
    double res = DOUBLE_INF;
    Point q = line().projection(p);
    if (on(q)) res = min(res, p.dist(q));
    res = min(res, min(p.dist(a), p.dist(b)));
    return res;
  }
  double distance(Line l) {
    if (is_intersect(l)) return 0.0;
    double res = DOUBLE_INF;
    res = min(res, l.distance(a));
    res = min(res, l.distance(b));
    return res;
  }
  double distance(Segment s) {
    if (is_intersect(s)) return 0.0;
    double res = DOUBLE_INF;
    res = min(res, s.distance(a));
    res = min(res, s.distance(b));
    res = min(res, this->distance(s.a));
    res = min(res, this->distance(s.b));
    return res;
  }
  friend istream &operator>>(istream &is, Segment &s) {
    return is >> s.a >> s.b;
  }
  friend ostream &operator<<(ostream &os, const Segment &s) {
    return os << s.a << " -> " << s.b;
  }
};

// ------------------- Polygon -----------------------
// Note: A polygon generally don't need to be convex.

typedef vector<Point> Polygon;
// verified AOJ CGL_3_A
double area(Polygon &pol) {
  Points vec;
  double res = 0.0;
  int M = pol.size();
  for (int i = 0; i < M; i++) {
    res += (pol[i] - pol[0]).area(pol[(i + 1) % M] - pol[0]);
  }
  return res;
}

bool is_convex(Polygon &pol) {
  int n = pol.size();
  for (int i = 0; i < n - 1; i++) {
    if (ccw(pol[i], pol[i + 1], pol[(i + 2) % n]) == CLOCKWISE) {
      return false;
    }
  }
  return true;
}

// vecrified AOJ CGL_3_C
enum { OUT, ON, IN };
int contained(Polygon &pol, Point p) {
  int n = pol.size();
  Point outer(1e9, p.y);
  Segment s = Segment(outer, p);
  int cnt = 0;
  for (int i = 0; i < n; i++) {
    Segment e = Segment(pol[i], pol[(i + 1) % n]);
    if (e.on(p)) return ON;
    Vector a = pol[i] - p;
    Vector b = pol[(i + 1) % n] - p;
    if (a.y > b.y) swap(a, b);
    if (a.y <= 0.0 && b.y > 0.0) {
      if (a.det(b) < 0.0) cnt++;
    }
  }
  if ((cnt & 1) == 1)
    return IN;
  else
    return OUT;
}

// A compare function for convex_hull
// sort points by (x-y) lexicographical order.
// you can change (y-x) order with no change in convex_hull
bool comp(const Point &p, const Point &q) {
  if (!EQ(p.x, q.x))
    return p.x < q.x;
  else
    return p.y < q.y;
}

// Convex hull
// if you want not to contain points on boundary,
// change while(....<=0.0)
// verified AOJ CGL_4_A
Polygon convex_hull(vector<Point> ps) {
  sort(all(ps), comp);
  int k = 0;
  int n = ps.size();
  Polygon qs(2 * n);
  for (int i = 0; i < n; i++) {
    while (k > 1 && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) < 0.0) k--;
    qs[k++] = ps[i];
  }
  for (int i = n - 2, t = k; i >= 0; i--) {
    while (k > t && (qs[k - 1] - qs[k - 2]).det(ps[i] - qs[k - 1]) < 0.0) k--;
    qs[k++] = ps[i];
  }
  qs.resize(k - 1);
  return qs;
}

// Caliper method
// verified AOJ CGL_4_B
double convex_diameter(Polygon &cv) {
  int i = 0, j = 0;
  int n = cv.size();
  for (int k = 0; k < n; k++) {
    if (!comp(cv[i], cv[k])) i = k;
    if (comp(cv[j], cv[k])) j = k;
  }
  int si = i, sj = j;
  double res = 0.0;
  while (i != sj || j != si) {
    res = max(res, cv[i].dist(cv[j]));
    if ((cv[(i + 1) % n] - cv[i]).det(cv[(j + 1) % n] - cv[j]) < 0.0)
      i = (i + 1) % n;
    else
      j = (j + 1) % n;
  }
  return res;
}

// Cut conovex polygon by a line and return left polygon
// verified AOJ CGL_4_C
Polygon convex_cut(Polygon &cv, Line l) {
  int n = cv.size();
  Polygon left;
  for (int i = 0; i < n; i++) {
    Segment e = Segment(cv[i], cv[(i + 1) % n]);
    if (ccw(l.a, l.b, cv[i]) != CLOCKWISE) left.pb(cv[i]);
    if (e.is_intersect(l)) {
      if (!e.line().is_parallel(l)) { left.pb(e.line().intersection(l)); }
    }
  }
  return left;
}

// Distance between closest pair
// verified CGL_5_A
bool comp_y(const Point &p, const Point &q) {
  return p.y < q.y;
}
double closest_pair(vector<Point>::iterator a, int n) {
  if (n <= 1) return DOUBLE_INF;
  int m = n / 2;
  double x = (a + m)->x;
  double d = min(closest_pair(a, m), closest_pair(a + m, n - m));
  inplace_merge(a, a + m, a + n, comp_y);
  vector<Point> b;
  for (int i = 0; i < n; i++) {
    double ax = (a + i)->x;
    double ay = (a + i)->y;
    if (abs(ax - x) >= d) continue;
    for (int j = 0; j < b.size(); j++) {
      double dx = ax - b[b.size() - 1 - j].x;
      double dy = ay - b[b.size() - 1 - j].y;
      if (dy >= d) break;
      d = min(d, sqrt(dx * dx + dy * dy));
    }
    b.pb(*(a + i));
  }
  return d;
}
double closest_pair(vector<Point> a) {
  sort(all(a), comp);
  return closest_pair(a.begin(), (int)a.size());
}

template <class Cost = int>
struct edge {
  int from, to;
  Cost cost;
  edge() {}
  edge(int from, int to, Cost cost) : from(from), to(to), cost(cost) {}

  // for debug
  friend ostream &operator<<(ostream &os, const edge &e) {
    os << e.from << " -> " << e.to << " : " << e.cost << ", ";
    return os;
  }
};

template <class Cost = int>
struct Graph {
  int V;
  vector<vector<edge<Cost>>> G;
  Graph() {}
  Graph(int V) : V(V) { G.resize(V); }
  void add_edge(int a, int b, Cost cost = Cost(0)) {
    G[a].push_back(edge<Cost>(a, b, cost));
  }
  void add_edge_undirected(int a, int b, Cost cost = Cost(0)) {
    G[a].push_back(edge<Cost>(a, b, cost));
    G[b].push_back(edge<Cost>(b, a, cost));
  }
  size_t size() const { return G.size(); }
  const vector<edge<Cost>> &operator[](int id) const { return G[id]; }

  // for debug
  friend ostream &operator<<(ostream &os, const Graph g) {
    for (int i = 0; i < g.size(); i++) {
      os << g[i];
      if (i + 1 < g.size()) os << endl;
    }
    return os;
  }
};

// verified
// https://atcoder.jp/contests/dwacon6th-final-open/submissions/10023433
template <class Cost>
vector<Cost> dijkstra(Graph<Cost> &g, int s) {
  assert(0 <= s && s < g.size());
  vector<Cost> dist;
  dist.assign(g.size(), numeric_limits<Cost>::max());
  dist[s] = Cost(0);
  MinHeap<pair<Cost, int>> q;
  q.push(make_pair(Cost(0), s));
  while (!q.empty()) {
    auto a = q.top();
    q.pop();
    int v = a.second;
    if (dist[v] < a.first) continue;
    for (auto e : g[v]) {
      if (dist[e.to] > dist[v] + e.cost) {
        dist[e.to] = dist[v] + e.cost;
        q.push(make_pair(dist[e.to], e.to));
      }
    }
  }
  return dist;
}

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

bool solve() {
  int w, n;
  cin >> w >> n;
  if (w == 0 && n == 0) return false;

  vector<Polygon> ps(n);
  for (int i = 0; i < n; i++) {
    int m;
    cin >> m;
    for (int j = 0; j < m; j++) {
      Point p;
      cin >> p;
      ps[i].push_back(p);
    }
  }

  Graph<double> g(n + 2);
  int S = n, T = n + 1;

  for (int i = 0; i < n; i++) {
    for (int j = i + 1; j < n; j++) {
      double d = numeric_limits<double>::max();
      for (int k = 0; k < ps[i].size(); k++) {
        Segment is(ps[i][k], ps[i][(k + 1) % ps[i].size()]);
        for (int l = 0; l < ps[j].size(); l++) {
          Segment js(ps[j][l], ps[j][(l + 1) % ps[j].size()]);
          chmin(d, is.distance(js));
        }
      }
      dmp(i, j, d);
      g.add_edge(i, j, d);
      g.add_edge(j, i, d);
    }
  }

  {
    Line wall(Point(0.0, 0.0), Point(0.0, 1.0));
    for (int i = 0; i < n; i++) {
      double d = numeric_limits<double>::max();
      for (int j = 0; j < ps[i].size(); j++) {
        Segment seg(ps[i][j], ps[i][(j + 1) % ps[i].size()]);
        chmin(d, seg.distance(wall));
      }
      dmp(S, i, d);
      g.add_edge(S, i, d);
      g.add_edge(i, S, d);
    }
  }

  {
    Line wall(Point(w, 0.0), Point(w, 1.0));
    for (int i = 0; i < n; i++) {
      double d = numeric_limits<double>::max();
      for (int j = 0; j < ps[i].size(); j++) {
        Segment seg(ps[i][j], ps[i][(j + 1) % ps[i].size()]);
        chmin(d, seg.distance(wall));
      }
      dmp(i, T, d);
      g.add_edge(i, T, d);
      g.add_edge(T, i, d);
    }
  }

  auto dist = dijkstra(g, S);
  cout << min((double)w, dist[T]) << endl;

  return true;
}

int main() {
  fastio();
  if (!multitest) {
    while (solve()) {}
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 4496
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int i = 0; i < n; i++)
#define all(v) v.begin(), v.end()
template <class T, class U>
inline bool chmax(T &a, U b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}
template <class T, class U>
inline bool chmin(T &a, U b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
constexpr int INF = 1000000000;
constexpr ll llINF = 3000000000000000000;
constexpr int mod = 998244353;
constexpr double eps = 1e-10;
vector<int> prime_list(int n) {
    vector<int> v(n + 1), res;
    for (int i = n; i >= 2; i--) {
        for (int j = i; j <= n; j += i) v[j] = i;
    }
    for (int i = 2; i <= n; i++) {
        if (v[i] == i) res.push_back(i);
    }
    return res;
}
vector<int> next_divisor(int n) {
    vector<int> v(n + 1);
    for (int i = n; i >= 2; i--) {
        for (int j = i; j <= n; j += i) v[j] = i;
    }
    return v;
}
ll modpow(ll a, ll b, ll m = mod) {
    ll res = 1;
    while (b) {
        if (b & 1) {
            res *= a;
            res %= m;
        }
        a *= a;
        a %= m;
        b >>= 1;
    }
    return res;
}
vector<ll> inv, fact, factinv;
void init_fact(int n) {
    inv.resize(n + 1);
    fact.resize(n + 1);
    factinv.resize(n + 1);
    inv[0] = 0;
    inv[1] = 1;
    fact[0] = 1;
    factinv[0] = 1;
    for (ll i = 1; i <= n; i++) {
        if (i >= 2) inv[i] = mod - ((mod / i) * inv[mod % i] % mod);
        fact[i] = (fact[i - 1] * i) % mod;
        factinv[i] = factinv[i - 1] * inv[i] % mod;
    }
}
ll modinv(ll a, ll m = mod) {
    // gcd(a,m) must be 1
    ll b = m, u = 1, v = 0;
    while (b) {
        ll t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= m;
    if (u < 0) u += m;
    return u;
}
ll comb(int a, int b) {
    if (a < b) return 0;
    if (a < 0) return 0;
    return fact[a] * factinv[a - b] % mod * factinv[b] % mod;
}
struct point {
    double x, y;
    point() : x(0), y(0){};
    point(double x, double y) : x(x), y(y){};
    point operator+(point P) { return point(x + P.x, y + P.y); }
    point operator-(point P) { return point(x - P.x, y - P.y); }
    point operator*(double a) { return point(x * a, y * a); }
    double norm() { return x * x + y * y; }
    double abs() { return sqrt(norm()); }
};
double norm(point P) { return P.norm(); }
double abs(point P) { return P.abs(); }
double dist(point P, point Q) { return abs(Q - P); }
double dot(point P, point Q) { return P.x * Q.x + P.y * Q.y; }
double cross(point P, point Q) { return P.x * Q.y - P.y * Q.x; }
struct line {
    point A, B;
    line() {}
    line(point A, point B) : A(A), B(B) {}
};
point vec(line L) { return L.B - L.A; }
bool isParallel(line L, line M) { return abs(cross(vec(L), vec(M))) < eps; }
bool isOrthogonal(line L, line M) { return abs(dot(vec(L), vec(M))) < eps; }
int ccw(point A, point B, point C) {
    if (cross(B - A, C - A) > eps) return +1;
    if (cross(B - A, C - A) < -eps) return -1;
    if (dot(B - A, C - A) < -eps) return +2;
    if (norm(B - A) + eps < norm(C - A)) return -2;
    return 0;
}
bool intersect(line L, line M) { return ccw(L.A, L.B, M.A) * ccw(L.A, L.B, M.B) <= 0 && ccw(M.A, M.B, L.A) * ccw(M.A, M.B, L.B) <= 0; }
double p_l_d(point P, line L) { return abs(cross(P - L.A, vec(L))) / vec(L).abs(); }
double p_s_d(point P, line L) {
    if (dot(P - L.A, vec(L)) < 0) return dist(P, L.A);
    if (dot(P - L.B, vec(L)) > 0) return dist(P, L.B);
    return p_l_d(P, L);
}
double s_s_d(line L, line M) {
    if (intersect(L, M)) return 0;
    return min({p_s_d(L.A, M), p_s_d(L.B, M), p_s_d(M.A, L), p_s_d(M.B, L)});
}
point crosspoint(line L, line M) { return L.A + vec(L) * (cross(L.A - M.A, vec(M)) / cross(vec(M), vec(L))); }
void solve() {
    while (1) {
        int w, n;
        cin >> w >> n;
        if (w == 0) break;
        vector<vector<double>> dist(n + 2, vector<double>(n + 2, 1e9));
        vector<vector<line>> ls(n + 2);
        rep(i, n) {
            int m;
            cin >> m;
            vector<point> ps(m);
            ls[i].resize(m);
            for (auto &[x, y] : ps) cin >> x >> y;
            rep(j, m) ls[i][j] = line(ps[j], ps[(j + 1) % m]);
        }
        ls[n].push_back(line(point(0, 0), point(0, 1e9)));
        ls[n + 1].push_back(line(point(w, 0), point(w, 1e9)));
        rep(i, n + 2) {
            rep(j, n + 2) {
                if (i == j)
                    dist[i][j] = 0;
                else if (i + j == n + n + 1)
                    dist[i][j] = w;
                else {
                    for (line L : ls[i]) {
                        for (line M : ls[j]) {
                            chmin(dist[i][j], s_s_d(L, M));
                        }
                    }
                }
            }
        }
        rep(k, n + 2) rep(i, n + 2) rep(j, n + 2) chmin(dist[i][j], dist[i][k] + dist[k][j]);
        printf("%.12lf\n", dist[n][n + 1]);
    }
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    solve();
}
accuracy: 1
time_ms: 140
memory_kb: 3648
final_rank: 7

code_snippet: /*
2021年版
メモ
norm(P) Pの絶対値の2乗 abs(P)の2乗
abs(P) Pの絶対値
arg(P)の戻り値の範囲は[-π, π]
polar(長さ,角度(ラジアン))でPointができる
int(-2.2+0.5)=-1
*/

#include <bits/stdc++.h>
using namespace std;
template<class T,class U>constexpr bool chmin(T&a,const U b){if(a<=b)return false;a=b;return true;}
template<class T,class U>constexpr bool chmax(T&a,const U b){if(a>=b)return false;a=b;return true;}
template<class T,class U>constexpr bool bitUP(const T n,const U k){return (n>>k)&1;}

////////////////////////////
// マクロや型
////////////////////////////

using DD=long double;

const DD EPS=1e-9;
const DD INF=1e50;
const DD PI=acosl(-1.0);
#define EQ(a,b) (abs( (a) - (b) )<EPS) //a==b
#define LS(a,b) ( (a)+EPS<(b) ) //a<b
#define GR(a,b) ( (a)>(b)+EPS ) //a>b
#define LE(a,b) ( (a)<(b)+EPS ) //a<=b
#define GE(a,b) ( (a)>(b)-EPS ) //a>=b

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


//点
using Point=complex<DD>;
istream &operator>>(istream &is,Point &p) {
  DD x,y;
  is>>x>>y;
  p=Point(x,y);
  return is;
}
ostream &operator<<(ostream &os,const Point &p) {
  os<<p.X<<" "<<p.Y;
  return os;
}


void debug(const Point &p,string name=""){
    cout<<p;
    if(name!="") cout<<" "<<name;
    cout<<endl;
}
void debug(const Point &p,int id){
    debug(p,"P"+to_string(id));
}


//点a→点bの線分
//aとbが等しい時、色々バグるから注意!
struct Segment{
    Point a,b;
    Segment()=default;
    Segment(Point a,Point b) :a(a),b(b){}
    Segment(DD ax,DD ay,DD bx,DD by):a(ax,ay),b(bx,by){}
    Segment(DD r,Point a) :a(a),b(a+polar((DD)1.0,r)){}

    void debug(bool isLine=false,string name=""){
        if(isLine){
            cout<<"Line "<<b.Y-a.Y<<" "<<a.X-b.X<<" "<<-a.X*b.Y+b.X*a.Y<<endl;
        }else{
            cout<<"Segment "<<a<<" "<<b<<endl;
        }
        if(name!="") cout<<a<<" "<<name<<endl;
    }
    void debug(int id,bool isLine=false){
        if(isLine) debug(true,"L"+to_string(id));
        else debug(false,"S"+to_string(id));
    }
};
using Line=Segment;

//円
struct Circle{
    Point p;
    DD r;
    Circle()=default;
    Circle(Point p,DD r):p(p),r(r){}
    void debug(string name=""){
        cout<<"Circle "<<p<<" "<<r<<endl;
        if(name!="") cout<<p<<" "<<name<<endl;
    }
    void debug(int id){
        debug("C"+to_string(id));
    }
};

using Polygon=vector<Point>;
void debug(Polygon pol,string name=""){
    cout<<"Polygon"<<endl;
    for(auto p:pol){
        cout<<p;
        cout<<endl;
    }
    cout<<"..."<<endl;
    if(name!="") cout<<pol[0]<<" "<<name<<endl;
}
void debug(Polygon pol,int id){
    debug(pol,"T"+to_string(id));
}


////////////////////////////
// 基本計算
////////////////////////////

//度→ラジアン
inline DD torad(const DD deg){return deg*PI/180;}
//ラジアン→度
inline DD todeg(const DD rad){return rad*180/PI;}
//内積 |a||b|cosθ
inline DD dot(const Point &a,const Point &b){return (conj(a)*b).X;}
//外積 |a||b|sinθ
inline DD cross(const Point &a,const Point &b){return (conj(a)*b).Y;}
//ベクトルpを反時計回りにtheta(ラジアン)回転
Point rotate(const Point &p,const DD theta){return p*Point(cos(theta),sin(theta));}

//余弦定理 cos(角度abc(ラジアン))を返す
//長さの対応に注意 ab:辺abの長さ
//verify:https://codeforces.com/gym/102056/problem/F
DD cosine_formula(const DD ab,const DD bc,const DD ca){
    return (ab*ab+bc*bc-ca*ca)/(2*ab*bc);
}

inline bool xy_sort(const Point &a,const Point &b){
    if(a.X+EPS<b.X) return true;
    if(EQ(a.X,b.X) && a.Y+EPS<b.Y) return true;
    return false;
}
inline bool yx_sort(const Point &a,const Point &b){
    if(a.Y+EPS<b.Y) return true;
    if(EQ(a.Y,b.Y) && a.X+EPS<b.X) return true;
    return false;
}
namespace std{
    inline bool operator<(const Point &a,const Point &b)noexcept{
        return xy_sort(a,b);
    }
}
//DDの比較関数
//map<DD,vector<pii>,DDcom>
struct DDcom{
    bool operator()(const DD a, const DD b) const noexcept {
        return a+EPS<b;
    }
};


////////////////////////////
// 平行や直交
////////////////////////////

bool isOrthogonal(const Point &a,const Point &b){
    return EQ(dot(a,b),0.0);
}
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool isOrthogonal(const Segment &s,const Segment &t){
    return EQ(dot(s.a-s.b,t.a-t.b),0.0);
}
bool isParallel(const Point &a,const Point &b){
    return EQ(cross(a,b),0.0);
}
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool isParallel(const Segment &s,const Segment &t){
    return EQ(cross(s.a-s.b,t.a-t.b),0);
}
//線分a→bに対して点cがどの位置にあるか
//反時計回り:1　時計回り:-1 直線上(a,b,c:-2 a,c,b:0 c,a,b:2)
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
//線分a→bの端点にcがあるなら0と判定されるはず
int ccw(const Point &a,Point b,Point c){
    if(EQ(abs(b-c),0) or EQ(abs(a-c),0)) return 0;
    b-=a;c-=a;
    if(cross(b,c)>EPS) return 1;
    if(cross(b,c)<-EPS) return -1;
    if(dot(b,c)<-EPS) return 2;
    if(LS(norm(b),norm(c))) return -2;
    return 0;
}

////////////////////////////
// 射影と反射
////////////////////////////

//射影
//直線lに点pから垂線を引いたときの交点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point project(const Point &p,const Line &l){
    Point base=l.b-l.a;
    DD r=dot(p-l.a,base)/norm(base);
    return l.a+base*r;
}
//反射
//直線lに対して点pと対称な点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflect(const Point &p,const Line &l){
    return p+(project(p,l)-p)*(DD)2.0;
}
//反射
//直線lに対して線分sと対称な線分(直線でも使える)
//verify:https://onlinejudge.u-aizu.ac.jp/solutions/problem/1171/review/6009447/bin101/C++17
Segment reflect(const Segment &s,const Line &l){
    return Segment(reflect(s.a,l) , reflect(s.b,l));
}

////////////////////////////
// 点との距離
////////////////////////////

//点と直線の距離
DD DistPL(const Point &p,const Line &l){
    return abs(cross(l.b-l.a,p-l.a))/abs(l.b-l.a);
}
//点と線分の距離
DD DistPS(const Point &p,const Segment &s){
    if( dot(s.b-s.a,p-s.a)<0.0 ) return abs(p-s.a);
    if( dot(s.a-s.b,p-s.b)<0.0 ) return abs(p-s.b);
    return DistPL(p,s);
}

////////////////////////////
// 線分と直線
////////////////////////////

//線分a-b,c-dは交差するか?
//接する場合も交差すると判定
//接する場合は交差しないとするなら<=を<に変換
bool intersect(const Point &a,const Point &b,const Point &c,const Point &d){
    return(ccw(a,b,c)*ccw(a,b,d)<=0 && ccw(c,d,a)*ccw(c,d,b)<=0);
}
//線分s,tは交差するか？
//接する場合も交差すると判定
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B&lang=ja
//接する場合は交差しないとするならintersectの<=を<に変換
bool intersect(const Segment &s,const Segment &t){
    return intersect(s.a,s.b,t.a,t.b);
}
// 2直線の交点
// 線分の場合はintersectをしてから使う
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C&lang=ja
Point crossPoint(const Line &s,const Line &t){
    Point base=t.b-t.a;
    DD d1=cross(base,t.a-s.a);
    DD d2=cross(base,s.b-s.a);
    if(EQ(d1,0) and EQ(d2,0)) return s.a; //同じ直線
    if(EQ(d2,0)) assert(false); //交点がない
    return s.a+d1/d2*(s.b-s.a);
}
//線分と線分の距離
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D&lang=ja
DD Dist(const Segment &s,const Segment &t){
    if(intersect(s,t)) return 0.0;
    return min(min(DistPS(t.a,s),DistPS(t.b,s)),min(DistPS(s.a,t),DistPS(s.b,t)) );
}
bool issame(const Line &l,const Line &m){
    if (GR(abs(cross(m.a - l.a, l.b - l.a)),0) ) return false;
    if (GR(abs(cross(m.b - l.a, l.b - l.a)),0) ) return false;
    return true;
}
//垂直二等分線
//p-↑-q こんなかんじ
//voronoiで使う
Line bisector(const Point &p, const Point &q) {
    Point c=(p+q)/DD(2.0);
    Point v=rotate(q-p,PI/2);
    v/=abs(v);
    return Line(c-v,c+v);
}

////////////////////////////
// 円
////////////////////////////
//直線lと円Cの交点
//l.aにより近い方がindexが小さい
//veirfy:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
vector<Point> crossPointLC(const Line &l,const Circle &c){
    vector<Point> ret;
    if(GR(DistPL(c.p,l),c.r)) return ret; //交点がないとき、空ベクトルを返す
    Point pr=project(c.p,l);
    Point e=(l.b-l.a)/(abs(l.b-l.a));
    DD base=sqrt(c.r*c.r-norm(pr-c.p));
    ret.push_back(pr-e*base);
    ret.push_back(pr+e*base);
    if(EQ(DistPL(c.p,l),c.r)) ret.pop_back(); //接するとき
    return ret;
}
//線分sと円cの交点
//交点がないときは空ベクトルを返す
//線分の端が交わる場合も交点とみなす
//s.aにより近い方がindexが小さい
vector<Point> crossPointSC(const Segment &s,const Circle &c){
    vector<Point> ret;
    if(DistPS(c.p,s)>c.r+EPS) return ret;
    auto koho=crossPointLC(s,c);
    for(auto p:koho){
        if(ccw(s.a,s.b,p)==0 or EQ(abs(p-s.a),0) or EQ(abs(p-s.b),0)) ret.push_back(p);
    }
    return ret;
}

//円aと円bの共通接線の数
//離れている:4 外接:3 交わる:2 内接:1 内包:0
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A
int intersect(const Circle &a,const Circle &b){
    DD d=abs(a.p-b.p);
    if(GR(d,a.r+b.r)) return 4;
    if(EQ(d,a.r+b.r)) return 3;
    if(EQ(d,abs(a.r-b.r))) return 1;
    if(LS(d,abs(a.r-b.r))) return 0;
    return 2;
}

//円aと円bの交点
//交点がないときは空ベクトルを返す
//verify:https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=6030152#1
vector<Point> crossPoint(const Circle &a,const Circle &b){
    vector<Point> ret;
    int type=intersect(a,b);
    if(type==4 or type==0) return ret;
    DD d=abs(a.p-b.p);
    DD s=acosl((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d)); //0~π
    DD t=arg(b.p-a.p);
    if(type==3 or type==1) ret.push_back(a.p+polar(a.r,t));
    else ret.push_back(a.p+polar(a.r,t+s)),ret.push_back(a.p+polar(a.r,t-s));
    return ret;
}

//点pから円cに接線を引いたときの接点
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F&lang=ja
vector<Point> TanLine(const Point &p,const Circle &c){
    vector<Point> ret;
    DD d=abs(p-c.p);
    if(LS(d,c.r)) return ret; //pがcの内部にある場合
    if(EQ(d,c.r)){
        ret.push_back(p);
        return ret; //円の線上にある場合
    } 
    return crossPoint(c,Circle(p,sqrt(d*d-c.r*c.r)));
}

//円a,bの共通接線
//https://www.slideshare.net/kujira16/ss-35861169
//Line.aは円aと接線の交点
//(接線と円bの交点)と(接線と円aの交点)が違う場合はLine.bは(接線と円bの交点)
//一致する場合は円aの中心からLine.aに向かうベクトルを反時計回りに90度回転したものを
//Line.aに足したもの
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2201
vector<Line> TanLine(const Circle &a,const Circle &b){
    DD d=abs(a.p-b.p);
    vector<Line> ret;
    //外接線
    if(intersect(a,b)>=2){
        if(EQ(a.r,b.r)){
            Point up=polar(a.r,arg(b.p-a.p)+PI/2);
            ret.emplace_back(a.p+up,b.p+up);
            ret.emplace_back(a.p-up,b.p-up);
        }else{
            Point q=(a.p*b.r-b.p*a.r)/(b.r-a.r);
            auto as=TanLine(q,a);
            auto bs=TanLine(q,b);
            assert(as.size()==2 and bs.size()==2);
            for(int i=0;i<2;i++){
                ret.emplace_back(as[i],bs[i]);
            }
        }
    }else if(intersect(a,b)==1){ //内接する場合
        Point dir;
        if(a.r>b.r) dir=polar(a.r,arg(b.p-a.p));
        else dir=polar(a.r,arg(a.p-b.p));
        ret.emplace_back(a.p+dir,a.p+dir+rotate(dir,PI/2));
    }
    //内接線
    if(GR(abs(a.p-b.p),a.r+b.r)){ //円が離れている場合
        Point q=a.p+(b.p-a.p)*a.r/(a.r+b.r);
        auto as=TanLine(q,a);
        auto bs=TanLine(q,b);
        assert(as.size()==2 and bs.size()==2);
        for(int i=0;i<2;i++){
            ret.emplace_back(as[i],bs[i]);
        }
    }else if(EQ(d,a.r+b.r)){ //円が接している場合
        Point dir=polar(a.r,arg(b.p-a.p));
        ret.emplace_back(a.p+dir,a.p+dir+rotate(dir,PI/2));
    }
    return ret;
}
//２つの円の共通部分の面積
//参考: https://tjkendev.github.io/procon-library/python/geometry/circles_intersection_area.html
//verify: https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=6005736#1
DD Area(const Circle &c1,const Circle &c2){
    DD cd=abs(c1.p-c2.p);
    if(LE(c1.r+c2.r,cd)) return 0; //円が離れている

    if(LE(cd,abs(c1.r-c2.r))) //片方の円が他方を包んでいる
        return min(c1.r,c2.r)*min(c1.r,c2.r)*PI;

    DD theta1=acosl(cosine_formula(c1.r,cd,c2.r));
    DD theta2=acosl(cosine_formula(c2.r,cd,c1.r));

    return c1.r*c1.r*theta1+c2.r*c2.r*theta2-c1.r*cd*sin(theta1);
}


////////////////////////////
// 三角形
////////////////////////////

//ヘロンの公式　三角形の面積を返す
//三角形が成立するか(平行ではないか)を忘れずに
DD Heron(const DD ad,const DD bd,const DD cd){
    DD s=(ad+bd+cd)/2;
    return sqrt(s*(s-ad)*(s-bd)*(s-cd));
}
//三角形の外接円
//isParallel()を使って三角形が成立するか(平行ではないか)を忘れずに
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_C
Circle CircumscribedCircle(const Point &a,const Point &b,const Point &c){
    Point bc=(b+c)/(DD)2.0;
    Line aa(bc,bc+rotate(c-b,PI/2));
    Point ab=(a+b)/(DD)2.0;
    Line cc(ab,ab+rotate(b-a,PI/2));
    Point p=crossPoint(aa,cc);
    return Circle(p,abs(a-p));
}
//三角形の内接円
//isParallel()を使って三角形が成立するか(平行ではないか)を忘れずに
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_B
Circle InCircle(const Point &a,const Point &b,const Point &c){
    Line aa(a,a+polar((DD)1.0,(arg(b-a)+arg(c-a))/(DD)2.0));
    Line bb(b,b+polar((DD)1.0,(arg(a-b)+arg(c-b))/(DD)2.0));
    Point p=crossPoint(aa,bb);
    return Circle(p,DistPL(p,Line(a,b)));
}

////////////////////////////
// 多角形
////////////////////////////

//点pが多角形gに対してどの位置にあるか
//中:2 辺上:1 外:0
//凸多角形である必要ない
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C
int contains(const Point &p,const vector<Point> &g){
    int n=(int)g.size();
    int x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(EQ(cross(a,b),0) && dot(a,b)<EPS) return 1;
        if(a.Y>b.Y) swap(a,b);
        if(a.Y<EPS && EPS<b.Y && cross(a,b)>EPS) x=!x;
    }
    return (x?2:0);
}
//凸性判定
//多角形gは凸か？
//gは反時計回りでも時計回りでもいい
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B
bool isConvex(const vector<Point> &g){
    int n=(int)g.size();
    if(n<=3) return true;
    int flag=0;
    int t;
    for(int i=0;i<n;i++){
        Point a(g[(i+1)%n]-g[i]),b(g[(i+2)%n]-g[i]);
        if(cross(a,b)>EPS) t=1;
        else if(cross(a,b)<-EPS) t=-1;
        else continue;
        if(flag==-t) return false;
        flag=t;
    }
    return true;
}

//凸包　アンドリューのアルゴリズム
//O(NlogN)
//反時計回りの多角形を返す
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A
vector<Point> ConvexHull(vector<Point> s,const bool on_edge){
    int j;
    if(on_edge) j=-1;
    else j=1;
    int sz=(int)s.size();
    if(sz<3) return s;
    sort(s.begin(),s.end(),yx_sort);

    int n=0;
    vector<Point> res(2*sz);
    for(int i=0;i<sz;i++){
        while(n>=2 && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
            n--;
        }
        res[n]=s[i];
        n++;
    }
    int t=n+1;
    for(int i=sz-2;i>=0;i--){
        while(n>=t && cross(res[n-1]-res[n-2],s[i]-res[n-2])<EPS*j){
            n--;
        }
        res[n]=s[i];
        n++;
    }
    res.resize(n-1);
    return res;
}

//多角形g(凸でなくてもいい)の符号付き面積
//反時計回りの多角形なら正の値を返す　時計回りなら負
//O(N)
//https://imagingsolution.net/math/calc_n_point_area/
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A
DD Area(const vector<Point> &g){
    DD ret=0.0;
    int n=(int)g.size();
    for(int i=0;i<n;i++){
        ret+=cross(g[i],g[(i+1)%n]);
    }
    return ret/2.0;
}

//凸多角形gを直線lで切断
//直線の左側(向きを考慮)にできる凸多角形を返す
//多角形gが反時計回りならば、反時計回りで返す(時計回りなら時計回り)
//直線上の頂点を含む線分の交点は含めてない
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C
vector<Point> ConvexCut(const vector<Point> &g,const Line &l){
    vector<Point> ret;
    int gz=(int)g.size();
    for(int i=0;i<gz;i++){
        Point now=g[i],next=g[(i+1)%gz];
        if(ccw(l.a,l.b,now)!=-1) ret.push_back(now);
        if(EQ(DistPL(now,l),0) or EQ(DistPL(next,l),0)) continue;
        if(ccw(l.a,l.b,now)*ccw(l.a,l.b,next)<0){
            ret.push_back(crossPoint(Line(now,next),l));
        }
    }
    return ret;
}
//部品
inline DD calc(const Point &a,const Point &b,const DD &r,const bool triangle){
    if(triangle) return cross(a,b);
    else return r*r*arg(b/a);
}
//部品
DD calcArea(const DD &r,const Point &a,const Point &b){
    if(EQ(abs(a-b),0)) return 0;
    bool ina=(abs(a)<r+EPS);
    bool inb=(abs(b)<r+EPS);
    if(ina && inb) return cross(a,b);
    auto cr=crossPointSC(Segment(a,b),Circle(Point(0,0),r));
    if(cr.empty()) return calc(a,b,r,false);
    auto s=cr[0],t=cr.back();
    return calc(s,t,r,true)+calc(a,s,r,ina)+calc(t,b,r,inb);
}
//円と多角形の共通部分の面積
//多角形が反時計回りならば正の値を返す
//凸多角形でなくても大丈夫
//http://drken1215.hatenablog.com/entry/2020/02/02/091000
//verify:https://onlinejudge.u-aizu.ac.jp/solutions/problem/CGL_7_H/review/6029584/bin101/C++17
DD Area(const Circle &c,const vector<Point> &g){
    DD ret=0.0;
    int gz=g.size();
    if(gz<=2) return ret;
    for(int i=0;i<gz;i++){
        ret+=calcArea(c.r,g[i]-c.p,g[(i+1)%gz]-c.p);
    }
    return ret/2.0;
}

//点と多角形の距離
//点が多角形の中にあるなら0
DD Dist(const Point &a,const vector<Point> &b){
	if(b.size()==1) return abs(a-b[0]);
	if(contains(a,b)>=1) return 0.0L;
	DD ret=INF;
	for(size_t i=0;i<b.size();i++){
		chmin(ret,DistPS(a,Segment(b[i],b[(i+1)%b.size()])));
	}
	return ret;
}

//多角形と多角形の距離
//どちらかが内側に入っていたら0
//全ての線分の組み合わせの距離を求めて、その最小が答え
//O(size(a)*size(b))
//sizeが1の時は点との距離になる
//verify:https://onlinejudge.u-aizu.ac.jp/solutions/problem/2827/review/6029565/bin101/C++17
DD Dist(const vector<Point> &a,const vector<Point> &b){
	DD ret=INF;
	if(a.size()==1) return Dist(a[0],b);
	if(b.size()==1) return Dist(b[0],a);

	if(contains(a[0],b)>=1) return 0.0L;
	if(contains(b[0],a)>=1) return 0.0L;

	for(size_t i=0;i<a.size();i++){
		for(size_t j=0;j<b.size();j++){
			Segment sa(a[i],a[(i+1)%a.size()]);
			Segment sb(b[j],b[(j+1)%b.size()]);
			chmin(ret,Dist(sa,sb));
		}
	}
	return ret;
}

////////////////////////////
// 最近(遠)点間距離
////////////////////////////
//部品
DD RecClosetPair(const vector<Point>::iterator it,const int n){
    if(n<=1) return INF;
    int m=n/2;
    DD x=it[m].X;
    DD d=min(RecClosetPair(it,m),RecClosetPair(it+m,n-m));
    inplace_merge(it,it+m,it+n,yx_sort);
    vector<Point> v;
    for(int i=0;i<n;i++){
        if(abs(it[i].X-x)>=d) continue;
        for(int j=0;j<int(v.size());j++){
            DD dy=it[i].Y-v[(int)v.size()-1-j].Y;
            if(dy>=d) break;
            DD dx=it[i].X-v[(int)v.size()-1-j].X;
            d=min(d,sqrt(dx*dx+dy*dy));
        }
        v.push_back(it[i]);
    }
    return d;
}
//最近点対の距離
//点が1つのときINFを返す
//O(NlogN)
//verify:https://onlinejudge.u-aizu.ac.jp/solutions/problem/CGL_5_A/review/6029593/bin101/C++17
DD ClosetPair(vector<Point> g){
    sort(g.begin(),g.end(),xy_sort);
    return RecClosetPair(g.begin(),g.size());
}

//最遠頂点間
//verify:http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B
DD Diameter(vector<Point> g){
    g=ConvexHull(g,1);
    int gz=g.size();
    int m=0,M=0;
    for(int i=1;i<gz;i++){
        if(g[i].Y<g[m].Y) m=i;
        if(g[i].Y>g[M].Y) M=i;
    }
    DD ret=0;
    int sm=m,sM=M;
    while(m!=sM || M!=sm){
        ret=max(ret,norm(g[m]-g[M]));
        if(cross(g[(m+1)%gz]-g[m],g[(M+1)%gz]-g[M])<0) m=(m+1)%gz;
        else M=(M+1)%gz;
    }
    return sqrt(ret);
}
//動的凸包
//辺上にある点は含めない
//verify:https://atcoder.jp/contests/geocon2013/tasks/geocon2013_c
struct DynamicConvex{
	set<Point> up,down;
	DynamicConvex(){}
 
	bool isContain(set<Point> &pol,Point p){
		if(pol.size()==0) return false;
		if(pol.size()==1){
			Point q=*begin(pol);
			return EQ(q.X,p.X) and GE(q.Y,p.Y);
		}
		assert(pol.size()>=2);
        auto left=begin(pol);
        auto right=(--end(pol));
        if(LS(p.X,left->X) or GR(p.X,right->X)) return false;
        
        
        auto q1=pol.upper_bound(Point(p.X,INF));
        if(q1==end(pol)){
            return GE(right->Y,p.Y);
        }
        auto q2=q1--; //q1が範囲外になるのは最初に弾いてる
        return GE(cross(p-*q1,*q2-*q1),0.0);
	}
    bool isContain(Point p){
        if(not isContain(up,p)) return false;
        if(not isContain(down,Point(p.X,-p.Y))) return false;
        return true;
    }
 
	void add(set<Point> &pol,Point p){
		if(pol.size()==0){
			pol.insert(p);
			return;
		}
		if(pol.size()==1){
            Point q=*begin(pol);
			if(EQ(q.X,p.X)){
                pol.clear();
                pol.insert(max(p,q));
			}else{
				pol.insert(p);
			}
            return;
		}
        assert(pol.size()>=2);
        if(isContain(pol,p)) return;
        //left
        auto q1=pol.upper_bound(Point(p.X,INF));
        if(q1!=begin(pol)){
            q1--;
            while(pol.size()>=1 and q1!=begin(pol)){
                auto q2=q1--;
                if(GR(cross(*q2-p,*q1-p),0)) break;
                pol.erase(q2);
            }
        }
        //right
        q1=pol.lower_bound(Point(p.X,-INF));
        if(q1!=end(pol)){
            while(pol.size()>1 and q1!=--end(pol)){
                auto q2=q1++;
                if(GR(cross(*q1-p,*q2-p),0.0)) break;
                pol.erase(q2);
            }
        }
        pol.insert(p);
	}
 
	void add(Point p){
		add(up,p);
		add(down,Point(p.X,-p.Y)); //upと同じように処理をしたいから
	}
};

//ボロノイ図
//pol:全体 ps:点の集合 id:中心となる点の添字 pp:中心となる点
//計算量: pol.size()*ps.size()
//verify: https://judge.u-aizu.ac.jp/onlinejudge/review.jsp?rid=6029611#1
vector<Point> voronoi(Polygon pol,const vector<Point> &ps,int id=-1,const Point pp=Point()){
    Point p;
    if(id!=-1) p=ps[id];
    else p=pp;
    for(int i=0;i<int(ps.size());i++){
        if(i==id) continue;
        Line l=bisector(p,ps[i]);
        pol=ConvexCut(pol,l);
    }
    return pol;
}

using Graph=vector<vector<int>>;

template<typename T >
struct edge {
	int to;
	T cost;
	edge()=default;
	edge(int to, T cost) : to(to), cost(cost) {}

};
template<typename T>
using WeightGraph=vector<vector<edge<T>>>;

template<class T>
vector<T> dijkstra(const vector< vector<edge<T>> > &g,int s,const T inf,const T zero){
    vector<T> dist(g.size(),inf);
    using pti=pair<T,int>;
    priority_queue<pti,vector<pti>,greater<pti>> que;
    dist[s]=zero;
    que.emplace(dist[s],s);
    while(!que.empty()){
      T cost;
      int idx;
      tie(cost,idx)=que.top();
      que.pop();
      if(dist[idx]<cost) continue;
      for(auto &e:g[idx]){
        auto next_cost=cost+e.cost;
        if(dist[e.to]<=next_cost) continue;
        dist[e.to]=next_cost;
        que.emplace(dist[e.to],e.to);
      }
    }
    return dist;
}


int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr); 
    cout<<fixed<<setprecision(20);
while(true){
    int W,N;
    cin>>W>>N;
    if(W==0) return 0;

    vector<Polygon> P;
    for(int i=0;i<N;i++){
        int M; cin>>M;
        Polygon pol;
        while(M--){
            Point p; cin>>p;
            pol.push_back(p);
        }
        P.push_back(pol);
    }

    WeightGraph<DD> g(N+2);
    for(int i=0;i<N;i++){
        for(int j=0;j<N;j++){
            if(i==j) continue;
            auto dist=Dist(P[i],P[j]);
            g[i].emplace_back(j,dist);
        }
        DD minX=INF,maxX=-1;
        for(auto p:P[i]){
            chmin(minX,p.X);
            chmax(maxX,p.X);
        }
        g[N].emplace_back(i,minX);
        g[i].emplace_back(N+1,W-maxX);
    }
    cout<<dijkstra<DD>(g,N,W,0LL)[N+1]<<endl;
}
}
accuracy: 1
time_ms: 1350
memory_kb: 5752
final_rank: 18

code_snippet: #include<bits/stdc++.h>
#include<complex>
#include<functional>
using namespace std;
#define ALL(x) begin(x),end(x)
#define rep(i,n) for(int i=0;i<(n);i++)
#define debug(v) cout<<#v<<":";for(auto x:v){cout<<x<<' ';}cout<<endl;
#define mp(X,Y) make_pair(X,Y)

#define mod 1000000007
using ll = long long;
const int INF = 1000000000;
const ll LINF = 1001002003004005006ll;
int dx[] = { 1,0,-1,0 }, dy[] = { 0,1,0,-1 };
// ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return true; }return false; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return true; }return false; }

struct IOSetup {
    IOSetup() {
        cin.tie(0);
        ios::sync_with_stdio(0);
        cout << fixed << setprecision(12);
    }
} iosetup;

template<typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int)v.size(); i++) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
    return os;
}
template<typename T>
istream& operator>>(istream& is, vector<T>& v) {
    for (T& x : v)is >> x;
    return is;
}

#line 1 "Geometry/template.cpp"
// Real
using Real = double;
const Real EPS = 1e-6;
const Real pi = acosl(-1);

// Point
using Point = complex<Real>;
istream& operator>>(istream& is, Point& p) {
    Real a, b;
    is >> a >> b;
    p = Point(a, b);
    return is;
}
ostream& operator<<(ostream& os, Point& p) {
    return os << fixed << setprecision(12) << p.real() << ' ' << p.imag();
}
inline bool eq(Real a, Real b) {
    return fabs(a - b) < EPS;
}
Point operator*(const Point& p, const Real& d) {
    return Point(real(p) * d, imag(p) * d);
}

// Line
struct Line {
    Point p1, p2;
    Line() = default;
    Line(Point p1, Point p2) :p1(p1), p2(p2) {}
    //Ax + By = C
    Line(Real A, Real B, Real C) {
        if (eq(A, 0))     p1 = Point(0, C / B), p2 = Point(1, C / B);
        else if (eq(B, 0))p1 = Point(C / A, 0), p2 = Point(C / A, 1);
        else            p1 = Point(0, C / B), p2 = Point(C / A, 0);
    }
};

// Segment
struct Segment :Line {
    Segment() = default;
    Segment(Point p1, Point p2) :Line(p1, p2) {}
};
struct Circle {
    Point center;
    Real r;
    Circle() = default;
    Circle(Point center, Real r) :center(center), r(r) {}
};

// Polygon
using Polygon = vector<Point>;
#line 1 "Geometry/Rotate.cpp"
Point rotate(Real theta, Point p) {
    return Point(cos(theta) * real(p) - sin(theta) * imag(p), sin(theta) * real(p) + cos(theta) * imag(p));
}
#line 1 "Geometry/Dot.cpp"
// Dot
Real dot(Point a, Point b) {
    return real(a) * real(b) + imag(a) * imag(b);
}
#line 1 "Geometry/Cross.cpp"
// Cross
Real cross(Point a, Point b) {
    return real(a) * imag(b) - imag(a) * real(b);
}
#line 1 "Geometry/CounterClockWise.cpp"
// ccw (counter clockwise) (Requires: cross, dot)
//https://onlinejudge.u-aizu.ac.jp/courses/library/4/CGL/all/CGL_1_C
int ccw(Point a, Point b, Point c) {
    b -= a; c -= a;
    if (cross(b, c) > EPS)       return  1;//COUNTER CLOCKWISE
    else if (cross(b, c) < -EPS) return -1;//CLOCKWISE
    else if (dot(b, c) < 0)      return  2;//c--a--b ONLINE BACK
    else if (norm(b) < norm(c)) return -2;//a--b--c ONLINE FRONT
    else                     return  0;//a--c--b ON SEGMENT
}
#line 1 "Geometry/Projection.cpp"
// Projection (Requires: dot)
Point projection(Line l, Point p) {
    // ベクトルl乗に点pからおろした垂線の足
    Real k = dot(l.p1 - l.p2, p - l.p1) / norm(l.p1 - l.p2);
    return l.p1 + (l.p1 - l.p2) * k;
}
Point projection(Segment l, Point p) {
    Real k = dot(l.p1 - l.p2, p - l.p1) / norm(l.p1 - l.p2);
    return l.p1 + (l.p1 - l.p2) * k;
}
#line 1 "Geometry/Intersect.cpp"
// Intersect (Requires : ccw, Dots, Cross, Projection)
bool intersect(Line l, Point p) {
    return abs(ccw(l.p1, l.p2, p)) != 1;
}
//直線の交差判定，外積
bool intersect(Line l1, Line l2) {
    return abs(cross(l1.p2 - l1.p1, l2.p2 - l2.p1)) > EPS || abs(cross(l1.p2 - l1.p1, l2.p2 - l1.p1)) < EPS;
}
//線分に点が乗るかの判定，ccw
bool intersect(Segment s, Point p) {
    return ccw(s.p1, s.p2, p) == 0;
}
//直線と線分の交差判定
bool intersect(Line l, Segment s) {
    return cross(l.p2 - l.p1, s.p1 - l.p1) * cross(l.p2 - l.p1, s.p2 - l.p1) < EPS;
}
//円と直線の交差判定
bool intersect(Circle c, Line l) {
    return abs(c.center - projection(l, c.center)) <= c.r + EPS;
}
//円上かどうか，内部かどうかではない
bool intersect(Circle c, Point p) {
    return abs(abs(p - c.center) - c.r) < EPS;
}
//線分と線分の交差判定
bool intersect(Segment s, Segment t) {
    return ccw(s.p1, s.p2, t.p1) * ccw(s.p1, s.p2, t.p2) <= 0 && ccw(t.p1, t.p2, s.p1) * ccw(t.p1, t.p2, s.p2) <= 0;
}
//線分と円の交差判定，交点の個数を返す
int intersect(Circle c, Segment l) {
    Point h = projection(l, c.center);
    //直線まるっと円の外側
    if (norm(h - c.center) - c.r * c.r > EPS)    return 0;
    Real d1 = abs(c.center - l.p1), d2 = abs(c.center - l.p2);
    //線分が円内
    if (d1 < c.r + EPS && d2 < c.r + EPS) return 0;
    if ((d1<c.r - EPS && d2>c.r + EPS) || (d2<c.r - EPS && d1>c.r + EPS)) return 1;
    //円の外部にまるまるはみ出ていないか
    if (dot(l.p1 - h, l.p2 - h) < 0) return 2;
    return 0;
}
//円と円の位置関係，共通接線の個数を返す
int intersect(Circle c1, Circle c2) {
    if (c1.r < c2.r) swap(c1, c2);
    Real d = abs(c1.center - c2.center);
    //2円が離れている
    if (c1.r + c2.r < d)     return 4;
    //2円が外接する
    if (eq(c1.r + c2.r, d)) return 3;
    //2円が交わる
    if (c1.r - c2.r < d)     return 2;
    //円が内接する
    if (eq(c1.r - c2.r, d)) return 1;
    //内包
    return 0;
}
#line 1 "Geometry/Distance.cpp"
// Distance (Requires: Projection, Intersect)
Real dis(Point a, Point b) {
    return abs(a - b);
}
Real dis(Line l, Point p) {
    return abs(p - projection(l, p));
}
Real dis(Segment s, Point p) {
    Point r = projection(s, p);
    if (intersect(s, r)) return abs(r - p);
    return min(abs(s.p1 - p), abs(s.p2 - p));
}
Real dis(Segment a, Segment b) {
    if (intersect(a, b)) return 0;
    return min({ dis(a,b.p1),dis(a,b.p2),dis(b,a.p1),dis(b,a.p2) });
}
Real dis(Polygon a, Polygon b) {
    Real ret = -10;
    int n = (int)a.size(), m = (int)b.size();
    for (int i = 0; i < n; i++)for (int j = 0; j < m; j++) {
        Real d = dis(Segment(a[i], a[(i + 1) % n]), Segment(b[j], b[(j + 1) % m]));
        if (ret < 0) ret = d;
        else      ret = min(ret, d);
    }
    return ret;
}
Real dis(Polygon poly, Point p) {
    Real ret = -10;
    int n = (int)poly.size();
    for (int i = 0; i < n; i++) {
        Real d = dis(Segment(poly[i], poly[(i + 1) % n]), p);
        if (ret < 0) ret = d;
        else      ret = min(ret, d);
    }
    return ret;
}
#line 1 "Geometry/CrossPoint.cpp"
//intersectをチェックすること
//v
Point crosspoint(Line l, Line m) {
    Real A = cross(m.p2 - m.p1, m.p1 - l.p1);
    Real B = cross(m.p2 - m.p1, l.p2 - l.p1);
    if (eq(A, 0) && eq(B, 0)) return l.p1;
    if (eq(B, 0))             throw "NAI";
    return l.p1 + A / B * (l.p2 - l.p1);
}
Point crosspoint(Segment l, Segment m) {
    return crosspoint(Line(l), Line(m));
}
vector<Point> crosspoint(Circle c, Line l) {
    vector<Point> ret;
    Point h = projection(l, c.center);
    Real d = sqrt(c.r * c.r - norm(h - c.center));
    Point e = (l.p2 - l.p1) * (1 / abs(l.p2 - l.p1));
    if (c.r * c.r + EPS < norm(h - c.center)) return ret;
    if (eq(dis(l, c.center), c.r)) {
        ret.push_back(h);
        return ret;
    }
    ret.push_back(h + e * d); ret.push_back(h - e * d);
    return ret;
}
//要verify，
vector<Point> crosspoint(Circle c, Segment s) {
    Line l = Line(s.p1, s.p2);
    int ko = intersect(c, s);
    if (ko == 2) return crosspoint(c, l);
    vector<Point> ret;
    if (ko == 0) return ret;
    ret = crosspoint(c, l);
    if (ret.size() == 1) return ret;
    vector<Point> rret;
    //交点で挟める方を返す
    if (dot(s.p1 - ret[0], s.p2 - ret[0]) < 0)  rret.push_back(ret[0]);
    else                                rret.push_back(ret[1]);
    return rret;
}
//v
vector<Point> crosspoint(Circle c1, Circle c2) {
    vector<Point> ret;
    int isec = intersect(c1, c2);
    if (isec == 0 || isec == 4) return ret;
    Real d = abs(c1.center - c2.center);
    Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    Real t = atan2(c2.center.imag() - c1.center.imag(), c2.center.real() - c1.center.real());
    ret.push_back(c1.center + Point(cos(t + a) * c1.r, sin(t + a) * c1.r));
    ret.push_back(c1.center + Point(cos(t - a) * c1.r, sin(t - a) * c1.r));
    return ret;
}
#line 1 "Geometry/Angle.cpp"
// angle of a-b-c
Real get_smaller_angle(Point a, Point b, Point c) {
    Point v = a - b, w = c - b;
    auto A = atan2(imag(v), real(v));
    auto B = atan2(imag(w), real(w));
    if (A > B) swap(A, B);
    Real res = B - A;
    return min(res, pi * 2.0 - res);
}
#line 1 "Geometry/InscribedCircle.cpp"
// 内接円
Circle inscribed_circle(Point a, Point b, Point c) {
    Real A, B;
    {
        Point t = c - a;
        t *= conj(b - a);
        t /= norm(b - a);
        A = atan2(imag(t), real(t));
    }
    {
        Point t = a - b;
        t *= conj(c - b);
        t /= norm(c - b);
        B = atan2(imag(t), real(t));
    }
    Line Amid = Line(a, a + rotate(A * 0.5, b - a)), Bmid = Line(b, b + rotate(B * 0.5, c - b));
    auto center = crosspoint(Amid, Bmid);
    auto h = projection(Line(a, b), center);
    return Circle(center, dis(h, center));
}
#line 1 "Geometry/CircumscribedCircle.cpp"
// 外接円
Circle circumscribed_circle(Point a, Point b, Point c) {
    Line orth_ab((a + b) * 0.5, (a + b) * 0.5 + Point(-imag(b - a), real(b - a)));
    Line orth_bc((b + c) * 0.5, (b + c) * 0.5 + Point(-imag(c - b), real(c - b)));
    Point center = crosspoint(orth_ab, orth_bc);
    Real r = dis(a, center);
    return Circle(center, r);
}
#line 1 "Geometry/Tangent.cpp"
//v
//点pから引いた円cの接線の接点を返す
vector<Point> tangent(Circle c, Point p) {
    return crosspoint(c, Circle(p, sqrt(norm(c.center - p) - c.r * c.r)));
}
//v
//二円の共通接線，Lineの2点は接点を表す
vector<Line> tangent(Circle c1, Circle c2) {
    vector<Line> ret;
    if (c1.r < c2.r) swap(c1, c2);
    Real g = norm(c1.center - c2.center);
    if (eq(g, 0)) return ret;
    Point u = (c2.center - c1.center) / sqrt(g);
    Point v = rotate(pi * 0.5, u);
    for (int s : {-1, 1}) {
        Real h = (c1.r + s * c2.r) / sqrt(g);
        if (eq(1 - h * h, 0)) {
            ret.push_back(Line(c1.center + u * c1.r, c1.center + (u + v) * c1.r));
        }
        else if (1 - h * h > 0) {
            Point uu = u * h, vv = v * sqrt(1 - h * h);
            ret.push_back(Line(c1.center + (uu + vv) * c1.r, c2.center - (uu + vv) * c2.r * s));
            ret.push_back(Line(c1.center + (uu - vv) * c1.r, c2.center - (uu - vv) * c2.r * s));
        }
    }
    return ret;
}
#line 1 "Geometry/Contain.cpp"
// out 0, on 1, in 2
int contains(Polygon poly, Point p) {
    int res = 0;
    int n = (int)poly.size();
    for (int i = 0; i < n; i++) {
        Point a = poly[i] - p, b = poly[(i + 1) % n] - p;
        if (imag(a) > imag(b)) swap(a, b);
        if (imag(a) <= 0 && 0 < imag(b) && cross(a, b) < 0) res ^= 1;
        if (eq(cross(a, b), 0) && (dot(a, b) < 0 || eq(dot(a, b), 0))) return 1;
    }
    if (res) res = 2;
    return res;
}
#line 1 "Geometry/MinimumBoundingCircle.cpp"
//最小包含円を返す　計算量は期待値O(n)
/*
Circle MinimumBoundingCircle(vector<Point> v){
    int n=v.size();
    //ランダムシャッフル．いぢわるされたくないもんだ
    mt19937 mt(time(0));
    shuffle(v.begin(),v.end(),mt);
    Circle ret(0,0);

    auto make_circle2=[&](Point a,Point b){
        return Circle((a+b)*0.5,dis(a,b)/2);
    };

    auto make_circle3=[&](Point A,Point B,Point C){
        Point cent=circumscribed_circle(A,B,C).center;
        return Circle(cent,dis(cent,A));
    };

    auto isIn=[&](Point a){
        return dis(ret.center,a)<ret.r+EPS;
    };

    ret=make_circle2(v[0],v[1]);
    for(int i=2;i<n;i++){
        //v[i]が円に入っていないなら
        if(!isIn(v[i])){
            //円内にないなら点v[i]は必ず円周上に来る
            ret=make_circle2(v[0],v[i]);
            for(int j=1;j<i;j++){
                if(!isIn(v[j])){
                    //この時iとjが円周上を考える
                    ret=make_circle2(v[i],v[j]);
                    //最後の1点の決定
                    for(int k=0;k<j;k++)if(!isIn(v[k])) ret=make_circle3(v[i],v[j],v[k]);
                }
            }
        }
    }
    return ret;
}*/
#line 1 "Geometry/ClosestPair.cpp"
// 最近点対
// O(NlogN)
Real closest_pair(vector<Point> ps) {
    sort(ALL(ps), [&](Point a, Point b) {
        return real(a) < real(b);
        });
    function<Real(int, int)> rec = [&](int l, int r) {
        if (r - l <= 1) return (Real)1e18;
        int m = (l + r) / 2;
        Real x = real(ps[m]);
        Real ret = min(rec(l, m), rec(m, r));
        inplace_merge(begin(ps) + l, begin(ps) + m, begin(ps) + r, [&](Point a, Point b) {
            return imag(a) < imag(b);
            });
        // 分割を跨いで最小距離があるか調べる
        vector<Point> b;
        for (int i = l; i < r; i++) {
            if (abs(real(ps[i]) - x) >= ret) continue;
            for (int j = (int)b.size() - 1; j >= 0; j--) {
                if (abs(imag(ps[i] - b[j])) >= ret) break;
                ret = min(ret, abs(ps[i] - b[j]));
            }
            b.push_back(ps[i]);
        }
        return ret;
    };
    return rec(0, (int)ps.size());
}
#line 1 "Geometry/Convex.cpp"
// 凸多角形系統
// 凸多角形の頂点は反時計周りに訪れる順序
// v
// 頂点は反時計周りに訪れる順序，時計回りとなるような3点があるとfalse
bool is_convex(const vector<Point>& ps) {
    int n = (int)ps.size();
    for (int i = 0; i < n; i++)if (ccw(ps[(i + n - 1) % n], ps[i], ps[(i + 1) % n]) == -1)return false;
    return true;
}

// 凸包，あんまりよくわかってない．直線状に頂点をのせない場合(↑)，のせる場合(↓)
vector<Point> convex_hull(vector<Point> p) {
    int n = (int)p.size(), k = 0;
    if (n <= 2)return p;
    sort(begin(p), end(p), [](Point a, Point b) {
        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
        });
    vector<Point>ch(2 * n);
    for (int i = 0; i < n; ch[k++] = p[i++]) {
        // while(k>=2 and cross(ch[k-1]-ch[k-2],p[i]-ch[k-1])<EPS)k--;
        while (k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    for (int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]) {
        // while(k>=t and cross(ch[k-1]-ch[k-2],p[i]-ch[k-1])<EPS)k--;
        while (k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0)k--;
    }
    ch.resize(k - 1);
    return ch;
}

vector<Point> crosspoint(Polygon poly, Circle c) {
    int n = (int)poly.size();
    vector<Point> ret;
    rep(i, n) {
        Segment seg = Segment(poly[i], poly[(i + 1) % n]);
        auto ps = crosspoint(c, seg);
        for (auto& p : ps) ret.push_back(p);
    }
    return ret;
}




#line 18 "Geometry/include.cpp"

Real get(Point a, Point b, Point c) {
    a -= b;
    c -= b;
    Real ret = atan2(real(c), imag(c)) - atan2(real(a), imag(a));
    while (ret > pi * 2) ret -= pi * 2;
    while (ret < 0) ret += pi * 2;
    return ret;
}

/*
aを中心とし，bをradだけ回すような扇と
polyの交差判定

polyとa-bの交差判定は行わない
*/
bool cross(Polygon& poly, Point a, Point b, Real rad) {
    int n = (int)poly.size();
    Real l = dis(a, b);
    Point v = rotate(rad, b - a) / l;
    // 多角形の返上に棒が載っている時，常にaで交差判定がtrueになるんじゃないか？
    // EPSだけズラしてみた．わからない
    Segment abrot = Segment(a + v * EPS, a + v * l);
    rep(i, n) {
        Segment seg = Segment(poly[i], poly[(i + 1) % n]);

        if (intersect(seg, abrot)) return true;
        auto h = projection(seg, a);
        auto hr = get(b, a, h);
        if (hr <= rad) return true;
    }
    return false;
}

Real L, R; int N;



int main() {
    while (1) {
        int W, N;
        cin >> W >> N;
        if (W == 0)return 0;

        vector<Polygon> Ob(N + 2);
        rep(n, N) {
            ll M;
            cin >> M;
            rep(m, M) {
                Point P;
                cin >> P;
                Ob[n].push_back(P);
            }
        }

        Point P = Point(0, -1e6);
        Ob[N].push_back(P);
        P = Point(0, 1e6);
        Ob[N].push_back(P);
        P = Point(W, -1e6);
        Ob[N + 1].push_back(P);
        P = Point(W, 1e6);
        Ob[N + 1].push_back(P);

        vector<Real> dist(N + 2, 1e18);
        dist[N] = 0.0;
        priority_queue<pair<Real, int>, vector<pair<Real, int>>, greater<pair<Real, int>>> Q;
        Q.push(make_pair(0.0, N));
        vector<bool> seen(N + 2, false);
        while (!Q.empty()) {
            auto p = Q.top();
            Q.pop();
            if (seen[p.second])continue;
            seen[p.second] = true;
            rep(i, N + 2) {
                Real d = dis(Ob[i], Ob[p.second]);
                if (dist[i] < dist[p.second] + d)continue;
                if (seen[i])continue;
                dist[i] = dist[p.second] + d;
                Q.push(make_pair(dist[i], i));
            }


        }
        cout << dist[N + 1] << endl;

    }
    //


}
accuracy: 1
time_ms: 550
memory_kb: 3868
final_rank: 13

code_snippet: #include <cmath>
#include <iostream>
#include <iomanip>
#include <tuple>
#include <vector>

#include <algorithm>
#include <limits>
#include <queue>
#include <vector>

namespace suisen {
template<typename Cost>
class dijkstra {
    public:
        template <typename Transition>
        dijkstra(unsigned int n, Transition transition, unsigned int src) : _src(src) {
            _par.resize(n);
            _dist.assign(n, UNREACHABLE);
            _dist[src] = 0;
            using state = std::pair<Cost, unsigned int>;
            std::priority_queue<state, std::vector<state>, std::greater<state>> pq;
            pq.emplace(0, src);
            auto g = [&](unsigned int u) {
                return [&, u](unsigned int v, Cost new_cost) {
                    if (new_cost < _dist[v]) pq.emplace(_dist[v] = new_cost, v), _par[v] = u;
                };
            };
            while (pq.size()) {
                auto [du, u] = pq.top(); pq.pop();
                if (du == _dist[u]) transition(u, du, g(u));
            }
        }
        dijkstra(const std::vector<std::vector<std::pair<int, Cost>>> &g, unsigned int src) :
            dijkstra(g.size(), [&](int u, Cost du, auto f) { for (auto [v, c] : g[u]) f(v, du + c); }, src) {}
        std::vector<unsigned int> path_to(unsigned int t) const {
            assert(is_reachale(t));
            std::vector<unsigned int> path = {t};
            while (t != _src) path.push_back(t = _par[t]);
            std::reverse(path.begin(), path.end());
            return path;
        }
        Cost operator[](unsigned int t) const { return _dist[t]; }
        bool is_reachale   (unsigned int t) const { return _dist[t] != UNREACHABLE; }
        bool is_unreachable(unsigned int t) const { return _dist[t] == UNREACHABLE; }
    private:
        const Cost UNREACHABLE = std::numeric_limits<Cost>::max();
        const unsigned int _src;
        std::vector<Cost> _dist;
        std::vector<unsigned int> _par;
};
} // namespace suisen

#include <cassert>
#include <complex>
#include <iostream>
#include <optional>
#include <tuple>
#include <variant>

namespace suisen {
namespace geometry {

    using coordinate_t = long double;
    using Point = std::complex<coordinate_t>;

    // operator

    Point operator+(const Point &p, coordinate_t real) { return Point(p) + Point(real, 0); }
    Point operator-(const Point &p, coordinate_t real) { return Point(p) - Point(real, 0); }
    Point operator*(const Point &p, coordinate_t real) { return Point(p) * Point(real, 0); }
    Point operator/(const Point &p, coordinate_t real) { return Point(p) / Point(real, 0); }
    Point operator+(coordinate_t real, const Point &p) { return Point(real, 0) + Point(p); }
    Point operator-(coordinate_t real, const Point &p) { return Point(real, 0) - Point(p); }
    Point operator*(coordinate_t real, const Point &p) { return Point(real, 0) * Point(p); }
    Point operator/(coordinate_t real, const Point &p) { return Point(real, 0) / Point(p); }

    std::istream& operator>>(std::istream &in, Point &p) {
        coordinate_t x, y;
        in >> x >> y;
        p = Point(x, y);
        return in;
    }
    std::ostream& operator<<(std::ostream &out, const Point &p) {
        return out << p.real() << ' ' << p.imag();
    }

    // relations between three points X, Y, Z.

    struct ISP {
        static constexpr int L_CURVE = +1; // +---------------+ Z is in 'a' => ISP = +1
        static constexpr int R_CURVE = -1; // |aaaaaaaaaaaaaaa| Z is in 'b' => ISP = -1
        static constexpr int FRONT   = +2; // |ddd X eee Y ccc| Z is in 'c' => ISP = +2
        static constexpr int BACK    = -2; // |bbbbbbbbbbbbbbb| Z is in 'd' => ISP = -2
        static constexpr int MIDDLE  =  0; // +---------------+ Z is in 'e' => ISP =  0
    };

    struct Sign {
        static constexpr int NEGATIVE = -1;
        static constexpr int ZERO = 0;
        static constexpr int POSITIVE = +1;
    };

    enum class Containment {
        OUT, ON, IN
    };

    constexpr Point ZERO = Point(0, 0);
    constexpr Point ONE  = Point(1, 0);
    constexpr Point I    = Point(0, 1);
    constexpr coordinate_t EPS = 1e-9;
    constexpr coordinate_t PI  = 3.14159265358979323846264338327950288419716939937510L;
    constexpr coordinate_t E   = 2.71828182845904523536028747135266249775724709369995L;

    constexpr auto XY_COMPARATOR = [](const Point &p, const Point &q) {
        return p.real() == q.real() ? p.imag() < q.imag() : p.real() < q.real();
    };
    constexpr auto XY_COMPARATOR_GREATER = [](const Point &p, const Point &q) {
        return p.real() == q.real() ? p.imag() > q.imag() : p.real() > q.real();
    };
    constexpr auto YX_COMPARATOR = [](const Point &p, const Point &q) {
        return p.imag() == q.imag() ? p.real() < q.real() : p.imag() < q.imag();
    };
    constexpr auto YX_COMPARATOR_GREATER = [](const Point &p, const Point &q) {
        return p.imag() == q.imag() ? p.real() > q.real() : p.imag() > q.imag();
    };

    int sgn(coordinate_t x) {
        return x > EPS ? Sign::POSITIVE : x < -EPS ? Sign::NEGATIVE : Sign::ZERO;
    }
    int compare(coordinate_t x, coordinate_t y) {
        return sgn(x - y);
    }

    auto cartesian(const coordinate_t real, const coordinate_t imag) {
        return Point(real, imag);
    }
    auto polar(const coordinate_t rho, const coordinate_t theta) {
        return Point(rho * std::cos(theta), rho * std::sin(theta));
    }
    auto cis(const coordinate_t theta) {
        return Point(std::cos(theta), std::sin(theta));
    }
    auto conj(const Point &z) {
        return Point(z.real(), -z.imag());
    }
    auto arg(const Point &z) {
        return std::atan2(z.imag(), z.real());
    }
    auto square_abs(const Point &z) {
        return z.real() * z.real() + z.imag() * z.imag();
    }
    auto abs(const Point &z) {
        return std::sqrt(square_abs(z));
    }
    auto rot(const Point &z, const coordinate_t theta) {
        return cis(theta) * z;
    }
    auto dot(const Point &a, const Point &b) {
        return a.real() * b.real() + a.imag() * b.imag();
    }
    auto det(const Point &a, const Point &b) {
        return a.real() * b.imag() - a.imag() * b.real();
    }
    bool equals(const Point &a, const Point &b) {
        return sgn(a.real() - b.real()) == Sign::ZERO and sgn(a.imag() - b.imag()) == Sign::ZERO;
    }
    bool equals(coordinate_t a, coordinate_t b) {
        return compare(a, b) == 0;
    }
    
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
    int isp(const Point &a, const Point &b, const Point &c) {
        Point ab = b - a, ac = c - a;
        int s = sgn(det(ab, ac));
        if (s == Sign::POSITIVE) return ISP::L_CURVE;
        if (s == Sign::NEGATIVE) return ISP::R_CURVE;
        if (sgn(dot(ab, ac)) == Sign::NEGATIVE) return ISP::BACK;
        Point ba = a - b, bc = c - b;
        if (sgn(dot(ba, bc)) == Sign::NEGATIVE) return ISP::FRONT;
        return ISP::MIDDLE;
    }

    struct Line {
        Point a, b;
        Line() : Line(ZERO, ZERO) {}
        Line(const Point &from, const Point &to) : a(from), b(to) {}
    };
    struct Ray {
        Point a, b;
        Ray() : Ray(ZERO, ZERO) {}
        Ray(const Point &from, const Point &to) : a(from), b(to) {}
    };
    struct Segment {
        Point a, b;
        Segment() : Segment(ZERO, ZERO) {}
        Segment(const Point &from, const Point &to) : a(from), b(to) {}
    };
    struct Circle {
        Point center;
        coordinate_t radius;
        Circle() : Circle(ZERO, 0) {}
        Circle(const Point &c, const coordinate_t &r) : center(c), radius(r) {}
    };

    // Triangle
    
    coordinate_t signed_area(const Point &a, const Point &b, const Point &c) {
        return det(b - a, c - a) / 2;
    }
    coordinate_t area(const Point &a, const Point &b, const Point &c) {
        return std::abs(signed_area(a, b, c));
    }
    Point pG(const Point &a, const Point &b, const Point &c) {
        return (a + b + c) / 3;
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_B
    Circle pI(const Point &a, const Point &b, const Point &c) {
        auto la = std::abs(b - c), lb = std::abs(c - a), lc = std::abs(a - b);
        auto l = la + lb + lc;
        la /= l, lb /= l, lc /= l;
        Point center = la * a + lb * b + lc * c;
        auto radius = 2. * area(a, b, c) / l;
        return Circle(center, radius);
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_C
    Circle pO(const Point &a, const Point &b, const Point &c) {
        Point ab = b - a, bc = c - b, ca = a - c;
        auto la = square_abs(bc), lb = square_abs(ca), lc = square_abs(ab);
        auto s = la * (lb + lc - la), t = lb * (lc + la - lb), u = lc * (la + lb - lc);
        auto l = s + t + u;
        s /= l, t /= l, u /= l;
        Point center = a * s + b * t + c * u;
        return Circle(center, std::abs(center - a));
    }
    Point pH(const Point &a, const Point &b, const Point &c) {
        return a + b + c - 2 * pO(a, b, c).center;
    }
    auto pIabc(const Point &a, const Point &b, const Point &c) {
        return std::make_tuple(pI(-a, b, c), pI(a, -b, c), pI(a, b, -c));
    }

    // Line

    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
    template <typename line_t_1, typename line_t_2>
    auto is_parallel(const line_t_1 &l1, const line_t_2 &l2) -> decltype(l1.a, l1.b, l2.a, l2.b, bool()) {
        return sgn(det(l1.b - l1.a, l2.b - l2.a)) == Sign::ZERO;
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
    template <typename line_t_1, typename line_t_2>
    auto is_orthogonal(const line_t_1 &l1, const line_t_2 &l2) -> decltype(l1.a, l1.b, l2.a, l2.b, bool())  {
        return sgn(dot(l1.b - l1.a, l2.b - l2.a)) == Sign::ZERO;
    }
    template <typename line_t_1, typename line_t_2>
    auto on_the_same_line(const line_t_1 &l1, const line_t_2 &l2) -> decltype(l1.a, l1.b, l2.a, l2.b, bool())  {
        return is_parallel(l1, l2) and sgn(det(l1.b - l1.a, l2.a - l1.a)) == Sign::ZERO;
    }

    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
    template <typename line_t>
    Point projection(const Point &p, const line_t &line) {
        Point a = p - line.a;
        Point b = line.b - line.a;
        return line.a + dot(a, b) / square_abs(b) * b;
    }

    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
    template <typename line_t>
    Point reflection(const Point &p, const line_t &line) {
        Point h = projection(p, line);
        return p + (h - p) * 2;
    }

    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
    coordinate_t square_distance(const Point &p, const Segment &l) {
        Point h = projection(p, l);
        if (isp(l.a, l.b, h) == ISP::MIDDLE) {
            return square_abs(h - p);
        } else {
            return std::min(square_abs(p - l.a), square_abs(p - l.b));
        }
    }
    coordinate_t square_distance(const Segment &l, const Point &p) {
        return square_distance(p, l);
    }
    coordinate_t square_distance(const Point &p, const Ray &l) {
        Point h = projection(p, l);
        int dir = isp(l.a, l.b, h);
        return dir == ISP::MIDDLE or dir == ISP::FRONT ? square_abs(h - p) : std::min(square_abs(p - l.a), square_abs(p - l.b));
    }
    coordinate_t square_distance(const Ray &l, const Point &p) {
        return square_distance(p, l);
    }
    coordinate_t square_distance(const Point &p, const Line &l) {
        return square_abs(projection(p, l) - p);
    }
    coordinate_t square_distance(const Line &l, const Point &p) {
        return square_distance(p, l);
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
    coordinate_t distance(const Point &p, const Segment &l) {
        return std::sqrt(square_distance(p, l));
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
    coordinate_t distance(const Segment &l, const Point &p) {
        return distance(p, l);
    }
    coordinate_t distance(const Point &p, const Ray &l) {
        return std::sqrt(square_distance(p, l));
    }
    coordinate_t distance(const Ray &l, const Point &p) {
        return distance(p, l);
    }
    coordinate_t distance(const Point &p, const Line &l) {
        return std::sqrt(square_distance(p, l));
    }
    coordinate_t distance(const Line &l, const Point &p) {
        return distance(p, l);
    }

    Containment contains(const Segment &l, const Point &p) {
        return sgn(distance(l, p)) == 0 ? Containment::ON : Containment::OUT;
    }
    Containment contains(const Ray &l, const Point &p) {
        return sgn(distance(l, p)) == 0 ? Containment::ON : Containment::OUT;
    }
    Containment contains(const Line &l, const Point &p) {
        return sgn(distance(l, p)) == 0 ? Containment::ON : Containment::OUT;
    }

    bool equals(const Line &l, const Line &m) {
        return on_the_same_line(l, m);
    }
    bool equals(const Ray &l, const Ray &m) {
        return on_the_same_line(l, m) and equals(l.a, m.a);
    }
    bool equals(const Segment &l, const Segment &m) {
        return (equals(l.a, m.a) and equals(l.b, m.b)) or (equals(l.a, m.b) and equals(l.b, m.a));
    }

    // "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B"
    bool has_common_point(const Segment &l1, const Segment &l2) {
        int isp_1a = isp(l1.a, l1.b, l2.a), isp_1b = isp(l1.a, l1.b, l2.b);
        if (isp_1a * isp_1b > 0) return false;
        int isp_2a = isp(l2.a, l2.b, l1.a), isp_2b = isp(l2.a, l2.b, l1.b);
        if (isp_2a * isp_2b > 0) return false;
        return true;
    }

    namespace internal {
        template <typename line_t_1, typename line_t_2>
        Point cross_point(const line_t_1 &l1, const line_t_2 &l2) {
            assert(not is_parallel(l1, l2));
            Point u = l1.b - l1.a, v = l2.a - l2.b, c = l2.a - l1.a;
            return l2.a - det(u, c) / det(u, v) * v;
        }
    }

    // "https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C"
    std::variant<std::nullptr_t, Point, Segment> common_point(const Segment &l1, const Segment &l2) {
        if (not has_common_point(l1, l2)) return nullptr;
        if (not is_parallel(l1, l2)) return internal::cross_point(l1, l2);
        std::vector<Point> ps { l1.a, l1.b, l2.a, l2.b };
        for (int i = 0; i <= 2; ++i) for (int j = 2; j >= i; --j) {
            if (XY_COMPARATOR(ps[j + 1], ps[j])) std::swap(ps[j], ps[j + 1]);
        }
        if (equals(ps[1], ps[2])) return ps[1];
        return Segment(ps[1], ps[2]);
    }

    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
    coordinate_t square_distance(const Segment &l1, const Segment &l2) {
        if (has_common_point(l1, l2)) return 0;
        return std::min({ square_distance(l1, l2.a), square_distance(l1, l2.b), square_distance(l1.a, l2), square_distance(l1.b, l2) });
    }
    // https://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
    coordinate_t distance(const Segment &l1, const Segment &l2) {
        return std::sqrt(square_distance(l1, l2));
    }
}
} // namespace suisen

using namespace suisen::geometry;

void solve(int n, int w, std::vector<std::vector<Point>> pillars) {
    std::vector<int> offset(n + 1, 0);
    for (int i = 0; i < n; ++i) {
        offset[i + 1] = offset[i] + pillars[i].size();
    }
    const int s = offset[n], t = s + 1;

    using cost_t = coordinate_t;
    std::vector<std::vector<std::pair<int, cost_t>>> g(offset[n] + 2);

    g[s].emplace_back(t, w);

    for (int i = 0; i < n; ++i) {
        const auto &pillar = pillars[i];
        const int m = pillar.size();
        for (int j = 0; j < m; ++j) {
            auto x = pillar[j].real();
            g[s].emplace_back(offset[i] + j, x);
            g[offset[i] + j].emplace_back(t, w - x);

            int nj = (j + 1) % m;
            g[offset[i] + j].emplace_back(offset[i] + nj, 0);
            g[offset[i] + nj].emplace_back(offset[i] + j, 0);

            for (int i2 = 0; i2 < i; ++i2) {
                const auto &pillar2 = pillars[i2];
                const int m2 = pillar2.size();
                for (int j2 = 0; j2 < m2; ++j2) {
                    int nj2 = (j2 + 1) % m2;
                    cost_t d = distance(Segment{pillar[j], pillar[nj]}, Segment{pillar2[j2], pillar2[nj2]});
                    g[offset[i] + j].emplace_back(offset[i2] + j2, d);
                    g[offset[i2] + j2].emplace_back(offset[i] + j, d);
                }
            }
        }
    }

    std::cout << std::fixed << std::setprecision(20) << suisen::dijkstra(g, s)[t] << std::endl;
}

int main() {
    while (true) {
        int w, n;
        std::cin >> w >> n;
        if (n == 0 and w == 0) return 0;
        std::vector<std::vector<Point>> pillars(n);
        for (auto &pillar : pillars) {
            int m;
            std::cin >> m;
            for (int i = 0; i < m; ++i) {
                coordinate_t x, y;
                std::cin >> x >> y;
                pillar.push_back({ x, y });
            }
        }
        solve(n, w, pillars);
    }
}
accuracy: 1
time_ms: 420
memory_kb: 35424
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, s, t) for (int i = (int)(s); i < (int)(t); ++i)

using T = double;
using Vec = std::complex<T>;

constexpr T eps = 1e-12;
inline bool eq(T a, T b) { return std::abs(a - b) < eps; }
inline bool lt(T a, T b) { return a < b - eps; }
inline bool leq(T a, T b) { return a < b + eps; }

std::istream& operator>>(std::istream& is, Vec& p) {
    T x, y;
    is >> x >> y;
    p = {x, y};
    return is;
}

T dot(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).real();
}

T cross(const Vec& a, const Vec& b) {
    return (std::conj(a) * b).imag();
}

int ccw(const Vec& a, const Vec& b, const Vec& c) {
    if (eq(cross(b - a, c - a), 0)) return 0;  // collinear
    if (lt(cross(b - a, c - a), 0)) return -1;  // clockwise
    return 1;  // counter clockwise
}

bool on_segment(const Vec& a, const Vec& b, const Vec& c) {
    Vec u = a - c, v = b - c;
    return eq(cross(u, v), 0) && leq(dot(u, v), 0);
}

bool intersect_segments(const Vec& a, const Vec& b, const Vec& c, const Vec& d) {
    if (ccw(a, c, d) != ccw(b, c, d) && ccw(a, b, c) != ccw(a, b, d)) return true;
    if (on_segment(a, b, c) || on_segment(c, d, a) || on_segment(c, d, a) || on_segment(c, d, b)) return true;
    return false;
}

T dist_segment_point(const Vec& a, const Vec& b, const Vec& c) {
    if (lt(dot(b - a, c - a), 0)) return std::abs(c - a);
    if (lt(dot(a - b, c - b), 0)) return std::abs(c - b);
    return std::abs(cross(b - a, c - a)) / std::abs(b - a);
}

T dist_segments(const Vec& a, const Vec& b, const Vec& c, const Vec& d) {
    if (intersect_segments(a, b, c, d)) return T(0);
    return std::min(
        std::min(dist_segment_point(a, b, c), dist_segment_point(a, b, d)),
        std::min(dist_segment_point(c, d, a), dist_segment_point(c, d, b))
    );
}

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& v) {
    for (int i = 0; i < (int) v.size(); ++i) {
        os << v[i];
        if (i < (int) v.size() - 1) os << " ";
    }
    return os;
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout << fixed << setprecision(15);

    while (true) {
        int W, N;
        cin >> W >> N;
        if (W == 0) break;
        vector<vector<Vec>> polys(N);
        rep(i, 0, N) {
            int M;
            cin >> M;
            polys[i].resize(M);
            rep(j, 0, M) cin >> polys[i][j];
        }
        vector<vector<double>> dist(N+2, vector<double>(N+2, 1e9));
        dist[N][N+1] = dist[N+1][N] = W;
        rep(i, 0, N+2) dist[i][i] = 0;
        rep(i, 0, N) {
            double left = 1e9, right = 1e9;
            rep(j, 0, polys[i].size()) {
                left = min(left, polys[i][j].real());
                right = min(right, W - polys[i][j].real());
            }
            dist[i][N] = dist[N][i] = left;
            dist[i][N+1] = dist[N+1][i] = right;
            rep(j, 0, N) {
                if (i == j) continue;
                double d = 1e9;
                int a = polys[i].size(), b = polys[j].size();
                rep(k, 0, a) {
                    rep(l, 0, b) {
                        d = min(d, dist_segments(polys[i][k], polys[i][(k+1)%a], polys[j][l], polys[j][(l+1)%b]));
                    }
                }
                dist[i][j] = dist[j][i] = d;
            }
        }
        rep(k, 0, N+2) rep(i, 0, N+2) rep(j, 0, N+2) dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
        cout << dist[N][N+1] << "\n";
    }
}
accuracy: 1
time_ms: 280
memory_kb: 3568
final_rank: 11

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;
using Real = long double;
using Point = complex< Real >;
using Polygon = vector< Point >;
const Real EPS = 1e-6, PI = acos(-1);
constexpr int COUNTER_CLOCKWISE = +1;
constexpr int CLOCKWISE = -1;
constexpr int ONLINE_BACK = +2;  // c-a-b
constexpr int ONLINE_FRONT = -2; // a-b-c
constexpr int ON_SEGMENT = 0;    // a-c-b

Point operator*(const Point &p, const Real &d) {
    return Point(real(p) * d, imag(p) * d);
}

Point operator/(const Point &p, const Real &d) {
    return Point(real(p) / d, imag(p) / d);
}

istream &operator>>(istream &is, Point &p) {
    Real a, b; is >> a >> b;
    p = Point(a, b);
    return is;
}

ostream &operator<<(ostream &os, const Point &p) {
    return os << fixed << setprecision(10) << real(p) << " " << imag(p);
}

namespace std {
    bool operator<(const Point &a, const Point &b) {
        return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
    }
}

// 符号
inline int sign(const Real &r) {
    return r <= -EPS ? -1 : r >= EPS ? 1 : 0;
}

// a = b ? 
inline bool equals(const Real &a, const Real &b) {
    return sign(a - b) == 0;
}


// 単位ベクトル
Point unitVec(const Point &a){ return a / abs(a); }

// 法線ベクトル 半時計周り
Point normVec(const Point &a){ return a * Point(0, 1); }
//Point normVec(const Point &a){ return a * Point(0,-1); }

// 内積
Real dot(const Point &a, const Point &b) {
    return (a.real() * b.real() + a.imag() * b.imag());
}

// 外積
Real cross(const Point &a, const Point &b) {
    return (a.real() * b.imag() - a.imag() * b.real());
}

Point rotate(const Point &p, const Real &theta) {
    return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                 sin(theta) * p.real() + cos(theta) * p.imag());
}

Real Radian_To_Degree(const Real &radian){ return radian * 180.0 / PI; }
Real Degree_To_Radian(const Real &degree){ return degree * PI / 180.0; }

struct Line {
    Point a, b;
    Line() = default;
    Line(Point a, Point b) : a(a), b(b) {}

    // Ax + By = C
    Line(Real A, Real B, Real C) {
        if(equals(A, 0)) {
            a = Point(0, C / B), b = Point(1, C / B);
        }else if(equals(B,0)) {
            b = Point(C / A, 0), b = Point(C / A, 1);
        }else{
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }

    friend ostream &operator<<(ostream &os, Line &p) {
        return os << p.a << " " << p.b;
    }

    friend istream &operator>>(istream &is, Line &a) {
        return is >> a.a >> a.b;
    }
};

struct Segment : Line {
    Segment() = default;
    Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
    Point p;
    Real r;
    Circle() = default;
    Circle(Point p, Real r) : p(p), r(r) {}

    friend ostream &operator<<(ostream &os, Circle &c) {
        return os << c.p << " " << c.r;
    }

    friend istream &operator>>(istream &is, Circle &c) {
        return is >> c.p >> c.r;
    }
};

// 直線lに点pから引いた垂線の足を求める
Point projection(const Line &l, const Point &p) {
    Real t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
    Real t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

// 直線lに関して点pと対称な点を求める
Point reflection(const Line &l, const Point &p) {
    return p + (projection(l, p) - p) * 2.0;
}

// 点の回転方向
// 点aを基準に点b,cの位置関係
int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if(sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE; // 反時計回り
    if(sign(cross(b, c)) == -1) return CLOCKWISE;         // 時計回り
    if(sign(dot(b, c)) == -1) return ONLINE_BACK;         // c - a - b
    if(norm(b) < norm(c)) return ONLINE_FRONT;            // a - b - c
    return ON_SEGMENT;                                    // a - c - b
}

// 2直線の直交判定
bool is_orthogonal(const Line &a, const Line &b) {
    return equals(dot(a.b - a.a, b.b - b.a), 0);
}

// 2直線の平行判定
bool is_parallel(const Line &a, const Line &b) {
    return equals(cross(a.b - a.a, b.b - b.a), 0);
}

// 線分の交差判定
bool is_intersect_ss(const Segment &s, const Segment &t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
           ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 直線の交差判定
bool is_intersect_ll(const Line &l, const Line &m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if(equals(abs(A), 0) && equals(abs(B), 0)) return true;
    return !is_parallel(l, m);
}

// 線分に点が乗っているか
bool is_intersect_sp(const Segment &s, const Point &p) {
    return ccw(s.a, s.b, p) == ON_SEGMENT;
}

// 点と点の距離
Real distance_pp(const Point &p1, const Point &p2) {
    return sqrt(pow(real(p1)-real(p2), 2) + pow(imag(p1)-imag(p2), 2));
}

// 点と直線の距離
Real distance_lp(const Line &l, const Point &p) {
    return abs(p - projection(l, p));
}

// 直線と直線の距離
Real distance_ll(const Line &l, const Line &m) {
    return is_intersect_ll(l, m) ? 0 : distance_lp(l, m.a);
}

// 点と線分の距離
Real distance_sp(const Segment &s, const Point &p) {
    Point r = projection(s, p);
    if(is_intersect_sp(s, r)) return abs(r - p);
    return min(abs(s.a - p), abs(s.b - p));
}

// 線分と線分の距離
Real distance_ss(const Segment &a, const Segment &b) {
    if(is_intersect_ss(a, b)) return 0;
    return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b)});
}

// 交点
Point cross_point_ll(const Line &l, const Line &m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if(equals(abs(A), 0) && equals(abs(B), 0)) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

// 円と円の位置関係
int intersect(Circle c1, Circle c2) {
    if(c1.r < c2.r) swap(c1, c2);
    Real d = abs(c1.p - c2.p);
    if(c1.r + c2.r < d) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(c1.r - c2.r < d) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}

Real area(const Polygon &p){
    Real A = 0;
    for(int i = 0; i < p.size(); i++){
        A += cross(p[i], p[(i + 1) % p.size()]);
    }
    return A * 0.5;
}

bool is_convex(const Polygon &p){
    for(int i = 0; i < p.size(); i++){
        if(ccw(p[(i + p.size() - 1) % p.size()], p[i], p[(i + 1) % p.size()]) == -1) return false;
    }
    return true;
}

enum { OUT, ON, IN };
int contains(const Polygon &Q, const Point &p){
    bool in = false;
    for(int i = 0; i < Q.size(); i++){
        Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
        if(a.imag() > b.imag()) swap(a, b);
        if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
        if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}

Polygon convex_hull(Polygon &p, bool strict = true){
    int n = (int)p.size(), k = 0;
    if(n <= 2) return p;
    sort(p.begin(), p.end());
    Polygon ch(2 * n);
    for(int i = 0; i < n; ch[k++] = p[i++]){
        while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]){
        while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
    }
    ch.resize(k - 1);
    return ch;
}

Real convex_diameter(const Polygon &p){
    int n = (int)p.size();
    int is = 0, js = 0;
    for(int i = 1; i < n; i++){
        if(p[i].imag() > p[is].imag()) is = i;
        if(p[i].imag() < p[js].imag()) js = i;
    }
    Real maxdis = norm(p[is] - p[js]);
    int maxi, maxj, i, j;
    i = maxi = is;
    j = maxj = js;
    do {
        if(cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j]) >= 0){
            j = (j + 1) % n;
        }else{
            i = (i + 1) % n;
        }

        if(norm(p[i] - p[j]) > maxdis){
            maxdis = norm(p[i] - p[j]);
            maxi = i;
            maxj = j;
        }

    }while(i != is || j != js);
    return sqrt(maxdis);
}

Polygon convex_cut(const Polygon &U, Line l){
    Polygon ret;
    for(int i = 0; i < U.size(); i++){
        Point now = U[i], nxt = U[(i + 1) % U.size()];
        if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0){
            ret.push_back(cross_point_ll(Line(now, nxt), l));
        }
    }
    return ret;
}

pair< Point, Point > cross_point_cc(const Circle &c1, const Circle &c2) {
    Real d = abs(c1.p - c2.p);
    Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
    Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
    Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
    return {p1, p2};
}

const int BOTTOM = 0;
const int LEFT   = 1;
const int RIGHT  = 2;
const int TOP    = 3;

class endPoint {
    public:
        Point p;
        int seg; // id of Point
        int st; // kind of Point
        endPoint(){}
        endPoint(Point inp, int inseg, int inst):p(inp),seg(inseg),st(inst){}
        bool operator<(const endPoint &ep)const {
            if(p.imag() == ep.p.imag()) return st < ep.st;
            else return p.imag() < ep.p.imag();
        }
};

endPoint EP[220000];
int Manhattan_Intersections(vector< Segment > s){
    int n = s.size();
    double hoge;

    for(int i = 0, k = 0; i < n; i++){
        if(s[i].a.imag() == s[i].b.imag()){
            if(s[i].a.real() > s[i].b.real()){
                hoge = s[i].a.real();
                s[i].a.real(s[i].b.real());
                s[i].b.real(hoge);
            }
        }else if(s[i].a.imag() > s[i].b.imag()){
            hoge = s[i].a.imag();
            s[i].a.imag(s[i].b.imag());
            s[i].b.imag(hoge);
        }

        if(s[i].a.imag() == s[i].b.imag()){
            EP[k++] = endPoint(s[i].a, i, LEFT);
            EP[k++] = endPoint(s[i].b, i, RIGHT);
        }else{
            EP[k++] = endPoint(s[i].a, i, BOTTOM);
            EP[k++] = endPoint(s[i].b, i, TOP);
        }
    }

    sort(EP, EP + 2 * n);
    set<int> BT;
    BT.insert(1000000001);
    int cnt = 0;
    for(int i = 0; i < 2 * n; i++){
        if(EP[i].st == TOP) BT.erase(EP[i].p.real());
        else if(EP[i].st == BOTTOM) BT.insert(EP[i].p.real());
        else if(EP[i].st == LEFT){
            set<int>::iterator b = lower_bound(BT.begin(), BT.end(), s[EP[i].seg].a.real());
            set<int>::iterator e = upper_bound(BT.begin(), BT.end(), s[EP[i].seg].b.real());
            cnt += distance(b, e);
        }
    }

    return cnt;
}

// 内接円
Circle Inscribed_Circle(const Point& a, const Point& b, const Point& c){
    double A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point x = Point((a * A + b * B + c * C) / (A + B + C));
    double r = distance_sp(Segment(a,b),x);
    return Circle(x, r);
}

// 外接円
Circle Circumscribed_Circle(const Point& a, const Point& b, const Point& c){
    Point m1((a+b)/2.0), m2((b+c)/2.0);
    Point v((b-a).imag(), (a-b).real()), w((b-c).imag(), (c-b).real());
    Line s(m1, Point(m1+v)), t(m2, Point(m2+w));
    const Point x = cross_point_ll(s, t);
    return Circle(x, abs(a-x));
}

pair< Point, Point > cross_point_cl(const Circle &c, const Line &l) {
    Point pr = projection(l, c.p);
    if(equals(abs(pr - c.p), c.r)) return {pr, pr};
    Point e = (l.b - l.a) / abs(l.b - l.a);
    auto k = sqrt(norm(c.r) - norm(pr - c.p));
    return {pr - e * k, pr + e * k};
}

// 点pを通る円の接線
pair<Point,Point> tangent_cp(const Circle &c, const Point &p) {
    return cross_point_cc(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
}

// 二つの円の共通接線
vector< Line > tangent_cc(Circle c1, Circle c2){
    vector< Line > ret;
    if(c1.r < c2.r) swap(c1,c2);
    double g = norm(c1.p-c2.p);
    if(equals(g,0.0)) return ret;
    Point u = (c2.p-c1.p)/sqrt(g);
    Point v = rotate(u, PI * 0.5);
    for(int s:{-1,1}){
        double h = (c1.r+ s*c2.r)/sqrt(g);
        if(equals(1- h*h, 0)){
            ret.emplace_back(c1.p+u*c1.r, c1.p+(u+v)*c1.r);
        }else if(1-h*h > 0){
            Point uu = u*h, vv = v*sqrt(1-h*h);
            ret.emplace_back(c1.p+(uu+vv)*c1.r, c2.p-(uu+vv)*c2.r*s);
            ret.emplace_back(c1.p+(uu-vv)*c1.r, c2.p-(uu-vv)*c2.r*s);
        }
    }
    return ret;
}

Real area_poly_c(const Polygon &p, const Circle &c) {
    if(p.size() < 3) return 0.0;
    function< Real(Circle, Point, Point) > cross_area = [&](const Circle &c, const Point &a, const Point &b) {
        Point va = c.p - a, vb = c.p - b;
        Real f = cross(va, vb), ret = 0.0;
        if(equals(f, 0.0)) return ret;
        if(max(abs(va), abs(vb)) < c.r + EPS) return f;
        if(distance_sp(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
        auto u = cross_point_cl(c, Segment(a, b));
        vector< Point > tot{a, u.first, u.second, b};
        for(int i = 0; i + 1 < tot.size(); i++) {
            ret += cross_area(c, tot[i], tot[i + 1]);
        }
        return ret;
    };
    Real A = 0;
    for(int i = 0; i < p.size(); i++) {
        A += cross_area(c, p[i], p[(i + 1) % p.size()]);
    }
    return A;
}

Real area_cc(const Circle &c1, const Circle &c2) {
    Real d = abs(c1.p - c2.p);
    if(c1.r + c2.r <= d + EPS) return 0.0;
    if(d <= fabs(c1.r - c2.r) + EPS) {
        Real r = min(c1.r, c2.r);
        return r * r * PI;
    }
    Real rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    Real theta = acos(rc / c1.r);
    Real phi = acos((d - rc) / c2.r);
    return (c1.r * c1.r*theta + c2.r*c2.r*phi - d*c1.r*sin(theta));
}

Real distance_pp(vector< Point > p, vector< Point > q) {
    Real ans = 1e9;
    rep(i,p.size())rep(j,q.size()) {
        ans = min(ans, distance_sp(Segment(q[j], q[(j + 1) % q.size()]), p[i]));
        ans = min(ans, distance_sp(Segment(p[i], p[(i + 1) % p.size()]), q[j]));
    }
    return ans;
}

Real distance_line_poly(Line l, vector< Point > p) {
    Real ans = 1e9;
    rep(i,p.size()) ans = min(ans, distance_lp(l, p[i]));
    return ans;
}

// g <- pair < v , cost > 
template < class T >
vector<T> Dijkstra(vector<vector<pair<int,T>>> &g, int s) {
    vector<T> dist(g.size(), -1);
    priority_queue<pair<T,int>> Q;
    Q.emplace(0, s);
    while(!Q.empty()){
        T cost = Q.top().first;
        int v = Q.top().second;
        Q.pop();
        cost = - cost;
        if(dist[v] == -1){
            dist[v] = cost;
            for(auto e : g[v]){
                if(dist[e.first] == -1){
                    Q.emplace(-(cost + e.second), e.first);
                }
            }
        }
    }
    return dist;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);

    while(true)
    {

    int W,N; cin >> W >> N; if(W == 0 && N == 0) break;
    vector< vector< Point > > P(N);
    rep(i,N) {
        int M; cin >> M;
        rep(j,M) {
            Point a; cin >> a;
            P[i].push_back(a);
        }
    }

    vector<vector<pair<int,Real>>> G(N + 2);
    int S = N, T = N + 1;
    rep(i,N)rep(j,N) if(i < j) {
        Real dist = distance_pp(P[i], P[j]);
        G[i].push_back({j, dist});
        G[j].push_back({i, dist});
    }

    rep(i,N) {
        Real mi = 1e9;
        rep(j,P[i].size()) mi = min(mi, P[i][j].real());
        G[S].push_back({i, mi});
        G[i].push_back({S, mi});
    }
    rep(i,N) {
        Real mi = 1e9;
        rep(j,P[i].size()) mi = min(mi, W - P[i][j].real());
        G[i].push_back({T, mi});
        G[T].push_back({i, mi});
    }
     G[S].push_back({T, W});

    auto res = Dijkstra(G, S);
    cout.precision(17);
    cout << res[T] << endl; 

    }
}
accuracy: 1
time_ms: 420
memory_kb: 17020
final_rank: 16

code_snippet: #include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < (n); i++)
using namespace std;
typedef long long ll;
using Real = long double;
using Point = complex< Real >;
using Polygon = vector< Point >;
const Real EPS = 1e-6, PI = acos(-1);
constexpr int COUNTER_CLOCKWISE = +1;
constexpr int CLOCKWISE = -1;
constexpr int ONLINE_BACK = +2;  // c-a-b
constexpr int ONLINE_FRONT = -2; // a-b-c
constexpr int ON_SEGMENT = 0;    // a-c-b

Point operator*(const Point &p, const Real &d) {
    return Point(real(p) * d, imag(p) * d);
}

Point operator/(const Point &p, const Real &d) {
    return Point(real(p) / d, imag(p) / d);
}

istream &operator>>(istream &is, Point &p) {
    Real a, b; is >> a >> b;
    p = Point(a, b);
    return is;
}

ostream &operator<<(ostream &os, const Point &p) {
    return os << fixed << setprecision(10) << real(p) << " " << imag(p);
}

namespace std {
    bool operator<(const Point &a, const Point &b) {
        return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag();
    }
}

// 符号
inline int sign(const Real &r) {
    return r <= -EPS ? -1 : r >= EPS ? 1 : 0;
}

// a = b ? 
inline bool equals(const Real &a, const Real &b) {
    return sign(a - b) == 0;
}


// 単位ベクトル
Point unitVec(const Point &a){ return a / abs(a); }

// 法線ベクトル 半時計周り
Point normVec(const Point &a){ return a * Point(0, 1); }
//Point normVec(const Point &a){ return a * Point(0,-1); }

// 内積
Real dot(const Point &a, const Point &b) {
    return (a.real() * b.real() + a.imag() * b.imag());
}

// 外積
Real cross(const Point &a, const Point &b) {
    return (a.real() * b.imag() - a.imag() * b.real());
}

Point rotate(const Point &p, const Real &theta) {
    return Point(cos(theta) * p.real() - sin(theta) * p.imag(),
                 sin(theta) * p.real() + cos(theta) * p.imag());
}

Real Radian_To_Degree(const Real &radian){ return radian * 180.0 / PI; }
Real Degree_To_Radian(const Real &degree){ return degree * PI / 180.0; }

struct Line {
    Point a, b;
    Line() = default;
    Line(Point a, Point b) : a(a), b(b) {}

    // Ax + By = C
    Line(Real A, Real B, Real C) {
        if(equals(A, 0)) {
            a = Point(0, C / B), b = Point(1, C / B);
        }else if(equals(B,0)) {
            b = Point(C / A, 0), b = Point(C / A, 1);
        }else{
            a = Point(0, C / B), b = Point(C / A, 0);
        }
    }

    friend ostream &operator<<(ostream &os, Line &p) {
        return os << p.a << " " << p.b;
    }

    friend istream &operator>>(istream &is, Line &a) {
        return is >> a.a >> a.b;
    }
};

struct Segment : Line {
    Segment() = default;
    Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
    Point p;
    Real r;
    Circle() = default;
    Circle(Point p, Real r) : p(p), r(r) {}

    friend ostream &operator<<(ostream &os, Circle &c) {
        return os << c.p << " " << c.r;
    }

    friend istream &operator>>(istream &is, Circle &c) {
        return is >> c.p >> c.r;
    }
};

// 直線lに点pから引いた垂線の足を求める
Point projection(const Line &l, const Point &p) {
    Real t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
    Real t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
    return l.a + (l.a - l.b) * t;
}

// 直線lに関して点pと対称な点を求める
Point reflection(const Line &l, const Point &p) {
    return p + (projection(l, p) - p) * 2.0;
}

// 点の回転方向
// 点aを基準に点b,cの位置関係
int ccw(const Point &a, Point b, Point c) {
    b = b - a, c = c - a;
    if(sign(cross(b, c)) == +1) return COUNTER_CLOCKWISE; // 反時計回り
    if(sign(cross(b, c)) == -1) return CLOCKWISE;         // 時計回り
    if(sign(dot(b, c)) == -1) return ONLINE_BACK;         // c - a - b
    if(norm(b) < norm(c)) return ONLINE_FRONT;            // a - b - c
    return ON_SEGMENT;                                    // a - c - b
}

// 2直線の直交判定
bool is_orthogonal(const Line &a, const Line &b) {
    return equals(dot(a.b - a.a, b.b - b.a), 0);
}

// 2直線の平行判定
bool is_parallel(const Line &a, const Line &b) {
    return equals(cross(a.b - a.a, b.b - b.a), 0);
}

// 線分の交差判定
bool is_intersect_ss(const Segment &s, const Segment &t) {
    return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 &&
           ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
}

// 直線の交差判定
bool is_intersect_ll(const Line &l, const Line &m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if(equals(abs(A), 0) && equals(abs(B), 0)) return true;
    return !is_parallel(l, m);
}

// 線分に点が乗っているか
bool is_intersect_sp(const Segment &s, const Point &p) {
    return ccw(s.a, s.b, p) == ON_SEGMENT;
}

// 点と点の距離
Real distance_pp(const Point &p1, const Point &p2) {
    return sqrt(pow(real(p1)-real(p2), 2) + pow(imag(p1)-imag(p2), 2));
}

// 点と直線の距離
Real distance_lp(const Line &l, const Point &p) {
    return abs(p - projection(l, p));
}

// 直線と直線の距離
Real distance_ll(const Line &l, const Line &m) {
    return is_intersect_ll(l, m) ? 0 : distance_lp(l, m.a);
}

// 点と線分の距離
Real distance_sp(const Segment &s, const Point &p) {
    Point r = projection(s, p);
    if(is_intersect_sp(s, r)) return abs(r - p);
    return min(abs(s.a - p), abs(s.b - p));
}

// 線分と線分の距離
Real distance_ss(const Segment &a, const Segment &b) {
    if(is_intersect_ss(a, b)) return 0;
    return min({distance_sp(a, b.a), distance_sp(a, b.b), distance_sp(b, a.a), distance_sp(b, a.b)});
}

// 交点
Point cross_point_ll(const Line &l, const Line &m) {
    Real A = cross(l.b - l.a, m.b - m.a);
    Real B = cross(l.b - l.a, l.b - m.a);
    if(equals(abs(A), 0) && equals(abs(B), 0)) return m.a;
    return m.a + (m.b - m.a) * B / A;
}

// 円と円の位置関係
int intersect(Circle c1, Circle c2) {
    if(c1.r < c2.r) swap(c1, c2);
    Real d = abs(c1.p - c2.p);
    if(c1.r + c2.r < d) return 4;
    if(equals(c1.r + c2.r, d)) return 3;
    if(c1.r - c2.r < d) return 2;
    if(equals(c1.r - c2.r, d)) return 1;
    return 0;
}

Real area(const Polygon &p){
    Real A = 0;
    for(int i = 0; i < p.size(); i++){
        A += cross(p[i], p[(i + 1) % p.size()]);
    }
    return A * 0.5;
}

bool is_convex(const Polygon &p){
    for(int i = 0; i < p.size(); i++){
        if(ccw(p[(i + p.size() - 1) % p.size()], p[i], p[(i + 1) % p.size()]) == -1) return false;
    }
    return true;
}

enum { OUT, ON, IN };
int contains(const Polygon &Q, const Point &p){
    bool in = false;
    for(int i = 0; i < Q.size(); i++){
        Point a = Q[i] - p, b = Q[(i + 1) % Q.size()] - p;
        if(a.imag() > b.imag()) swap(a, b);
        if(a.imag() <= 0 && 0 < b.imag() && cross(a, b) < 0) in = !in;
        if(cross(a, b) == 0 && dot(a, b) <= 0) return ON;
    }
    return in ? IN : OUT;
}

Polygon convex_hull(Polygon &p, bool strict = true){
    int n = (int)p.size(), k = 0;
    if(n <= 2) return p;
    sort(p.begin(), p.end());
    Polygon ch(2 * n);
    for(int i = 0; i < n; ch[k++] = p[i++]){
        while(k >= 2 && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
    }
    for(int i = n - 2, t = k + 1; i >= 0; ch[k++] = p[i--]){
        while(k >= t && cross(ch[k - 1] - ch[k - 2], p[i] - ch[k - 1]) < 0) --k;
    }
    ch.resize(k - 1);
    return ch;
}

Real convex_diameter(const Polygon &p){
    int n = (int)p.size();
    int is = 0, js = 0;
    for(int i = 1; i < n; i++){
        if(p[i].imag() > p[is].imag()) is = i;
        if(p[i].imag() < p[js].imag()) js = i;
    }
    Real maxdis = norm(p[is] - p[js]);
    int maxi, maxj, i, j;
    i = maxi = is;
    j = maxj = js;
    do {
        if(cross(p[(i + 1) % n] - p[i], p[(j + 1) % n] - p[j]) >= 0){
            j = (j + 1) % n;
        }else{
            i = (i + 1) % n;
        }

        if(norm(p[i] - p[j]) > maxdis){
            maxdis = norm(p[i] - p[j]);
            maxi = i;
            maxj = j;
        }

    }while(i != is || j != js);
    return sqrt(maxdis);
}

Polygon convex_cut(const Polygon &U, Line l){
    Polygon ret;
    for(int i = 0; i < U.size(); i++){
        Point now = U[i], nxt = U[(i + 1) % U.size()];
        if(ccw(l.a, l.b, now) != -1) ret.push_back(now);
        if(ccw(l.a, l.b, now) * ccw(l.a, l.b, nxt) < 0){
            ret.push_back(cross_point_ll(Line(now, nxt), l));
        }
    }
    return ret;
}

pair< Point, Point > cross_point_cc(const Circle &c1, const Circle &c2) {
    Real d = abs(c1.p - c2.p);
    Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));
    Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
    Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
    Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
    return {p1, p2};
}

const int BOTTOM = 0;
const int LEFT   = 1;
const int RIGHT  = 2;
const int TOP    = 3;

class endPoint {
    public:
        Point p;
        int seg; // id of Point
        int st; // kind of Point
        endPoint(){}
        endPoint(Point inp, int inseg, int inst):p(inp),seg(inseg),st(inst){}
        bool operator<(const endPoint &ep)const {
            if(p.imag() == ep.p.imag()) return st < ep.st;
            else return p.imag() < ep.p.imag();
        }
};

endPoint EP[220000];
int Manhattan_Intersections(vector< Segment > s){
    int n = s.size();
    double hoge;

    for(int i = 0, k = 0; i < n; i++){
        if(s[i].a.imag() == s[i].b.imag()){
            if(s[i].a.real() > s[i].b.real()){
                hoge = s[i].a.real();
                s[i].a.real(s[i].b.real());
                s[i].b.real(hoge);
            }
        }else if(s[i].a.imag() > s[i].b.imag()){
            hoge = s[i].a.imag();
            s[i].a.imag(s[i].b.imag());
            s[i].b.imag(hoge);
        }

        if(s[i].a.imag() == s[i].b.imag()){
            EP[k++] = endPoint(s[i].a, i, LEFT);
            EP[k++] = endPoint(s[i].b, i, RIGHT);
        }else{
            EP[k++] = endPoint(s[i].a, i, BOTTOM);
            EP[k++] = endPoint(s[i].b, i, TOP);
        }
    }

    sort(EP, EP + 2 * n);
    set<int> BT;
    BT.insert(1000000001);
    int cnt = 0;
    for(int i = 0; i < 2 * n; i++){
        if(EP[i].st == TOP) BT.erase(EP[i].p.real());
        else if(EP[i].st == BOTTOM) BT.insert(EP[i].p.real());
        else if(EP[i].st == LEFT){
            set<int>::iterator b = lower_bound(BT.begin(), BT.end(), s[EP[i].seg].a.real());
            set<int>::iterator e = upper_bound(BT.begin(), BT.end(), s[EP[i].seg].b.real());
            cnt += distance(b, e);
        }
    }

    return cnt;
}

// 内接円
Circle Inscribed_Circle(const Point& a, const Point& b, const Point& c){
    double A = abs(b - c), B = abs(c - a), C = abs(a - b);
    Point x = Point((a * A + b * B + c * C) / (A + B + C));
    double r = distance_sp(Segment(a,b),x);
    return Circle(x, r);
}

// 外接円
Circle Circumscribed_Circle(const Point& a, const Point& b, const Point& c){
    Point m1((a+b)/2.0), m2((b+c)/2.0);
    Point v((b-a).imag(), (a-b).real()), w((b-c).imag(), (c-b).real());
    Line s(m1, Point(m1+v)), t(m2, Point(m2+w));
    const Point x = cross_point_ll(s, t);
    return Circle(x, abs(a-x));
}

pair< Point, Point > cross_point_cl(const Circle &c, const Line &l) {
    Point pr = projection(l, c.p);
    if(equals(abs(pr - c.p), c.r)) return {pr, pr};
    Point e = (l.b - l.a) / abs(l.b - l.a);
    auto k = sqrt(norm(c.r) - norm(pr - c.p));
    return {pr - e * k, pr + e * k};
}

// 点pを通る円の接線
pair<Point,Point> tangent_cp(const Circle &c, const Point &p) {
    return cross_point_cc(c, Circle(p, sqrt(norm(c.p - p) - c.r * c.r)));
}

// 二つの円の共通接線
vector< Line > tangent_cc(Circle c1, Circle c2){
    vector< Line > ret;
    if(c1.r < c2.r) swap(c1,c2);
    double g = norm(c1.p-c2.p);
    if(equals(g,0.0)) return ret;
    Point u = (c2.p-c1.p)/sqrt(g);
    Point v = rotate(u, PI * 0.5);
    for(int s:{-1,1}){
        double h = (c1.r+ s*c2.r)/sqrt(g);
        if(equals(1- h*h, 0)){
            ret.emplace_back(c1.p+u*c1.r, c1.p+(u+v)*c1.r);
        }else if(1-h*h > 0){
            Point uu = u*h, vv = v*sqrt(1-h*h);
            ret.emplace_back(c1.p+(uu+vv)*c1.r, c2.p-(uu+vv)*c2.r*s);
            ret.emplace_back(c1.p+(uu-vv)*c1.r, c2.p-(uu-vv)*c2.r*s);
        }
    }
    return ret;
}

Real area_poly_c(const Polygon &p, const Circle &c) {
    if(p.size() < 3) return 0.0;
    function< Real(Circle, Point, Point) > cross_area = [&](const Circle &c, const Point &a, const Point &b) {
        Point va = c.p - a, vb = c.p - b;
        Real f = cross(va, vb), ret = 0.0;
        if(equals(f, 0.0)) return ret;
        if(max(abs(va), abs(vb)) < c.r + EPS) return f;
        if(distance_sp(Segment(a, b), c.p) > c.r - EPS) return c.r * c.r * arg(vb * conj(va));
        auto u = cross_point_cl(c, Segment(a, b));
        vector< Point > tot{a, u.first, u.second, b};
        for(int i = 0; i + 1 < tot.size(); i++) {
            ret += cross_area(c, tot[i], tot[i + 1]);
        }
        return ret;
    };
    Real A = 0;
    for(int i = 0; i < p.size(); i++) {
        A += cross_area(c, p[i], p[(i + 1) % p.size()]);
    }
    return A;
}

Real area_cc(const Circle &c1, const Circle &c2) {
    Real d = abs(c1.p - c2.p);
    if(c1.r + c2.r <= d + EPS) return 0.0;
    if(d <= fabs(c1.r - c2.r) + EPS) {
        Real r = min(c1.r, c2.r);
        return r * r * PI;
    }
    Real rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    Real theta = acos(rc / c1.r);
    Real phi = acos((d - rc) / c2.r);
    return (c1.r * c1.r*theta + c2.r*c2.r*phi - d*c1.r*sin(theta));
}

Real distance_pp(vector< Point > p, vector< Point > q) {
    Real ans = 1e9;
    rep(i,p.size())rep(j,q.size()) {
        ans = min(ans, distance_sp(Segment(q[j], q[(j + 1) % q.size()]), p[i]));
        ans = min(ans, distance_sp(Segment(p[i], p[(i + 1) % p.size()]), q[j]));
    }
    return ans;
}

Real distance_line_poly(Line l, vector< Point > p) {
    Real ans = 1e9;
    rep(i,p.size()) ans = min(ans, distance_lp(l, p[i]));
    return ans;
}

// g <- pair < v , cost > 
template < class T >
vector<T> Dijkstra(vector<vector<pair<int,T>>> &g, int s) {
    vector<T> dist(g.size(), -1);
    priority_queue<pair<T,int>> Q;
    Q.emplace(0, s);
    while(!Q.empty()){
        T cost = Q.top().first;
        int v = Q.top().second;
        Q.pop();
        cost = - cost;
        if(dist[v] == -1){
            dist[v] = cost;
            for(auto e : g[v]){
                if(dist[e.first] == -1 || dist[e.first] > cost + e.second){
                    Q.emplace(-(cost + e.second), e.first);
                }
            }
        }
    }
    return dist;
}

int main(){
    cin.tie(0);
    ios::sync_with_stdio(0);

    while(true)
    {

    int W,N; cin >> W >> N; if(W == 0 && N == 0) break;
    vector< vector< Point > > P(N);
    rep(i,N) {
        int M; cin >> M;
        rep(j,M) {
            Point a; cin >> a;
            P[i].push_back(a);
        }
    }

    vector<vector<pair<int,Real>>> G(N + 2);
    int S = N, T = N + 1;
    rep(i,N)rep(j,N) if(i < j) {
        Real dist = distance_pp(P[i], P[j]);
        G[i].push_back({j, dist});
        G[j].push_back({i, dist});
    }

    rep(i,N) {
        Real mi = 1e9;
        rep(j,P[i].size()) mi = min(mi, P[i][j].real());
        G[S].push_back({i, mi});
        G[i].push_back({S, mi});
    }
    rep(i,N) {
        Real mi = 1e9;
        rep(j,P[i].size()) mi = min(mi, W - P[i][j].real());
        G[i].push_back({T, mi});
        G[T].push_back({i, mi});
    }
     G[S].push_back({T, W});

    auto res = Dijkstra(G, S);
    cout.precision(17);
    cout << res[T] << endl; 

    }
}
accuracy: 1
time_ms: 420
memory_kb: 17024
final_rank: 17

code_snippet: using namespace std;
#include<iostream>
#include<algorithm>
#include<vector>
#include<cmath>
#include<iomanip>
#include<queue>
using Real=double;
const Real EPS=1e-10;
const Real PI=acos((Real)-1);
bool eq(Real a,Real b){return abs(a-b)<EPS;}
struct Point{
	Real x,y;
	Point(Real x_=0,Real y_=0):x(x_),y(y_){}
	Point operator-()const{return Point(-x,-y);}
	Point operator+(const Point&p)const{return Point(x+p.x,y+p.y);}
	Point operator-(const Point&p)const{return Point(x-p.x,y-p.y);}
	Point operator*(const Real k)const{return Point(x*k,y*k);}
	Point operator/(const Real k)const{return Point(x/k,y/k);}
	bool operator<(const Point&p)const{return eq(x,p.x)?y<p.y:x<p.x;}
	bool operator==(const Point&p)const{return eq(x,p.x)&&eq(y,p.y);}
};
istream&operator>>(istream&is,Point&p){return is>>p.x>>p.y;}
ostream&operator<<(ostream&os,const Point&p){return os<<fixed<<setprecision(9)<<p.x<<' '<<p.y;}
struct Line{
	Point p1,p2;
	Line(Point p1_=Point(),Point p2_=Point()):p1(p1_),p2(p2_){}
};
struct Segment:Line{
	Segment(Point p1_=Point(),Point p2_=Point()):Line(p1_,p2_){}
};
struct Circle{
	Point o;
	Real r;
	Circle(Point o_=Point(),Real r_=0):o(o_),r(r_){}
};
using Polygon=vector<Point>;
//function list begin
Point vec(const Line&);
Real norm(const Point&);
Real norm(const Line&);
Real abs(const Point&);
Real abs(const Line&);
Real arg(const Point&);
Real arg(const Line&);
Real arg(const Point&,const Point&,const Point&);// /_abc,[0,pi]
int argtype(const Point&);////(-pi,0]->-1,(0,pi]->1,(0,0)->0
bool argless(const Point&,const Point&);//sorting points with arg
Real dot(const Point&,const Point&);
Real cross(const Point&,const Point&);
Point polar(const Real,const Real);
Point rotate(const Point&,const Real);
enum{ONLINE_FRONT=-2,CLOCKWISE=-1,ON_SEGMENT=0,COUNTER_CLOCKWISE=1,ONLINE_BACK=2};
int ccw(const Point&,const Point&);
int ccw(const Point&,const Point&,const Point&);
int ccw(const Line&,const Point&);
bool orthogonal(const Point&,const Point&);
bool orthogonal(const Line&,const Line&);
bool parallel(const Point&,const Point&);
bool parallel(const Line&,const Line&);
bool intersect(const Line&,const Point&);
bool intersect(const Line&,const Line&);
bool intersect(const Segment&,const Point&);
bool intersect(const Segment&,const Segment&);
bool intersect(const Line&,const Segment&);
bool intersect(const Segment&,const Line&);
bool intersect(const Circle&,const Point&);
int intersect(const Circle&,const Line&);//count contacts
int intersect(const Circle&,const Segment&);//count contacts
bool intersect(const Circle&,const Circle&);
int count_tangent(const Circle&,const Circle&);//count common tangents
Real distance(const Point&,const Point&);
Real distance(const Line&,const Point&);
Real distance(const Line&,const Line&);
Real distance(const Segment&,const Point&);
Real distance(const Segment&,const Segment&);
Real distance(const Line&,const Segment&);
Real distance(const Segment&,const Line&);
Real distance(const Circle&,const Point&);
Real distance(const Circle&,const Line&);
Real distance(const Circle&,const Segment&);
Real distance(const Circle&,const Circle&);
Point projection(const Line&,const Point&);
Point reflection(const Line&,const Point&);
Point crosspoint(const Line&,const Line&);
pair<Point,Point>crosspoint(const Circle&,const Line&);
pair<Point,Point>crosspoint(const Circle&,const Segment&);
pair<Point,Point>crosspoint(const Circle&,const Circle&);
pair<Point,Point>tangent(const Circle&,const Point&);
vector<Line>tangent(const Circle&,const Circle&);
bool is_convex(const Polygon&);
Polygon convex_hull(Polygon,bool=false);
enum{OUT,ON,IN};
int contain(const Polygon&,const Point&);
int contain(const Circle&,const Point&);
int contain(const Circle&,const Segment&);
int convex_contain(const Polygon&,const Point&);//O(log |P|)
Polygon convex_cut(const Polygon&,const Line&);
Real diameter(Polygon);
Real area(const Polygon&);
Real area(const Polygon&,const Line&);
Real area(const Polygon&,const Circle&);
Real area(const Circle&);
Real area(const Circle&,const Circle&);
//function list end
Point vec(const Line&s){return s.p2-s.p1;}
Real norm(const Point&p){return p.x*p.x+p.y*p.y;}
Real norm(const Line&s){return norm(vec(s));}
Real abs(const Point&p){return hypot(p.x,p.y);}
Real abs(const Line&s){return abs(vec(s));}
Real arg(const Point&p){return atan2(p.y,p.x);}
Real arg(const Line&s){return arg(vec(s));}
Real arg(const Point&a,const Point&b,const Point&c){
	Real A=arg(a-b),B=arg(c-b);
	Real theta=abs(A-B);
	return min(theta,2*PI-theta);
}
int argtype(const Point&a)
{
	return a.y<-EPS?-1:a.y>EPS?1:a.x<-EPS?1:a.x>EPS?-1:0;
}
bool argless(const Point&a,const Point&b)
{
	int at=argtype(a),bt=argtype(b);
	return at!=bt?at<bt:ccw(a,b)>0;
}
Real dot(const Point&a,const Point&b){return a.x*b.x+a.y*b.y;}
Real cross(const Point&a,const Point&b){return a.x*b.y-a.y*b.x;}
Point polar(const Real r,const Real theta){return Point(cos(theta),sin(theta))*r;}
Point rotate(const Point&p,const Real theta){
	return Point(p.x*cos(theta)-p.y*sin(theta),p.x*sin(theta)+p.y*cos(theta));
}
int ccw(const Point&a,const Point&b)
{
	return cross(a,b)>EPS?COUNTER_CLOCKWISE
		:cross(a,b)<-EPS?CLOCKWISE
		:dot(a,b)<0?ONLINE_BACK
		:norm(a)<norm(b)?ONLINE_FRONT
		:ON_SEGMENT;
}
int ccw(const Point&a,const Point&b,const Point&c){return ccw(b-a,c-a);}
int ccw(const Line&s,const Point&p){return ccw(s.p1,s.p2,p);}
bool orthogonal(const Point&a,const Point&b){return eq(dot(a,b),0);}
bool orthogonal(const Line&s,const Line&t){return orthogonal(vec(s),vec(t));}
bool parallel(const Point&a,const Point&b){return eq(cross(a,b),0);}
bool parallel(const Line&s,const Line&t){return parallel(vec(s),vec(t));}
bool intersect(const Line&s,const Point&p){return eq(cross(vec(s),p-s.p1),0);}
bool intersect(const Line&s,const Line&t){return !parallel(s,t)||intersect(s,t.p1);}
bool intersect(const Segment&s,const Point&p){return ccw(s,p)==ON_SEGMENT;}
bool intersect(const Segment&s,const Segment&t){
	return ccw(s,t.p1)*ccw(s,t.p2)<=0&&ccw(t,s.p1)*ccw(t,s.p2)<=0;
}
bool intersect(const Line&s,const Segment&t){
	return cross(vec(s),t.p1-s.p1)*cross(vec(s),t.p2-s.p1)<EPS;
}
bool intersect(const Segment&s,const Line&t){return intersect(t,s);}
bool intersect(const Circle&c,const Point&p){return eq(distance(c.o,p),c.r);}
int intersect(const Circle&c,const Line&s){
	Real d=distance(s,c.o);
	return eq(d,c.r)?1:d<c.r?2:0;
}
int intersect(const Circle&c,const Segment&s){
	Point h=projection(s,c.o);
	Real d1=distance(c.o,s.p1),d2=distance(c.o,s.p2);
	return distance(c.o,h)>c.r+EPS?0
		:d1<c.r-EPS&&d2<c.r-EPS?0
		:(d1<c.r-EPS&&d2>c.r-EPS)||(d1>c.r-EPS&&d2<c.r-EPS)?1
		:intersect(s,h)?eq(distance(c.o,h),c.r)?1:2
		:0;
}
bool intersect(const Circle&a,const Circle&b){
	int c=count_tangent(a,b);
	return 1<=c&&c<=3;
}
int count_tangent(const Circle&a,const Circle&b){
	Real d=distance(a.o,b.o);
	return eq(d,a.r+b.r)?3:d>a.r+b.r?4:eq(d,abs(a.r-b.r))?1:d>abs(a.r-b.r)?2:0;
}
Real distance(const Point&a,const Point&b){return abs(a-b);}
Real distance(const Line&s,const Point&p){return distance(p,projection(s,p));}
Real distance(const Line&s,const Line&t){return intersect(s,t)?0:distance(s,t.p1);}
Real distance(const Segment&s,const Point&p){
	return distance(p,
		dot(vec(s),p-s.p1)<0?s.p1
		:dot(-vec(s),p-s.p2)<0?s.p2
		:projection(s,p)
	);
}
Real distance(const Segment&s,const Segment&t){
	return intersect(s,t)?0:min({
		distance(s,t.p1),distance(s,t.p2),
		distance(t,s.p1),distance(t,s.p2)
	});
}
Real distance(const Line&s,const Segment&t){
	return intersect(s,t)?0:min(distance(s,t.p1),distance(s,t.p2));
}
Real distance(const Segment&s,const Line&t){return distance(t,s);}
Real distance(const Circle&c,const Point&p){return abs(distance(c.o,p)-c.r);}
Real distance(const Circle&c,const Line&s){return max(distance(s,c.o)-c.r,(Real)0);}
Real distance(const Circle&c,const Segment&s){
	return intersect(c,s)?0
		:contain(c,s)?c.r-max(distance(c.o,s.p1),distance(c.o,s.p2))
		:distance(s,c.o)-c.r;
}
Real distance(const Circle&a,const Circle&b){return max(distance(a.o,b.o)-a.r-b.r,(Real)0);}
Point projection(const Line&s,const Point&p){
	return s.p1+vec(s)*dot(p-s.p1,vec(s))/norm(s);
}
Point reflection(const Line&s,const Point&p){return projection(s,p)*2-p;}
Point crosspoint(const Line&s,const Line&t){
	Real d1=cross(vec(s),t.p1-s.p1);
	Real d2=-cross(vec(s),t.p2-s.p1);
	return t.p1+vec(t)*(d1/(d1+d2));
}
pair<Point,Point>crosspoint(const Circle&c,const Line&s){
	Point h=projection(s,c.o);
	Point e=vec(s)/abs(s)*sqrt(c.r*c.r-norm(h-c.o));
	return minmax(h-e,h+e);
}
pair<Point,Point>crosspoint(const Circle&c,const Segment&s){
	pair<Point,Point>p=crosspoint(c,Line(s));
	return intersect(c,s)==2?p
		:intersect(s,p.first)?make_pair(p.first,p.first)
		:make_pair(p.second,p.second);
}
pair<Point,Point>crosspoint(const Circle&a,const Circle&b){
	Real d=distance(a.o,b.o);
	Real alpha=acos((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d));
	Real theta=arg(b.o-a.o);
	return minmax(a.o+polar(a.r,theta+alpha),a.o+polar(a.r,theta-alpha));
}
pair<Point,Point>tangent(const Circle&c,const Point&p){
	return crosspoint(c,Circle(p,sqrt(norm(c.o-p)-c.r*c.r)));
}
vector<Line>tangent(const Circle&a,const Circle&b){
	vector<Line>ret;
	Real g=distance(a.o,b.o);
	if(eq(g,0))return ret;
	Point u=(b.o-a.o)/g;
	Point v=rotate(u,PI/2);
	for(int s:{-1,1}){
		Real h=(a.r+b.r*s)/g;
		if(eq(h*h,1))ret.emplace_back(a.o+(h>0?u:-u)*a.r,a.o+(h>0?u:-u)*a.r+v);
		else if(1-h*h>0){
			Point U=u*h,V=v*sqrt(1-h*h);
			ret.emplace_back(a.o+(U+V)*a.r,b.o-(U+V)*b.r*s);
			ret.emplace_back(a.o+(U-V)*a.r,b.o-(U-V)*b.r*s);
		}
	}
	return ret;
}
bool is_convex(const Polygon&P){
	for(int i=0;i<P.size();i++)
		if(ccw(P[i],P[(i+1)%P.size()],P[(i+2)%P.size()])==CLOCKWISE)return false;
	return true;
}
Polygon convex_hull(Polygon P,bool ONSEG){
	if(P.size()<=2)return P;
	sort(P.begin(),P.end());
	Polygon ret(2*P.size());
	int k=0,t;
	if(ONSEG){
		for(const Point&p:P){
			while(k>=2&&ccw(ret[k-2],ret[k-1],p)==CLOCKWISE)k--;
			ret[k++]=p;
		}
		t=k;
		for(int i=P.size()-2;i>=0;i--){
			while(k>=t+1&&ccw(ret[k-2],ret[k-1],P[i])==CLOCKWISE)k--;
			ret[k++]=P[i];
		}
	}
	else{
		for(const Point&p:P){
			while(k>=2&&ccw(ret[k-2],ret[k-1],p)!=COUNTER_CLOCKWISE)k--;
			ret[k++]=p;
		}
		t=k;
		for(int i=P.size()-2;i>=0;i--){
			while(k>=t+1&&ccw(ret[k-2],ret[k-1],P[i])!=COUNTER_CLOCKWISE)k--;
			ret[k++]=P[i];
		}
	}
	ret.resize(k-1);
	int mi=0;
	for(int i=1;i<k-1;i++)
		if(eq(ret[mi].y,ret[i].y)?ret[mi].x>ret[i].x:ret[mi].y>ret[i].y)mi=i;
	rotate(ret.begin(),ret.begin()+mi,ret.end());
	return ret;
}
int contain(const Polygon&P,const Point&p){
	bool in=false;
	for(int i=0;i<P.size();i++){
		Segment s(P[i],P[(i+1)%P.size()]);
		if(intersect(s,p))return ON;
		else{
			Point a=s.p1-p,b=s.p2-p;
			if(a.y>b.y)swap(a,b);
			if(a.y<EPS&&EPS<b.y&&cross(a,b)>EPS)in=!in;
		}
	}
	return in?IN:OUT;
}
int contain(const Circle&c,const Point&p){
	Real d=distance(c.o,p);
	return eq(d,c.r)?ON:d<c.r?IN:OUT;
}
int contain(const Circle&c,const Segment&s){
	Real d1=distance(c.o,s.p1),d2=distance(c.o,s.p2);
	return d1<c.r+EPS&&d2<c.r+EPS?eq(d1,c.r)||eq(d2,c.r)?ON:IN:OUT;
}
int convex_contain(const Polygon&P,const Point&p)
{
	if(P[0]==p)return ON;
	int l=0,r=P.size();
	while(r-l>1)
	{
		int mid=(l+r)/2;
		int t=ccw(P[0],P[mid],p);
		if(t==CLOCKWISE)r=mid;
		else l=mid;
	}
	if(r==1)return OUT;
	if(l+1==P.size())
	{
		if(intersect(Segment(P[0],P[P.size()-1]),p))return ON;
		else return OUT;
	}
	if(l==1&&intersect(Segment(P[0],P[1]),p))return ON;
	Polygon tmp={P[0],P[l],P[l+1]};
	int ret=contain(tmp,p);
	if(ret==ON)
	{
		if(intersect(Segment(P[l],P[l+1]),p))return ON;
		else return IN;
	}
	return ret;
}
Polygon convex_cut(const Polygon&P,const Line&s){
	Polygon ret;
	for(int i=0;i<P.size();i++){
		Segment t(P[i],P[(i+1)%P.size()]);
		if(ccw(s,t.p1)!=CLOCKWISE)ret.push_back(t.p1);
		if(!parallel(s,t)&&!intersect(s,t.p1)
			&&!intersect(s,t.p2)&&intersect(s,t))ret.push_back(crosspoint(s,t));
	}
	return ret;
}
Real diameter(Polygon P){
	if(!is_convex(P))P=convex_hull(P);
	int mi=0,Mi=0;
	for(int i=1;i<P.size();i++){
		if(P[i].x<P[mi].x)mi=i;
		if(P[i].x>P[Mi].x)Mi=i;
	}
	Real ret=0;
	int sm=mi,sM=Mi;
	while(mi!=sM||Mi!=sm){
		ret=max(ret,norm(P[mi]-P[Mi]));
		if(cross(P[(mi+1)%P.size()]-P[mi],P[(Mi+1)%P.size()]-P[Mi])<0)mi=(mi+1)%P.size();
		else Mi=(Mi+1)%P.size();
	}
	return sqrt(ret);
}
Real area(const Polygon&P){
	Real ret=0;
	for(int i=0;i<P.size();i++)ret+=cross(P[i],P[(i+1)%P.size()]);
	return ret/2;
}
Real area(const Polygon&P,const Line&s){return area(convex_cut(P,s));}
Real area(const Polygon&P,const Circle&c){
	Real ret=0;
	for(int i=0;i<P.size();i++)
	{
		Segment s(P[i],P[(i+1)%P.size()]);
		if(contain(c,s))ret+=cross(s.p1-c.o,s.p2-c.o);
		else if(!intersect(c,s)){
			Real a=arg(s.p2-c.o)-arg(s.p1-c.o);
			if(a>PI)a-=2*PI;
			if(a<-PI)a+=2*PI;
			ret+=c.r*c.r*a;
		}
		else
		{
			pair<Point,Point>p=crosspoint(c,s);
			Point tmp[4]={s.p1,p.first,p.second,s.p2};
			if(intersect(c,Segment(s.p1,p.first))==2)swap(tmp[1],tmp[2]);
			for(int j=0;j<3;j++)
			{
				Segment t(tmp[j],tmp[j+1]);
				if(contain(c,t))ret+=cross(t.p1-c.o,t.p2-c.o);
				else{
					Real a=arg(t.p2-c.o)-arg(t.p1-c.o);
					if(a>PI)a-=2*PI;
					if(a<-PI)a+=2*PI;
					ret+=c.r*c.r*a;
				}
			}
		}
	}
	return ret/2;
}
Real area(const Circle&c){return PI*c.r*c.r;}
Real area(const Circle&a,const Circle&b)
{
	int c=count_tangent(a,b);
	if(c>=3)return 0;
	else if(c<=1)return area(a.r<b.r?a:b);
	else
	{
		Real d=distance(a.o,b.o);
		Real ret=0;
		{
			Real alpha=acos((a.r*a.r+d*d-b.r*b.r)/(2*a.r*d));
			ret+=alpha*a.r*a.r;
			ret-=sin(alpha*2)*a.r*a.r/2;
		}
		{
			Real alpha=acos((b.r*b.r+d*d-a.r*a.r)/(2*b.r*d));
			ret+=alpha*b.r*b.r;
			ret-=sin(alpha*2)*b.r*b.r/2;
		}
		return ret;
	}
}
Polygon P[200];
int main()
{
	int W,N;
	while(cin>>W>>N,W)
	{
		for(int i=0;i<N;i++)
		{
			int k;cin>>k;
			P[i].resize(k);
			for(int j=0;j<k;j++)cin>>P[i][j];
		}
		vector<vector<pair<int,double> > >G(N+2);
		int st=N,go=N+1;
		G[st].push_back(make_pair(go,W));
		G[go].push_back(make_pair(st,W));
		for(int i=0;i<N;i++)
		{
			double Lmin=W,Rmin=W;
			for(Point&p:P[i])
			{
				Lmin=min(Lmin,p.x);
				Rmin=min(Rmin,W-p.x);
			}
			G[st].push_back(make_pair(i,Lmin));
			G[i].push_back(make_pair(st,Lmin));
			G[i].push_back(make_pair(go,Rmin));
			G[go].push_back(make_pair(i,Rmin));
			for(int j=i+1;j<N;j++)
			{
				double now=1e9;
				for(int I=0;I<P[i].size();I++)
				{
					Segment s(P[i][I],P[i][I+1==P[i].size()?0:I+1]);
					for(int J=0;J<P[j].size();J++)
					{
						Segment t(P[j][J],P[j][J+1==P[j].size()?0:J+1]);
						now=min(now,distance(s,t));
					}
				}
				G[i].push_back(make_pair(j,now));
				G[j].push_back(make_pair(i,now));
			}
		}
		priority_queue<pair<double,int> >Q;
		vector<double>dist(N+2,1e9);
		dist[st]=0;
		Q.push(make_pair(0,st));
		while(!Q.empty())
		{
			double c=-Q.top().first;
			int u=Q.top().second;
			Q.pop();
			if(dist[u]<c)continue;
			for(pair<int,double>e:G[u])
			{
				int v=e.first;
				double nxt=c+e.second;
				if(dist[v]>nxt)
				{
					dist[v]=nxt;
					Q.push(make_pair(-nxt,v));
				}
			}
		}
		cout<<fixed<<setprecision(16)<<dist[go]<<endl;
	}
}
accuracy: 1
time_ms: 100
memory_kb: 4544
final_rank: 8

code_snippet: /*	author:  Kite_kuma
	created: 2021.09.10 16:11:11 */

// #ifdef LOCAL
// #define _GLIBCXX_DEBUG
// #endif
#include <bits/stdc++.h>
using namespace std;

#pragma region macros

#define foa(s, v) for(auto &s : v)
#define all(v) (v).begin(), (v).end()
#define rall(v) (v).rbegin(), (v).rend()
#define popcnt(n) __builtin_popcountll((long long)n)

#define REPname(a, b, c, d, e, ...) e
#define rep(...) REPname(__VA_ARGS__, REP3, REP2, REP1, REP0)(__VA_ARGS__)
#define REP0(x) for(int Counter_in_rep_macro = 0; Counter_in_rep_macro < (x); ++Counter_in_rep_macro)
#define REP1(i, x) for(int i = 0; i < (x); ++i)
#define REP2(i, l, r) for(int i = (l); i < (r); ++i)
#define REP3(i, l, r, c) for(int i = (l); i < (r); i += (c))

#define DREPname(a, b, c, d, e, ...) e
#define drep(...) DREPname(__VA_ARGS__, DREP3, DREP2, DREP1)(__VA_ARGS__)
#define DREP1(i, x) for(int i = (x)-1; i >= 0; --i)
#define DREP2(i, l, r) for(int i = (r)-1; i >= (l); --i)
#define DREP3(i, l, r, c) for(int i = (r)-1; i >= (l); i -= (c))

#pragma endregion

#pragma region aliases

using ll = long long;
using ld = long double;
using ull = unsigned long long;
using vi = std::vector<int>;
using vvi = std::vector<std::vector<int>>;
using vvvi = std::vector<std::vector<std::vector<int>>>;
using vll = std::vector<ll>;
using vvll = std::vector<vll>;
using vvvll = std::vector<vvll>;
using pii = std::pair<int, int>;
using pll = std::pair<long long, long long>;
template <class T = ll>
using V = std::vector<T>;
template <class T = ll>
using VV = V<V<T>>;
template <class T = ll>
using VVV = V<V<V<T>>>;
template <class T = ll>
using pqup = std::priority_queue<T, std::vector<T>, std::greater<T>>;
template <class T = ll>
using pqdn = std::priority_queue<T>;

#pragma endregion

#pragma region constants

const int inf = 1e9;
const long long INF = 1e18;
const long double pi = acos(-1);
const char dl = '\n';
const char sp = ' ';
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};

const int mod_1000000007 = 1000000007;
const int mod_998244353 = 998244353;

#pragma endregion

#pragma region basic_operation

template <class T0, class T1, class T2>
inline bool in_range(T0 x, T1 lef, T2 rig) {
	return ((lef <= x) && (x < rig));
}

template <class T>
inline bool chmin(T &a, T b) {
	if(a > b) {
		a = b;
		return true;
	}
	return false;
}
template <class T>
inline bool chmax(T &a, T b) {
	if(a < b) {
		a = b;
		return true;
	}
	return false;
}

void Yes(bool f = 1) { std::cout << (f ? "Yes" : "No") << '\n'; }
void No() { std::cout << "No\n"; }
void YES(bool f = 1) { std::cout << (f ? "YES" : "NO") << '\n'; }
void NO() { std::cout << "NO\n"; }

template <class T>
void drop(T answer) {
	std::cout << answer << '\n';
	exit(0);
}

void err(bool flag = true) {
	if(!flag) return;
	std::cout << -1 << '\n';
	exit(0);
}

template <class T>
void vout(std::vector<T> const &v, bool vertically = 0) {
	if(vertically) {
		for(auto const &a : v) {
			std::cout << a << '\n';
		}
		return;
	}
	for(auto it = v.begin(); it != v.end(); it++) {
		std::cout << (*it);
		if(it != v.end() - 1) {
			std::cout << ' ';
		}
	}
	std::cout << '\n';
	return;
}

inline void print() { std::cout << '\n'; }
template <class T>
inline void print(T x) {
	std::cout << x << '\n';
	return;
}
template <typename Head, typename... Tail>
void print(Head H, Tail... T) {
	std::cout << H << " ";
	print(T...);
}

template <class T>
void add(std::vector<T> &v, T val) {
	for(auto &a : v) a += val;
	return;
}

template <class T>
T dup(T a, T b) {
	assert(b != 0);
	return (a + b - 1) / b;
}

template <class T>
T greatest_lower_multiple(T x, T d) {
	if(d == 0) return 0;
	if(d < 0) d *= -1;
	T y = x % d;
	if(y < 0) y += d;
	return x - y;
}

template <class T>
T least_upper_multiple(T x, T d) {
	return -greatest_lower_multiple(-x, d);
}

long long POW(long long a, long long n) {
	long long res = 1;
	while(n > 0) {
		if(n & 1) res = res * a;
		a = a * a;
		n >>= 1;
	}
	return res;
}

long long modpow(long long a, long long n, long long mod) {	 // a^n mod
	assert(n >= 0 && mod);
	if(mod == 1) return 0LL;
	long long res = 1;
	a %= mod;
	while(n > 0) {
		if(n & 1) res = res * a % mod;
		a = a * a % mod;
		n >>= 1;
	}
	return res < 0 ? res + mod : res;
}

// return x which satisfies a * x % mod == gcd(a, mod)
// not (mod | a)
long long modinv(long long a, long long mod) {
	long long b = mod, u = 1, v = 0;
	while(b) {
		long long t = a / b;
		a -= t * b;
		std::swap(a, b);
		u -= t * v;
		std::swap(u, v);
	}
	u %= mod;
	if(u < 0) u += mod;
	return u;
}

template <class T>
int lb(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::lower_bound(a.begin(), a.end(), x));
}
template <class T>
int ub(const std::vector<T> &a, const T x) {
	return std::distance(a.begin(), std::upper_bound(a.begin(), a.end(), x));
}
template <class T>
void unq_sort(std::vector<T> &a) {
	std::sort(a.begin(), a.end());
	a.erase(std::unique(a.begin(), a.end()), a.end());
}
template <class T>
std::vector<int> press(std::vector<T> &a) {
	auto vec = a;
	unq_sort(vec);
	std::vector<int> ret;
	for(auto &v : a) ret.push_back(lb(vec, v));
	return ret;
}

#pragma endregion

#pragma region input
#define VEC(type, name, size) \
	vector<type> name(size);  \
	scanner::INPUT(name)
#define VVEC(type, name, h, w)                     \
	vector<vector<type>> name(h, vector<type>(w)); \
	scanner::INPUT(name)
#define INT(...)     \
	int __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LL(...)            \
	long long __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define STR(...)        \
	string __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define CHR(...)      \
	char __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define DBL(...)        \
	double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define LD(...)              \
	long double __VA_ARGS__; \
	scanner::INPUT(__VA_ARGS__)
#define TPL3(type0, type1, type2, name)   \
	std::tuple<type0, type1, type2> name; \
	scanner::INPUT(name);
#define TPL4(type0, type1, type2, type3, name)   \
	std::tuple<type0, type1, type2, type3> name; \
	scanner::INPUT(name);

namespace scanner {
template <class T>
void scan(T &a) {
	std::cin >> a;
}

template <class T, class L>
void scan(std::pair<T, L> &p) {
	scan(p.first);
	scan(p.second);
}

template <class T0, class T1, class T2>
void scan(std::tuple<T0, T1, T2> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	scan(t0);
	scan(t1);
	scan(t2);
	p = std::make_tuple(t0, t1, t2);
}

template <class T0, class T1, class T2, class T3>
void scan(std::tuple<T0, T1, T2, T3> &p) {
	T0 t0;
	T1 t1;
	T2 t2;
	T3 t3;
	scan(t0);
	scan(t1);
	scan(t2);
	scan(t3);
	p = std::make_tuple(t0, t1, t2, t3);
}

template <class T>
void scan(std::vector<T> &a) {
	for(auto &i : a) scan(i);
}

void INPUT() {}
template <class Head, class... Tail>
void INPUT(Head &head, Tail &... tail) {
	scan(head);
	INPUT(tail...);
}
}  // namespace scanner

template <typename T1, typename T2>
std::istream &operator>>(std::istream &is, std::pair<T1, T2> &p) {
	is >> p.first >> p.second;
	return is;
}
#pragma endregion

#pragma region debug

#pragma region output
template <typename T1, typename T2>
std::ostream &std::operator<<(std::ostream &os, const std::pair<T1, T2> &p) {
	os << p.first << " " << p.second;
	return os;
}
template <class T>
std::ostream &std::operator<<(std::ostream &os, const std::vector<T> &v) {
	for(int i = 0; i < (int)v.size(); i++) {
		if(i) os << " ";
		os << v[i];
	}
	return os;
}
#pragma endregion

#pragma region view

namespace viewer {
void view(const long long e) {
	if(e == INF)
		std::cerr << "INF";
	else if(e == -INF)
		std::cerr << "-INF";
	else
		std::cerr << e;
}

void view(const int e) {
	if(e == inf)
		std::cerr << "inf";
	else if(e == -inf)
		std::cerr << "-inf";
	else
		std::cerr << e;
}

template <typename T>
void view(const T e) {
	std::cerr << e;
}

template <typename T, typename U>
void view(const std::pair<T, U> &p) {
	std::cerr << "(";
	view(p.first);
	std::cerr << ", ";
	view(p.second);
	std::cerr << ")";
}

template <class T0, class T1, class T2>
void view(const std::tuple<T0, T1, T2> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ")";
}

template <class T0, class T1, class T2, class T3>
void view(const std::tuple<T0, T1, T2, T3> &p) {
	std::cerr << "(";
	view(std::get<0>(p));
	std::cerr << ", ";
	view(std::get<1>(p));
	std::cerr << ", ";
	view(std::get<2>(p));
	std::cerr << ", ";
	view(std::get<3>(p));
	std::cerr << ")";
}

template <typename T>
void view(const std::set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::unordered_set<T> &s) {
	if(s.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(auto &t : s) {
		view(t);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<T> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << "{ ";
	for(const auto &e : v) {
		view(e);
		std::cerr << ", ";
	}
	std::cerr << "\b\b }";
}

template <typename T>
void view(const std::vector<std::vector<T>> &vv) {
	std::cerr << "{\n";
	for(const auto &v : vv) {
		std::cerr << "\t";
		view(v);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::vector<std::pair<T, U>> &v) {
	std::cerr << "{\n";
	for(const auto &c : v) {
		std::cerr << "\t(";
		view(c.first);
		std::cerr << ", ";
		view(c.second);
		std::cerr << ")\n";
	}
	std::cerr << "}";
}

template <class T0, class T1, class T2>
void view(const std::vector<std::tuple<T0, T1, T2>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <class T0, class T1, class T2, class T3>
void view(const std::vector<std::tuple<T0, T1, T2, T3>> &v) {
	if(v.empty()) {
		std::cerr << "{ }";
		return;
	}
	std::cerr << '{';
	for(const auto &t : v) {
		std::cerr << "\n\t";
		view(t);
		std::cerr << ",";
	}
	std::cerr << "\n}";
}

template <typename T, typename U>
void view(const std::map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}

template <typename T, typename U>
void view(const std::unordered_map<T, U> &m) {
	std::cerr << "{\n";
	for(const auto &t : m) {
		std::cerr << "\t[";
		view(t.first);
		std::cerr << "] : ";
		view(t.second);
		std::cerr << '\n';
	}
	std::cerr << "}";
}
}  // namespace viewer

#pragma endregion

// when debugging : g++ foo.cpp -DLOCAL
#ifdef LOCAL
void debug_out() {}
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	viewer::view(H);
	std::cerr << ", ";
	debug_out(T...);
}
#define debug(...)                                                \
	do {                                                          \
		std::cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                                   \
		std::cerr << "\b\b]\n";                                   \
	} while(0)
#define dump(x)                                      \
	do {                                             \
		std::cerr << __LINE__ << " " << #x << " : "; \
		viewer::view(x);                             \
		std::cerr << '\n';                           \
	} while(0)

#else
#define debug(...) (void(0))
#define dump(x) (void(0))
#endif

#pragma endregion

#pragma region geometry_light

using Real = long double;
using R = Real;
using Point = std::complex<Real>;
using Vec = Point;
const Real EPS = 1e-10, PI = acos(-1);

inline bool eq(const Real &a, const Real &b) { return fabs(b - a) < EPS; }
inline bool eq(const Point &a, const Point &b) { return fabs(b - a) < EPS; }
/*
	-1: a < b
	0 : a == b
	1 : a > b
*/
inline int compare(const Real &a, const Real &b) { return eq(a, b) ? 0 : a < b ? -1 : 1; }
inline int sign(const Real &a) { return fabs(a) < EPS ? 0 : a < 0 ? -1 : 1; }

namespace std {
const Point operator*(const Point &p, const Real &d) { return Point(real(p) * d, imag(p) * d); }
}  // namespace std

std::istream &operator>>(std::istream &is, Point &p) {
	Real a, b;
	is >> a >> b;
	p = Point(a, b);
	return is;
}
std::ostream &operator<<(std::ostream &os, Point &p) { return os << std::fixed << std::setprecision(10) << p.real() << " " << p.imag(); }

// rotate point 'p' for counter clockwise direction
const Point rotate(const Real &theta, const Point &p) {
	return Point(cos(theta) * p.real() - sin(theta) * p.imag(), sin(theta) * p.real() + cos(theta) * p.imag());
}

const Real radian_to_degree(const Real &r) { return (r * 180.0 / PI); }

const Real degree_to_radian(const Real &d) { return (d * PI / 180.0); }

// get angle a-b-c (<pi)
const Real get_angle(const Point &a, const Point &b, const Point &c) {
	const Point v(a - b), w(c - b);
	Real theta = fabs(atan2(w.imag(), w.real()) - atan2(v.imag(), v.real()));
	return std::min(theta, 2 * PI - theta);
}

namespace std {
bool operator<(const Point &a, const Point &b) { return a.real() != b.real() ? a.real() < b.real() : a.imag() < b.imag(); }
}  // namespace std

struct Line {
	Point a, b;

	Line() = default;

	Line(Point a, Point b) : a(a), b(b) {}

	Line(Real A, Real B, Real C)  // Ax + By = C
	{
		if(eq(A, 0))
			a = Point(0, C / B), b = Point(1, C / B);
		else if(eq(B, 0))
			b = Point(C / A, 0), b = Point(C / A, 1);
		else
			a = Point(0, C / B), b = Point(C / A, 0);
	}

	friend std::ostream &operator<<(std::ostream &os, Line &p) { return os << p.a << " -- " << p.b; }

	friend std::istream &operator>>(std::istream &is, Line &a) { return is >> a.a >> a.b; }
};

struct Segment : Line {
	Segment() = default;

	Segment(Point a, Point b) : Line(a, b) {}
};

struct Circle {
	Point p;
	Real r;

	Circle() = default;

	Circle(Point p, Real r) : p(p), r(r) {}
};

using Points = std::vector<Point>;
using Polygon = std::vector<Point>;
using Segments = std::vector<Segment>;
using Lines = std::vector<Line>;
using Circles = std::vector<Circle>;

const Real cross(const Point &a, const Point &b) { return real(a) * imag(b) - imag(a) * real(b); }
const Real dot(const Point &a, const Point &b) { return real(a) * real(b) + imag(a) * imag(b); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C
const int ccw(const Point &a, Point b, Point c) {
	b = b - a, c = c - a;
	if(cross(b, c) > EPS) return +1;		// "COUNTER_CLOCKWISE"
	if(cross(b, c) < -EPS) return -1;		// "CLOCKWISE"
	if(dot(b, c) < -EPS) return +2;			// "ONLINE_BACK"
	if(norm(b) + EPS < norm(c)) return -2;	// "ONLINE_FRONT"
	return 0;								// "ON_SEGMENT"
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool parallel(const Line &a, const Line &b) { return eq(cross(a.b - a.a, b.b - b.a), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A
bool orthogonal(const Line &a, const Line &b) { return eq(dot(a.a - a.b, b.a - b.b), 0.0); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A
Point projection(const Line &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

Point projection(const Segment &l, const Point &p) {
	double t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
	return l.a + (l.a - l.b) * t;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B
Point reflection(const Line &l, const Point &p) { return projection(l, p) * 2.0 - p; }

int intersect(const Line &l, const Point &p) { return int(abs(ccw(l.a, l.b, p)) != 1); }

int intersect(const Line &l, const Line &m) {
	if(intersect(l, m.a) && intersect(l, m.b)) return -1;
	return int(abs(cross(l.b - l.a, m.b - m.a)) > EPS);
}

int intersect(const Segment &s, const Point &p) { return int(ccw(s.a, s.b, p) == 0); }

int intersect(const Line &l, const Segment &s) {
	if(intersect(l, s.a) && intersect(l, s.b)) return -1;
	return cross(l.b - l.a, s.a - l.a) * cross(l.b - l.a, s.b - l.a) < EPS;
}

Real distance(const Line &l, const Point &p);

int intersect(const Circle &c, const Line &l) {
	Real d = c.r - distance(l, c.p);
	return fabs(d) < EPS ? 1 : d > 0. ? 2 : 0;
}

int intersect(const Circle &c, const Point &p) { return int(abs(abs(p - c.p) - c.r) < EPS); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B
int intersect(const Segment &s, const Segment &t) {
	if(eq(s.a, s.b)) return intersect(t, s.a);
	if(intersect(Line(s), t.a) && intersect(Line(s), t.b) &&
	   std::max(std::min(s.a, s.b), std::min(t.a, t.b)) < std::min(std::max(s.a, s.b), std::max(t.a, t.b)))
		return -1;
	return int(ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0);
}

int intersect(const Circle &c, const Segment &l) {
	const Point h = projection(l, c.p);
	if(norm(h - c.p) - c.r * c.r > EPS) return 0;
	auto d1 = abs(c.p - l.a), d2 = abs(c.p - l.b);
	if(compare(d1, c.r) == -1 && compare(d2, c.r) == -1) return 0;
	if(d1 < c.r - EPS && d2 > c.r - EPS || d1 > c.r - EPS && d2 < c.r - EPS) return 1;
	return dot(l.a - h, l.b - h) < 0 ? 2 : 0;
}

Real distance(const Point &a, const Point &b);

int number_of_common_tangents(const Circle &c1, const Circle &c2) {
	Real r1 = std::min(c1.r, c2.r), r2 = std::max(c1.r, c2.r), d = distance(c1.p, c2.p);
	int com = compare(r1 + r2, d);
	return com == 1 ? compare(d + r1, r2) + 1 : 3 - com;
	// if(c1.r < c2.r) swap(c1, c2);
	// Real d = abs(c1.p - c2.p);
	// if(compare(c1.r + c2.r, d) == -1) return 4;
	// if(eq(c1.r + c2.r, d)) return 3;
	// if(compare(c1.r - c2.r, d) == -1) return 2;
	// return int(eq(c1.r - c2.r, d));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_A&lang=jp
int intersect(const Circle &c1, const Circle &c2) { return 2 - abs(2 - number_of_common_tangents(c1, c2)); }

Real distance(const Point &a, const Point &b) { return abs(a - b); }

Real distance(const Line &l, const Point &p) { return abs(p - projection(l, p)); }

Real distance(const Line &l, const Line &m) { return intersect(l, m) ? 0 : distance(l, m.a); }

Real distance(const Segment &s, const Point &p) {
	Point r = projection(s, p);
	return intersect(s, r) ? distance(r, p) : std::min(abs(s.a - p), abs(s.b - p));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D
Real distance(const Segment &a, const Segment &b) {
	if(intersect(a, b)) return 0;
	return std::min({distance(a, b.a), distance(a, b.b), distance(b, a.a), distance(b, a.b)});
}

Real distance(const Line &l, const Segment &s) {
	if(intersect(l, s)) return 0;
	return std::min(distance(l, s.a), distance(l, s.b));
}

Point crosspoint(const Line &l, const Line &m) {
	Real A = cross(l.b - l.a, m.b - m.a);
	Real B = cross(l.b - l.a, l.b - m.a);
	if(eq(abs(A), 0.0) && eq(abs(B), 0.0)) return m.a;
	return m.a + (m.b - m.a) * B / A;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C
Point crosspoint(const Segment &l, const Segment &m) { return crosspoint(Line(l), Line(m)); }

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_D
std::pair<Point, Point> crosspoint(const Circle &c, const Line l) {
	Point pr = projection(l, c.p);
	if(eq(distance(l, c.p), c.r)) return {pr, pr};
	Vec v = (l.b - l.a) / abs(l.b - l.a) * sqrt(c.r * c.r - norm(pr - c.p));
	return make_pair(pr - v, pr + v);
	// Vec e = (l.b - l.a) / abs(l.b - l.a);
	// double base = sqrt(c.r * c.r - norm(pr - c.p));
	// return {pr - e * base, pr + e * base};
}

std::pair<Point, Point> crosspoint(const Circle &c, const Segment &l) {
	if(intersect(c, l) == 2) return crosspoint(c, Line(l.a, l.b));
	auto ret = crosspoint(c, Line(l.a, l.b));
	if(dot(l.a - ret.first, l.b - ret.first) < EPS)
		ret.second = ret.first;
	else
		ret.first = ret.second;
	return ret;
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_E
std::pair<Point, Point> crosspoint(const Circle &c1, const Circle &c2) {
	Real d = abs(c1.p - c2.p);
	Real a = acos((c1.r * c1.r + d * d - c2.r * c2.r) / (2 * c1.r * d));  // cosine theorem
	Real t = atan2(c2.p.imag() - c1.p.imag(), c2.p.real() - c1.p.real());
	Point p1 = c1.p + Point(cos(t + a) * c1.r, sin(t + a) * c1.r);
	Point p2 = c1.p + Point(cos(t - a) * c1.r, sin(t - a) * c1.r);
	return make_pair(p1, p2);
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_F
// "点 p を通る円 c の接線"の接点2つ
std::pair<Point, Point> tangent(const Circle &c1, const Point &p2) {
	return crosspoint(c1, Circle(p2, sqrt(norm(c1.p - p2) - c1.r * c1.r)));
}

// http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_7_G
// 円 c1, c2 の共通接線
Lines tangent(Circle c1, Circle c2) {
	Lines ret;
	if(c1.r < c2.r) std::swap(c1, c2);
	Real g = norm(c1.p - c2.p);
	if(eq(g, 0)) return ret;
	Vec u = (c2.p - c1.p) / Real(sqrt(g));
	Vec v = rotate(PI * 0.5, u);
	for(int s : {-1, 1}) {
		Real h = (c1.r + s * c2.r) / sqrt(g);
		if(eq(1 - h * h, 0)) {
			ret.emplace_back(c1.p + u * c1.r, c1.p + (u + v) * c1.r);
		} else if(1 - h * h > 0) {
			Point uu = u * h, vv = v * sqrt(1 - h * h);
			ret.emplace_back(c1.p + (uu + vv) * c1.r, c2.p - (uu + vv) * c2.r * s);
			ret.emplace_back(c1.p + (uu - vv) * c1.r, c2.p - (uu - vv) * c2.r * s);
		}
	}
	return ret;
}

#pragma endregion

ld solve(int w) {
	int n;
	cin >> n;
	V<Polygon> pgns;
	V<Segments> edges;
	rep(n) {
		int m;
		cin >> m;
		Polygon p;
		rep(m) {
			Point pt;
			cin >> pt;
			p.push_back(pt);
		}
		pgns.push_back(p);

		Segments ed;
		rep(i, m) {
			int j = (i + 1) % m;
			ed.emplace_back(p[i], p[j]);
		}
		edges.push_back(ed);
	}

	int left_id = n, right_id = n + 1;
	Line left_wall(Point(0, 0), Point(0, 1)), right_wall(Point(w, 0), Point(w, 1));
	VV<R> dist(n + 2, V<R>(n + 2, INF));

	rep(i, n) {
		rep(j, i + 1, n) {
			auto &e = edges[i], &f = edges[j];
			R d = INF;
			foa(seg, e) foa(teg, f) { chmin(d, distance(seg, teg)); }
			dist[i][j] = dist[j][i] = d;
		}
	}

	rep(i, n) {
		R d = INF;
		foa(seg, edges[i]) { chmin(d, distance(left_wall, seg)); }
		dist[left_id][i] = dist[i][left_id] = d;

		d = INF;
		foa(seg, edges[i]) { chmin(d, distance(right_wall, seg)); }
		dist[right_id][i] = dist[i][right_id] = d;
	}

	dist[left_id][right_id] = w;

	pqup<pair<R, int>> q;
	q.emplace(0., left_id);

	debug(dist);

	V<R> res(n + 2, INF);
	res[left_id] = 0.;
	while(!q.empty()) {
		R d;
		int now;
		tie(d, now) = q.top();
		q.pop();
		if(d > res[now] + EPS) continue;

		debug(d, now);

		if(now == right_id) return d;

		rep(nxt, n + 2) {
			if(nxt == now) continue;
			if(chmin(res[nxt], d + dist[now][nxt])) {
				q.emplace(res[nxt], nxt);
			}
		}
	}

	return w;
}

int main() {
	std::ios::sync_with_stdio(false);
	std::cin.tie(nullptr);
	std::cout << std::fixed << std::setprecision(15);
	srand((unsigned)time(NULL));

	int n;
	while(cin >> n && n) {
		cout << solve(n) << dl;
	}

	return 0;
}
accuracy: 1
time_ms: 830
memory_kb: 4700
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef long long ll;
template<class T>bool chmax(T &a, const T &b) { if (a<b) { a=b; return true; } return false; }
template<class T>bool chmin(T &a, const T &b) { if (b<a) { a=b; return true; } return false; }
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define mp make_pair
#define si(x) int(x.size())
const int mod=1000000007,MAX=205,INF=1<<30;
//幾何ライブラリ

const double eps=1e-8;
const double pi=acos((double)-1.0L);
#define equals(a,b) (fabs((a)-(b))<eps)

double torad(double deg) {return (double)(deg)*pi/180.0;}
double todeg(double ang) {return ang*180.0/pi;}

class Point{
public:
    double x,y;
    
    Point(double x=0,double y=0):x(x),y(y){}
    
    Point operator + (Point p){return Point(x+p.x,y+p.y);}
    Point operator - (Point p){return Point(x-p.x,y-p.y);}
    Point operator * (double a){return Point(a*x,a*y);}
    Point operator / (double a){return Point(x/a,y/a);}
    
    double abs(){return sqrt(norm());}
    double norm(){return x*x+y*y;}
    
    bool operator < (const Point &p)const{
        return x+eps<p.x||(equals(x,p.x)&&y+eps<p.y);
    }
    
    bool operator == (const Point &p)const{
        return fabs(x-p.x)<eps/100000&&fabs(y-p.y)<eps/100000;
    }
};

typedef Point Vector;

double norm(Vector a){
    return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
    return sqrt(norm(a));
}

double dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y;
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

struct Segment{
    Point p1,p2;
};

bool isOrthogonal(Vector a,Vector b){
    return equals(dot(a,b),0.0);
}

bool isOrthogonal(Point a1,Point a2,Point b1,Point b2){
    return isOrthogonal(a1-a2,b1-b2);
}

bool isOrthogonal(Segment s1,Segment s2){
    return equals(dot(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

bool isParallel(Vector a,Vector b){
    return equals(cross(a,b),0.0);
}

bool isParallel(Point a1,Point a2,Point b1,Point b2){
    return isParallel(a1-a2,b1-b2);
}

bool isParallel(Segment s1,Segment s2){
    return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}

Point project(Segment s,Point p){
    Vector base=s.p2-s.p1;
    double r=dot(p-s.p1,base)/norm(base);
    return s.p1+base*r;
}

Point reflect(Segment s,Point p){
    return p+(project(s,p)-p)*2.0;
}

Point turn(Point p,Point c,double pi){
    double q=atan2(p.y-c.y,p.x-c.x);
    q+=pi;
    p=c+Point{cos(q)*abs(p-c),sin(q)*abs(p-c)};
    
    return p;
}
//pをcを中心としてpi回転させる(1周で2π)
//p=cのときnan

//p0,p1,p2の順に見たときどうなるか？

static const int counter_clockwise=1;
static const int clockwise=-1;
static const int online_back=2;
static const int online_front=-2;
static const int on_segment=0;

int ccw(Point p0,Point p1,Point p2){
    Vector a=p1-p0;
    Vector b=p2-p0;
    
    if(cross(a,b)>eps) return counter_clockwise;
    if(cross(a,b)<-eps) return clockwise;
    if(dot(a,b)<-eps) return online_back;
    if(a.norm()<b.norm()) return online_front;
    
    return on_segment;
}

bool intersect(Point p1,Point p2,Point p3,Point p4){
    return(ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0&&ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}

bool intersect(Segment s1,Segment s2){
    return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}

bool overlap(Segment s1,Segment s2){
    int a=ccw(s1.p1,s1.p2,s2.p1),b=ccw(s1.p1,s1.p2,s2.p2);
    if(a&1||b&1) return 0;
    if(a==2){
        if(b==-2||(b==0&&!(s2.p2==s1.p1))) return 1;
        else return 0;
    }
    if(a==-2){
        if(b==2||(b==0&&!(s2.p2==s1.p2))) return 1;
        else return 0;
    }
    if(a==0){
        if(s1.p1==s2.p1){
            if(b!=2) return 1;
            else return 0;
        }
        else if(s1.p2==s2.p1){
            if(b!=-2) return 1;
            else return 0;
        }
        else return 1;
    }
    return 0;
}
//s1とs2の共通の線分(長さ0より大きい)があるかどうか

typedef Segment Line;

double getDistance(Point a,Point b){
    return abs(a-b);
}

double getDistanceLP(Line l,Point p){
    return abs(cross(l.p2-l.p1,p-l.p1)/abs(l.p2-l.p1));
}

double getDistanceSP(Segment s,Point p){
    if(dot(s.p2-s.p1,p-s.p1)<0.0) return abs(p-s.p1);
    if(dot(s.p1-s.p2,p-s.p2)<0.0) return abs(p-s.p2);
    return getDistanceLP(s,p);
}

double getDistance(Segment s1,Segment s2){
    if(intersect(s1,s2)) return 0.0;
    return min({getDistanceSP(s1,s2.p1),getDistanceSP(s1,s2.p2),getDistanceSP(s2,s1.p1),getDistanceSP(s2,s1.p2)});
}

Point getCrossPointS(Segment s1,Segment s2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    Vector base=s2.p2-s2.p1;
    double d1=abs(cross(base,s1.p1-s2.p1));
    double d2=abs(cross(base,s1.p2-s2.p1));
    double t=d1/(d1+d2);
    return s1.p1+(s1.p2-s1.p1)*t;
}//同じ時壊れます

Point getCrossPointL(Line l1,Line l2){
    //if(ccw(s1.p1,s1.p2,s2.p1)==0&&ccw(s1.p1,s1.p2,s2.p2)==0) return s1.p1;
    
    Vector v1=l1.p2-l1.p1,v2=l2.p2-l2.p1;
    
    return l1.p1+v1*cross(v2,l2.p1-l1.p1)/cross(v2,v1);
}

Segment ParallelSegment(Segment s,double d){
    Vector v={-(s.p2-s.p1).y,(s.p2-s.p1).x};
    v=v/abs(v);
    
    s.p1=s.p1+v*d;
    s.p2=s.p2+v*d;
    
    return s;
}

Point naisin(Point p1,Point p2,Point p3){
    if(p1==p2&&p2==p3&&p3==p1) return p1;
    
    return (p1*abs(p2-p3)+p2*abs(p1-p3)+p3*abs(p1-p2))/(abs(p2-p3)+abs(p1-p3)+abs(p1-p2));
}

Point naisin(Line l1,Line l2,Line l3){
    //平行でない前提
    
    Point p1=getCrossPointL(l1,l2),p2=getCrossPointL(l1,l3),p3=getCrossPointL(l2,l3);
    return naisin(p1,p2,p3);
}

//ネットの適当を書いたのであってるか全く知りません→あってそう

class Circle{
public:
    Point c;
    double r;
    Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};

Point CircleCenter(Point a,Point b,Point c){
    Point u=a-b,v=a-c;
    double m1=(norm(a)-norm(b))/2.0,m2=(norm(a)-norm(c))/2.0;
    
    Point res;
    if(cross(u,v)==0.0){
        res.x=1e9;
        res.y=1e9;
        
        return res;
    }
    res.x=(m1*v.y-m2*u.y)/cross(u,v);
    res.y=(m1*v.x-m2*u.x)/cross(v,u);
    
    return res;
}
//3点を通る円の中心を返す

//交わる 0
// c1がc2のinside 1
// c1がc2のoutside 2
// 交わらない 3

int not_intersect(Circle c1,Circle c2){
    double d=getDistance(c1.c,c2.c);
    double r1=c1.r,r2=c2.r;
    if(r1<r2){
        if(d<(r2-r1)) return 1;
    }
    if(r1>r2){
        if(d<(r1-r2)) return 2;
    }
    if(d<=r1+r2) return 0;
    else return 3;
}

pair<Point,Point> segCrossPpoints(Circle c,Line l){
    //assert(intersect(c,l));
    Vector pr=project(l,c.c);
    Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
    double base=sqrt(c.r*c.r-norm(pr-c.c));
    return make_pair(pr+e*base,pr-e*base);
}

double arg(Vector p){return atan2(p.y,p.x);}
Vector polar(double a,double r){return Point(cos(r)*a,sin(r)*a);}

//inside(outside)

pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
    //assert(intersect(c1,c2));
    double d=abs(c1.c-c2.c);
    double a=acos((c1.r*c1.r+d*d-c2.r*c2.r)/(2*c1.r*d));
    double t=arg(c2.c-c1.c);
    return make_pair(c1.c+polar(c1.r,t+a),c1.c+polar(c1.r,t-a));
}

vector<Line> Commontangent(Circle c1,Circle c2){
    vector<Line> res;
    Point p=c2.c-c1.c;
    
    if(abs(p)>=(c1.r+c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r+c2.r)+p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r+c2.r)-p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r+c2.r)-p.y*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r+c2.r)+p.x*sqrt(norm(p)-(c1.r+c2.r)*(c1.r+c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    if(abs(p)>=abs(c1.r-c2.r)){
        Point a,b;
        a.x=c1.r*(p.x*(c1.r-c2.r)+p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        a.y=c1.r*(p.y*(c1.r-c2.r)-p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        b.x=c1.r*(p.x*(c1.r-c2.r)-p.y*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        b.y=c1.r*(p.y*(c1.r-c2.r)+p.x*sqrt(norm(p)-(c1.r-c2.r)*(c1.r-c2.r)))/norm(p);
        
        res.push_back(Line{a+c1.c,a+c1.c+Point{-a.y,a.x}});
        if(!(a==b)){
            res.push_back(Line{b+c1.c,b+c1.c+Point{-b.y,b.x}});
        }
    }
    
    return res;
}

typedef vector<Point> Polygon;

/*
 IN 2
 ON 1
 OUT 0
 */

int contains(Polygon g,Point p){
    int n=int(g.size());
    bool x=false;
    for(int i=0;i<n;i++){
        Point a=g[i]-p,b=g[(i+1)%n]-p;
        if(a.y>b.y) swap(a,b);
        if(a.y<eps&&0<b.y&&cross(a,b)<0) x=!x;
        if(abs(cross(a,b))<eps&&dot(a,b)<eps) return 1;
    }
    return (x?2:0);
}

Polygon andrewScan(Polygon s,bool ok){
    Polygon u,l;
    sort(all(s));
    
    if(int(s.size())<3) return s;
    int n=int(s.size());
    
    u.push_back(s[0]);
    u.push_back(s[1]);
    
    l.push_back(s[n-1]);
    l.push_back(s[n-2]);
    
    if(ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])==counter_clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])==counter_clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    if(!ok){
        for(int i=2;i<n;i++){
            for(int j=int(u.size());j>=2&&ccw(u[j-2],u[j-1],s[i])!=clockwise;j--){
                u.pop_back();
            }
            u.push_back(s[i]);
        }
        
        for(int i=int(s.size())-3;i>=0;i--){
            for(int j=int(l.size());j>=2&&ccw(l[j-2],l[j-1],s[i])!=clockwise;j--){
                l.pop_back();
            }
            l.push_back(s[i]);
        }
    }
    
    reverse(all(l));
    
    for(int i=int(u.size())-2;i>=1;i--) l.push_back(u[i]);
    
    return l;
}//ok==1なら辺の上も含める

Polygon convex_cut(const Polygon& P, const Line& l) {
    Polygon Q;
    for(int i=0;i<si(P);i++){
        Point A=P[i],B=P[(i+1)%si(P)];
        if(ccw(l.p1,l.p2,A)!=-1)Q.push_back(A);
        if(ccw(l.p1,l.p2,A)*ccw(l.p1,l.p2,B)<0) Q.push_back(getCrossPointL(Line{A,B},l));
    }
    return Q;
}

double area(Point a,Point b,Point c){
    b=b-a;
    c=c-a;
    return abs(b.x*c.y-b.y*c.x)/2.0;
}

double area(Polygon &P){
    if(si(P)==0) return 0.0;
    double res=0;
    Point c={0.0,0.0};
    for(int i=0;i<si(P);i++){
        c=c+P[i];
    }
    c=c/si(P);
    
    for(int i=0;i<si(P);i++){
        res+=area(c,P[i],P[(i+1)%si(P)]);
    }
    
    return res;
}

double dis[MAX][MAX];

int main(){
    
    std::ifstream in("text.txt");
    std::cin.rdbuf(in.rdbuf());
    cin.tie(0);
    ios::sync_with_stdio(false);
    
    while(1){
        int W,N;cin>>W>>N;
        if(W==0) break;
        vector<Polygon> P(N);
        int s=N,t=N+1;
        for(int i=0;i<N+2;i++) for(int j=0;j<N+2;j++) dis[i][j]=INF;
        for(int i=0;i<N;i++){
            int M;cin>>M;
            P[i].resize(M);
            for(int j=0;j<M;j++){
                cin>>P[i][j].x>>P[i][j].y;
                chmin(dis[s][i],P[i][j].x);
                chmin(dis[i][s],P[i][j].x);
                chmin(dis[t][i],W-P[i][j].x);
                chmin(dis[i][t],W-P[i][j].x);
            }
        }
        chmin(dis[s][t],(double)W);
        chmin(dis[t][s],(double)W);
        
        for(int i=0;i<N;i++){
            for(int j=0;j<N;j++){
                if(i==j){
                    dis[i][j]=0;
                    continue;
                }
                for(int a=0;a<si(P[i]);a++){
                    for(int b=0;b<si(P[j]);b++){
                        Segment s={P[j][b],P[j][(b+1)%si(P[j])]};
                        chmin(dis[i][j],getDistanceSP(s,P[i][a]));
                        
                        s={P[i][a],P[i][(a+1)%si(P[i])]};
                        chmin(dis[i][j],getDistanceSP(s,P[j][b]));
                    }
                }
            }
        }
        
        for(int k=0;k<N+2;k++){
            for(int i=0;i<N+2;i++){
                for(int j=0;j<N+2;j++){
                    chmin(dis[i][j],dis[i][k]+dis[k][j]);
                }
            }
        }
        
        cout<<fixed<<setprecision(25)<<dis[s][t]<<"\n";
    }
}
accuracy: 1
time_ms: 100
memory_kb: 3852
final_rank: 5

code_snippet: #include <bits/stdc++.h>
using namespace std;
const double INF = 10000000;
struct point{
  double x, y;
  point(){
  }
  point(double x, double y): x(x), y(y){
  }
  point operator -(point P){
    return point(x - P.x, y - P.y);
  }
};
double abs(point P){
  return sqrt(P.x * P.x + P.y * P.y);
}
double dist(point P, point Q){
  return abs(Q - P);
}
double dot(point P, point Q){
  return P.x * Q.x + P.y * Q.y;
}
double cross(point P, point Q){
  return P.x * Q.y - P.y * Q.x;
}
struct line{
  point A, B;
  line(point A, point B): A(A), B(B){
  }
};
point vec(line L){
  return L.B - L.A;
}
double point_line_distance(point P, line L){
  return abs(cross(P - L.A, vec(L))) / abs(vec(L));
}
double point_segment_distance(point P, line L){
  if (dot(P - L.A, vec(L)) < 0){
    return dist(P, L.A);
  } else if (dot(P - L.B, vec(L)) > 0){
    return dist(P, L.B);
  } else {
    return point_line_distance(P, L);
  }
}
double polygon_distance(vector<point> P1, vector<point> P2){
  int N = P1.size() - 1;
  int M = P2.size() - 1;
  double ans = INF;
  for (int i = 0; i < N; i++){
    for (int j = 0; j < M; j++){
      ans = min(ans, point_segment_distance(P1[i], line(P2[j], P2[j + 1])));
      ans = min(ans, point_segment_distance(P2[j], line(P1[i], P1[i + 1])));
    }
  }
  return ans;
}
int main(){
  cout << fixed << setprecision(20);
  while (true){
    int W, N;
    cin >> W >> N;
    if (W == 0 && N == 0){
      break;
    }
    vector<vector<point>> P(N + 2);
    P[0] = {point(0, 0), point(0, 10000), point(0, 0)};
    P[1] = {point(W, 0), point(W, 10000), point(W, 0)};
    for (int i = 2; i < N + 2; i++){
      int M;
      cin >> M;
      P[i] = vector<point>(M + 1);
      for (int j = 0; j < M; j++){
        cin >> P[i][j].x >> P[i][j].y;
      }
      P[i][M] = P[i][0];
    }
    vector<bool> used(N + 2, false);
    vector<double> d(N + 2, INF);
    d[0] = 0;
    for (int i = 0; i < N + 2; i++){
      int mn = -1;
      for (int j = 0; j < N + 2; j++){
        if (!used[j]){
          if (mn == -1){
            mn = j;
          } else if (d[j] < d[mn]){
            mn = j;
          }
        }
      }
      used[mn] = true;
      for (int j = 0; j < N + 2; j++){
        double dd = polygon_distance(P[mn], P[j]);
        d[j] = min(d[j], d[mn] + dd);
      }
    }
    cout << d[1] << endl;
  }
}
accuracy: 1
time_ms: 70
memory_kb: 3240
final_rank: 2