#include <bits/stdc++.h>
using namespace std;
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  os << '{';
  string sep;
  for (const auto &x : v) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename T, size_t size>
ostream &operator<<(ostream &os, const array<T, size> &arr) {
  os << '{';
  string sep;
  for (const auto &x : arr) os << sep << x, sep = ", ";
  return os << '}';
}
template <typename A, typename B>
ostream &operator<<(ostream &os, const pair<A, B> &p) {
  return os << '(' << p.first << ", " << p.second << ')';
}
void dbg_out() { cerr << endl; }
template <typename Head, typename... Tail>
void dbg_out(Head H, Tail... T) {
  cerr << ' ' << H;
  dbg_out(T...);
}
const bool CHECK_OVERFLOW64 = false;
struct point {
  int64_t x, y;
  point() : x(0), y(0) {}
  point(int64_t _x, int64_t _y) : x(_x), y(_y) {}
  point &operator+=(const point &other) {
    x += other.x;
    y += other.y;
    return *this;
  }
  point &operator-=(const point &other) {
    x -= other.x;
    y -= other.y;
    return *this;
  }
  point &operator*=(int64_t mult) {
    x *= mult;
    y *= mult;
    return *this;
  }
  point operator+(const point &other) const { return point(*this) += other; }
  point operator-(const point &other) const { return point(*this) -= other; }
  point operator*(int64_t mult) const { return point(*this) *= mult; }
  bool operator==(const point &other) const {
    return x == other.x && y == other.y;
  }
  bool operator!=(const point &other) const { return !(*this == other); }
  point operator-() const { return point(-x, -y); }
  point rotate90() const { return point(-y, x); }
  int64_t norm() const { return (int64_t)x * x + (int64_t)y * y; }
  long double dist() const { return sqrt((long double)norm()); }
  bool top_half() const { return y > 0 || (y == 0 && x > 0); }
  friend ostream &operator<<(ostream &os, const point &p) {
    return os << '(' << p.x << ", " << p.y << ')';
  }
};
int64_t cross(const point &a, const point &b) {
  return (int64_t)a.x * b.y - (int64_t)b.x * a.y;
}
int64_t dot(const point &a, const point &b) {
  return (int64_t)a.x * b.x + (int64_t)a.y * b.y;
}
int cross_sign(const point &a, const point &b) {
  if (CHECK_OVERFLOW64) {
    long double double_value = (long double)a.x * b.y - (long double)b.x * a.y;
    if (abs(double_value) > 1e18) return double_value > 0 ? +1 : -1;
  }
  uint64_t uint64_value = (uint64_t)a.x * b.y - (uint64_t)b.x * a.y;
  if (uint64_value == 0) return 0;
  return uint64_value >> 63 ? -1 : +1;
}
bool left_turn_strict(const point &a, const point &b, const point &c) {
  return cross_sign(b - a, c - a) > 0;
}
bool left_turn_lenient(const point &a, const point &b, const point &c) {
  return cross_sign(b - a, c - a) >= 0;
}
bool collinear(const point &a, const point &b, const point &c) {
  return cross_sign(b - a, c - a) == 0;
}
int64_t area_signed_2x(const point &a, const point &b, const point &c) {
  return cross(b - a, c - a);
}
long double distance_to_line(const point &p, const point &a, const point &b) {
  assert(a != b);
  return abs(area_signed_2x(p, a, b)) / (a - b).dist();
}
int64_t manhattan_dist(const point &a, const point &b) {
  return (int64_t)abs(a.x - b.x) + abs(a.y - b.y);
}
int64_t infinity_norm_dist(const point &a, const point &b) {
  return max(abs(a.x - b.x), abs(a.y - b.y));
}
bool yx_compare(const point &a, const point &b) { return (b - a).top_half(); }
bool angle_compare(const point &a, const point &b) {
  if (a.top_half() ^ b.top_half()) return a.top_half();
  return cross_sign(a, b) > 0;
}
using my_float = double;
const my_float FLOAT_INF = 1e30;
struct segment {
  my_float maximum;
  int index;
  segment(my_float _maximum = numeric_limits<my_float>::lowest(),
          int _index = -1)
      : maximum(_maximum), index(_index) {}
  void join(const segment &other) {
    if (other.maximum > maximum) {
      maximum = other.maximum;
      index = other.index;
    }
  }
  void join(const segment &a, const segment &b) {
    *this = a;
    join(b);
  }
};
int right_half[32];
struct basic_seg_tree {
  static const bool POWER_OF_TWO_MODE = true;
  int tree_n = 0;
  vector<segment> tree;
  basic_seg_tree(int n = -1) {
    if (n >= 0) init(n);
  }
  void init(int n) {
    if (POWER_OF_TWO_MODE) {
      tree_n = 1;
      while (tree_n < n) tree_n *= 2;
    } else {
      tree_n = n;
    }
    tree.assign(2 * tree_n, segment());
  }
  void build(const vector<segment> &initial) {
    int n = int(initial.size());
    init(n);
    assert(n <= tree_n);
    for (int i = 0; i < n; i++) tree[tree_n + i] = initial[i];
    for (int position = tree_n - 1; position > 0; position--)
      tree[position].join(tree[2 * position], tree[2 * position + 1]);
  }
  segment query(int a, int b) const {
    assert(0 <= a && a <= b && b <= tree_n);
    segment answer;
    int r_size = 0;
    for (a += tree_n, b += tree_n; a < b; a /= 2, b /= 2) {
      if (a & 1) answer.join(tree[a++]);
      if (b & 1) right_half[r_size++] = --b;
    }
    for (int i = r_size - 1; i >= 0; i--) answer.join(tree[right_half[i]]);
    return answer;
  }
  segment query_single(int index) const {
    assert(0 <= index && index < tree_n);
    return tree[tree_n + index];
  }
  void join_up(int position) {
    while (position > 1) {
      position /= 2;
      tree[position].join(tree[2 * position], tree[2 * position + 1]);
    }
  }
  void update(int index, const segment &seg) {
    assert(0 <= index && index < tree_n);
    int position = tree_n + index;
    tree[position] = seg;
    join_up(position);
  }
};
int N, K, R;
vector<point> points;
vector<int> ray_start;
int main() {
  ios::sync_with_stdio(false);
  cin.tie(nullptr);
  cout << setprecision(16);
  cin >> N >> K;
  points.resize(N);
  for (point &p : points) cin >> p.x >> p.y;
  for (point &p : points)
    if (p.x == 0 && p.y == 0) swap(p, points.front());
  sort(points.begin() + 1, points.end(), angle_compare);
  ray_start = {0, 1};
  for (int i = 1, j = 1; i < N; i = j) {
    while (j < N && !angle_compare(points[i], points[j])) j++;
    sort(points.begin() + i, points.begin() + j,
         [&](const point &p, const point &q) { return p.norm() < q.norm(); });
    ray_start.push_back(j);
  };
  R = int(ray_start.size()) - 1;
  vector<my_float> dist(N);
  for (int i = 0; i < N; i++) dist[i] = my_float(points[i].dist());
  vector<my_float> ray_prefix(N, 0);
  vector<int> which_ray(N, -1);
  for (int r = 0; r < R; r++) {
    my_float sum = 0;
    for (int i = ray_start[r]; i < ray_start[r + 1]; i++) {
      sum += dist[i];
      ray_prefix[i] = sum;
      which_ray[i] = r;
    }
  }
  vector<segment> initial(N);
  for (int i = 0; i < N; i++) initial[i] = segment(-FLOAT_INF, i);
  vector<int> ray_first(R), ray_last(R);
  for (int r = 0; r < R; r++) {
    int first = ray_start[r], last = ray_start[r + 1] - 1;
    ray_first[r] = first;
    ray_last[r] = last;
    initial[first] = segment((K - 1) * dist[first], first);
    initial[last] = segment((K - 1) * dist[last], last);
  }
  basic_seg_tree tree(N);
  tree.build(initial);
  my_float answer = 0;
  for (int k = 0; k < K; k++) {
    segment seg = tree.tree[1];
    ;
    answer += seg.maximum;
    int index = seg.index;
    assert(index >= 0);
    tree.update(index, segment());
    int r = which_ray[index];
    ;
    if (index == ray_first[r]) ray_first[r]++;
    if (index == ray_last[r]) ray_last[r]--;
    if (ray_first[r] <= ray_last[r]) {
      int first = ray_first[r];
      int last = ray_last[r];
      my_float before_sum = first == ray_start[r] ? 0 : ray_prefix[first - 1];
      int after = ray_start[r + 1] - last - 1;
      ;
      ;
      tree.update(
          first,
          segment((K - 1 - 2 * after) * dist[first] - 2 * before_sum, first));
      tree.update(
          last,
          segment((K - 1 - 2 * after) * dist[last] - 2 * before_sum, last));
    }
  }
  cout << answer << '\n';
}
