#include <bits/stdc++.h>
using namespace std;
const int maxn = 300007;
const double eps = 1e-9;
int n, m;
double C;
inline int Read() {
  register int ch, a, flag;
  while (ch = getchar(), (ch < '0' || ch > '9') && (ch != '-'))
    ;
  flag = (ch == '-');
  a = flag ? 0 : ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9')
    a = (a << 1) + (a << 3) + ch - '0';
  a = flag ? -a : a;
  return a;
}
inline int dcmp(double a) {
  if (fabs(a) <= eps) return 0;
  return a < 0 ? -1 : 1;
}
struct Point {
  double x, y;
  Point(double a = 0, double b = 0) { x = a, y = b; }
  bool operator==(const Point &A) const {
    return dcmp(x - A.x) == 0 && dcmp(y - A.y) == 0;
  }
};
inline Point operator+(const Point &A, const Point &B) {
  return Point(A.x + B.x, A.y + B.y);
}
inline Point operator-(const Point &A, const Point &B) {
  return Point(A.x - B.x, A.y - B.y);
}
inline Point operator*(const Point &A, const double &d) {
  return Point(A.x * d, A.y * d);
}
inline Point operator/(const Point &A, const double &d) {
  return Point(A.x / d, A.y / d);
}
inline double Dot(const Point &A, const Point &B) {
  return A.x * B.x + A.y * B.y;
}
inline double Cross(const Point &A, const Point &B) {
  return A.x * B.y - A.y * B.x;
}
inline double Length(const Point &A) { return sqrt(A.x * A.x + A.y * A.y); }
struct Segment {
  double len;
  Point v;
  Point p;
  inline Point Trans(double t) { return p + v * t; }
} s[maxn];
struct Pos {
  int id;
  Point p;
} p[maxn];
struct Func {
  double a, b, c;
  double be, ed;
  Func() {}
  Func(double s, double t, double q, double w, double e) {
    be = s, ed = t, a = q, b = w, c = e;
  }
};
vector<Func> f[maxn];
double ti[maxn << 1];
int tot;
bool cmp(const double &a, const double &b) { return dcmp(a - b) <= 0; }
void Load(int a, int b) {
  double be = -Length(p[a].p - s[p[a].id].p), ed;
  ti[++tot] = 0;
  double Rem = C / m - be;
  for (int i = p[a].id; i != p[b].id; i = i % n + 1) {
    ed = be + s[i].len;
    ti[++tot] = ed;
    be = ed;
    Rem -= s[i].len;
  }
  ti[++tot] = be + Rem;
}
void Insert(int a, int b, int c) {
  tot = 0;
  Load(a, b), Load(b, c);
  sort(ti + 1, ti + 1 + tot);
  tot = unique(ti + 1, ti + 1 + tot) - (ti + 1);
  Point A = p[a].p, B = p[b].p;
  int ida = p[a].id, idb = p[b].id;
  for (int i = 1; i < tot; i++) {
    double al = A.x - B.x, bt = s[ida].v.x - s[idb].v.x, gm = A.y - B.y,
           om = s[ida].v.y - s[idb].v.y;
    double alpha = bt * bt + om * om, beta = 2 * (al * bt + gm * om),
           gama = al * al + gm * gm;
    f[a].push_back(Func(ti[i], ti[i + 1] - ti[i], alpha, beta, gama));
    A = A + s[ida].v * (ti[i + 1] - ti[i]);
    B = B + s[idb].v * (ti[i + 1] - ti[i]);
    if (A == s[ida % n + 1].p) ida = ida % n + 1;
    if (B == s[idb % n + 1].p) idb = idb % n + 1;
  }
}
void Initation() {
  double dlt = C / m;
  p[1].p = s[1].p, p[1].id = 1;
  int j = 1;
  double rem = 0;
  for (int i = 2; i <= m; i++) {
    rem += dlt;
    while (dcmp(rem - s[j].len) >= 0) rem -= s[j++].len;
    p[i].id = j;
    p[i].p = s[j].Trans(rem);
  }
  for (int i = 1; i <= m; i++) Insert(i, i % m + 1, (i % m + 1) % m + 1);
}
struct Arr {
  double L, R;
} A[maxn << 1], B[maxn << 1];
int Ta, Tb;
inline Arr Calc(Func F, double R) {
  double A = F.a, B = F.b, C = F.c - R * R, le, ri;
  if (dcmp(A) == 0) {
    if (dcmp(B) < 0)
      le = 0, ri = -C / B;
    else if (dcmp(B) == 0) {
      if (C > 0) return (Arr){1, -1};
      le = 0, ri = F.ed;
    } else
      le = -C / B, ri = F.ed;
  } else {
    double dlt = B * B - 4 * A * C;
    if (dcmp(dlt) < 0) return (Arr){1, -1};
    dlt = sqrt(dlt + eps);
    le = (-B - dlt) / (2 * A), ri = (-B + dlt) / (2 * A);
    if (le > ri) swap(le, ri);
  }
  le = max(le, (double)0);
  ri = min(ri, F.ed);
  if (le > ri) return (Arr){1, -1};
  return (Arr){le + F.be, ri + F.be};
}
void Add(Arr *s, int &Top, int id, double R) {
  Top = 0;
  for (int i = 0; i < f[id].size(); i++) {
    Arr t = Calc(f[id][i], R);
    if (t.R < 0) continue;
    if (Top && dcmp(s[Top].R - t.L) >= 0)
      s[Top].R = t.R;
    else
      s[++Top] = t;
  }
}
Arr tmp[maxn << 1];
int Top;
void Merge() {
  Top = 0;
  int i = 1, j = 1, k = 0;
  double L, R;
  while (i <= Ta && j <= Tb) {
    L = max(A[i].L, B[j].L), R = min(A[i].R, B[j].R);
    if (L < R) tmp[++Top] = (Arr){L, R};
    if (A[i].R >= B[j].R)
      j++;
    else
      i++;
  }
  memcpy(A, tmp, sizeof(Arr) * (Top + 3));
  Ta = Top;
}
bool Check(double mid) {
  Add(A, Ta, 1, mid);
  if (!Ta) return 0;
  for (int i = 2; i <= m; i++) {
    Add(B, Tb, i, mid);
    Merge();
    if (!Ta) return 0;
  }
  return 1;
}
int main() {
  n = Read(), m = Read();
  for (int i = 1; i <= n; i++) s[i].p.x = Read(), s[i].p.y = Read();
  for (int i = 1; i < n; i++) {
    s[i].v = s[i + 1].p - s[i].p, s[i].len = Length(s[i].v);
    s[i].v = s[i].v / s[i].len;
    C += s[i].len;
  }
  s[n].v = s[1].p - s[n].p, s[n].len = Length(s[n].v);
  s[n].v = s[n].v / s[n].len;
  C += s[n].len;
  Initation();
  double le = 0, ri = 6666, mid;
  for (int r = 1; r <= 100; r++) {
    mid = (le + ri) / 2;
    if (!Check(mid))
      le = mid;
    else
      ri = mid;
  }
  printf("%.10f\n", mid);
  return 0;
}
