#include <cmath>
#include <utility>
#include <queue>
#include <limits>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <iostream>
namespace lc {
template <class WeightType>
struct EdgeWithWeight {
	int to;
	WeightType weight;
	EdgeWithWeight() : to(0), weight() { }
	EdgeWithWeight(int to, const WeightType &weight)
		: to(to), weight(weight)
	{ }
};
}
namespace lc {
template <typename EdgeType>
class AdjacencyList {
public:
	typedef std::vector<EdgeType> ListType;
private:
	std::vector<ListType> m_lists;
public:
	explicit AdjacencyList(int n = 0)
		: m_lists(n)
	{ }
	int size() const { return m_lists.size(); }
	template <typename... Args>
	void add_edge(int u, Args&&... args){
		m_lists[u].emplace_back(args...);
	}
	const ListType &operator[](int u) const { return m_lists[u]; }
};
}
namespace lc {
template <typename EdgeType>
auto sssp_dijkstra(int source, const AdjacencyList<EdgeType> &graph)
	-> std::vector<decltype(EdgeType().weight)>
{
	typedef decltype(EdgeType().weight) weight_type;
	typedef std::pair<weight_type, int> weighted_pair;
	const auto inf = std::numeric_limits<weight_type>::max();
	const int n = graph.size();
	std::vector<weight_type> result(n, inf);
	std::priority_queue<weighted_pair, std::vector<weighted_pair>, std::greater<weighted_pair>> pq;
	result[source] = weight_type();
	pq.push(std::make_pair(result[source], source));
	while(!pq.empty()){
		const auto d = pq.top().first;
		const auto u = pq.top().second;
		pq.pop();
		if(result[u] < d){ continue; }
		for(const auto &e : graph[u]){
			const auto v = e.to;
			const auto w = e.weight;
			if(d + w < result[v]){
				result[v] = d + w;
				pq.push(std::make_pair(result[v], v));
			}
		}
	}
	return result;
}
}
namespace lc {
static const double EPS = 1e-9;
}
namespace lc {
struct Point {
	double x;
	double y;
	explicit Point(const double &x = 0.0, const double &y = 0.0) :
		x(x), y(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*(double s) const { return Point(x * s, y * s); }
	double abs() const { return sqrt(x * x + y * y); }
	double norm() const { return x * x + y * y; }
};
inline Point operator*(double s, const Point &p){ return p * s; }
inline double cross(const Point &a, const Point &b){
	return a.x * b.y - a.y * b.x;
}
inline double dot(const Point &a, const Point &b){
	return a.x * b.x + a.y * b.y;
}
inline int ccw(const Point &a, const Point &b, const Point &c){
	Point d = b - a, e = c - a;
	if(cross(d, e) > 0.0){ return 1; }
	if(cross(d, e) < 0.0){ return -1; }
	if(dot(d, e) < 0.0){ return 2; }
	if(d.abs() < e.abs()){ return -2; }
	return 0;
}
}
namespace lc {
struct Line {
	Point a;
	Point b;
	explicit Line(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Point projection(const Point &p) const {
		double t = dot(p - a, b - a) / (b - a).norm();
		return a + t * (b - a);
	}
};
}
namespace lc {
struct Segment {
	Point a;
	Point b;
	explicit Segment(const Point &a = Point(), const Point &b = Point()) :
		a(a), b(b)
	{ }
	Line to_line() const { return Line(a, b); }
};
}
namespace lc {
class Polygon {
private:
	std::vector<Point> m_points;
public:
	Polygon() : m_points() { }
	explicit Polygon(size_t s, const Point &p = Point())
		: m_points(s, p)
	{ }
	Point &operator[](int i){ return m_points[i]; }
	Segment side(int i) const {
		return Segment(m_points[i], m_points[(i + 1) % m_points.size()]);
	}
	int size() const { return static_cast<int>(m_points.size()); }
};
}
namespace lc {
inline bool intersect(const Point &a, const Segment &b){
	return (b.a - a).abs() + (b.b - a).abs() - (b.b - b.a).abs() < EPS;
}
inline bool intersect(const Segment &a, const Point &b){
	return intersect(b, a);
}
inline bool intersect(const Segment &a, const Segment &b){
	if(ccw(a.a, a.b, b.a) * ccw(a.a, a.b, b.b) > 0){ return false; }
	if(ccw(b.a, b.b, a.a) * ccw(b.a, b.b, a.b) > 0){ return false; }
	return true;
}
}
namespace lc {
inline double distance(const Point &a, const Segment &b){
	const Point p = b.to_line().projection(a);
	if(intersect(b, p)){ return (a - p).abs(); }
	return std::min((b.a - a).abs(), (b.b - a).abs());
}
inline double distance(const Segment &a, const Segment &b){
	if(intersect(a, b)){ return 0.0; }
	const double x = std::min(distance(a.a, b), distance(a.b, b));
	const double y = std::min(distance(b.a, a), distance(b.b, a));
	return std::min(x, y);
}
}
using namespace std;
typedef lc::EdgeWithWeight<double> Edge;
int main(){
	ios_base::sync_with_stdio(false);
	cout << setiosflags(ios::fixed) << setprecision(10);
	const double inf = numeric_limits<double>::infinity();
	while(true){
		int w, n;
		cin >> w >> n;
		if(w == 0 && n == 0){ break; }
		vector<lc::Polygon> piles(n);
		for(int i = 0; i < n; ++i){
			int m;
			cin >> m;
			piles[i] = lc::Polygon(m);
			for(int j = 0; j < m; ++j){
				cin >> piles[i][j].x >> piles[i][j].y;
			}
		}
		lc::AdjacencyList<Edge> graph(n + 2);
		const int source = n, sink = n + 1;
		graph.add_edge(source, sink, w);
		graph.add_edge(sink, source, w);
		for(int i = 0; i < n; ++i){
			const int m = piles[i].size();
			double left = inf, right = inf;
			for(int j = 0; j < m; ++j){
				left = min(left, piles[i][j].x);
				right = min(right, w - piles[i][j].x);
			}
			graph.add_edge(source, i, left);
			graph.add_edge(i, source, left);
			graph.add_edge(sink, i, right);
			graph.add_edge(i, sink, right);
			for(int j = i + 1; j < n; ++j){
				const int r = piles[j].size();
				double d = inf;
				for(int k = 0; k < m; ++k){
					for(int l = 0; l < r; ++l){
						d = min(d, lc::distance(
							piles[i].side(k), piles[j].side(l)));
					}
				}
				graph.add_edge(i, j, d);
				graph.add_edge(j, i, d);
			}
		}
		cout << lc::sssp_dijkstra(source, graph)[sink] << endl;
	}
	return 0;
}

Measured memory_bytes: 2528