// Nikita Golikov, 2023 #include using namespace std; using uint = unsigned int; using ll = long long; using ull = unsigned long long; #ifdef GOLIKOV #include "/Users/golikovnik/contests/debug.h" #else #define debug(...) ; #endif template bool smin(A& x, B&& y) { if (y < x) { x = y; return true; } return false; } template bool smax(A& x, B&& y) { if (x < y) { x = y; return true; } return false; } template struct Point { T x{}, y{}; Point() = default; Point(T x_, T y_) : x(x_), y(y_) {} Point operator+(const Point& other) const { return Point(x + other.x, y + other.y); } Point operator-(const Point& other) const { return Point(x - other.x, y - other.y); } Point operator+() const { return *this; } Point operator-() const { return Point(-x, -y); } Point operator*(T k) const { return Point(x * k, y * k); } Point operator/(T k) const { return Point(x / k, y / k); } T operator*(const Point& other) const { return x * other.x + y * other.y; } T operator%(const Point& other) const { return x * other.y - y * other.x; } T lenSqr() const { return x * x + y * y; } double len() const { return sqrt(lenSqr()); } T distSqr(const Point& other) const { return (other - *this).lenSqr(); } double dist(const Point& other) const { return sqrt(distSqr(other)); } Point norm() const { return *this / len(); } // Counterclockwise rotation by 90 degrees Point ort() const { return Point(-y, x); } // Counterclockwise rotation by c = cos(alpha), s = sin(alpha) Point rot(double c, double s) const { return *this * c + ort() * s; } // Counterclockwise rotation by alpha Point rot(double alpha) const { return rot(cos(alpha), sin(alpha)); } double arg() const { return atan2(y, x); } friend istream& operator>>(istream& in, Point& p) { return in >> p.x >> p.y; } friend ostream& operator<<(ostream& out, Point p) { return out << p.x << ' ' << p.y; } bool up() const { return y > 0 || (y == 0 && x >= 0); } bool operator==(Point const& other) const { return x == other.x && y == other.y; } bool operator!=(Point const& other) const { return x != other.x || y != other.y; } static auto angleCmp(Point O) { return [O](Point x, Point y) { x = x - O; y = y - O; auto d = x.up() - y.up(); if (d == 0) { auto vmul = x % y; return vmul == 0 ? x.lenSqr() < y.lenSqr() : vmul > 0; } return d < 0; }; } static auto angleCmp() { return angleCmp(Point()); } bool operator<(Point const& other) const { return tie(x, y) < tie(other.x, other.y); } friend bool ccw(Point A, Point B, Point C) { return (B - A) % (C - A) >= 0; } // polygon ccw friend bool insidePolygon(vector const& p, Point O) { for (int i = 0; i < int(p.size()); ++i) { if (!ccw(O, p[i], p[(i + 1) % int(p.size())])) return false; } return true; } }; int main() { #ifdef GOLIKOV assert(freopen("in", "rt", stdin)); auto _clock_start = chrono::high_resolution_clock::now(); #endif ios::sync_with_stdio(false); cin.tie(nullptr); using ld = double; using P = Point; ld X; cin >> X; int n; cin >> n; vector

a(n); for (auto& [x, y] : a) { int xx, yy; cin >> xx >> yy; x = xx; y = yy; } ld ans = X; vector pref(n); int const ITERS = 50; auto updateAns = [&](int i, int j, ld at, ld skip) { debug(i, j, at, skip); assert(i < n - 1 && j < n - 1); auto di = (a[i + 1] - a[i]).norm(); auto dj = (a[j + 1] - a[j]).norm(); auto pi = a[i] + di * (at - pref[i]); auto pj = a[j] + dj * (at + X - pref[j]); auto eval = [&](ld t) { return (pi + di * t).dist(pj + dj * t); }; ld left = 0; ld right = skip; for (int iter = 0; iter < ITERS; ++iter) { ld m1 = left + (right - left) / 3; ld m2 = right - (right - left) / 3; if (eval(m1) < eval(m2)) { right = m2; } else { left = m1; } } smin(ans, eval((left + right) / 2)); }; for (int i = 0; i < n - 1; ++i) { pref[i + 1] = pref[i] + a[i].dist(a[i + 1]); } ld curT = 0; int curFirst = 0; int curSecond = 0; while (curSecond + 1 < n && pref[curSecond + 1] <= X) { ++curSecond; } ld const eps = 1e-9; while (curSecond < n - 1) { ld d2 = max(ld(0), pref[curSecond + 1] - (curT + X)); ld d1 = max(ld(0), pref[curFirst + 1] - curT); ld distNext = min(d1, d2); updateAns(curFirst, curSecond, curT, distNext); curT += distNext; if (fabs(distNext - d1) < eps) { ++curFirst; } if (fabs(distNext - d2) < eps) { ++curSecond; } } cout << setprecision(12) << fixed << ans << '\n'; #ifdef GOLIKOV cerr << "Executed in " << chrono::duration_cast( chrono::high_resolution_clock::now() - _clock_start).count() << "ms." << endl; #endif return 0; }