#include <algorithm>
#include <iostream>
#include <string>
#include <random>
#include <cassert>
#include <cstring>
#include <chrono>
#include <set>
#include <map>

using namespace std;


typedef long long ll;

typedef double D;
const D eps = 1E-8;

template<typename T>
T sqr(T x) {
  return x * x;
}

struct P {
  D x, y;
  P(D x = 0.0, D y = 0.0) : x(x), y(y) {}
  P operator +(const P& a) const {
    return P(x + a.x, y + a.y);
  }
  P operator -(const P &a) const {
    return P(x - a.x, y - a.y);
  }
  P operator *(D k) {
    return P(x * k, y * k);
  }
  D operator *(const P &a) const {
    return x * a.y - y * a.x;
  }
  D operator ^(const P &a) const {
    return x * a.x + y * a.y;
  }
  D Len() {
    return sqrt(x * x + y * y);
  }
  P Perp() {
    return P(y, -x);
  }
  P Norm() {
    D l = Len();
    return abs(l) < eps ? P(x, y) : P(x / l, y / l);
  }
  bool operator ==(const P &a) const {
    return abs(x - a.x) < eps && abs(y - a.y) < eps;
  }
  void Load() {
    cin >> x >> y;
  }
};

int sgn(D x)
{
  if (x > eps) return 1;
  if (x < -eps) return -1;
  return 0;
}

bool PointOnSegment(P p, P a, P b) {
  if (abs((a - p) * (b - p)) > eps)
    return false;
  return ((a - p) ^ (b - p)) < eps;
}

bool CrossSegments1d(D a, D aa, D b, D bb) {
  return min(a, aa) < max(b, bb) + eps && min(b, bb) < max(a, aa) + eps;
}

bool CrossSegments(P a, P aa, P b, P bb) {
  if (sgn((b - a) * (aa - a)) * sgn((aa - a) * (bb - a)) < 0)
    return false;
  if (sgn((a - b) * (bb - b)) * sgn((bb - b) * (aa - b)) < 0)
    return false;
  return CrossSegments1d(a.x, aa.x, b.x, bb.x) && CrossSegments1d(a.y, aa.y, b.y, bb.y);
}

struct L {
  D a, b, c;
  L(D a = 0.0, D b = 0.0, D c = 0.0): a(a), b(b), c(c) {}
};

L GetLine(P p1, P p2) {
  D x0 = p1.x, y0 = p1.y;
  D al = (p2 - p1).x, be = (p2 - p1).y;
  return L(be, -al, al * y0 - be * x0);
}

P GetPoint(L l1, L l2) {
  D det = l1.a * l2.b - l1.b * l2.a;
  D det1 = -(l1.c * l2.b - l1.b * l2.c);
  D det2 = -(l1.a * l2.c - l1.c * l2.a);
  return P(det1 / det, det2 / det);
}

struct C {
  P o;
  D r;
  C() {}
  C(P o, D r): o(o), r(r) {}
};

vector<P> CrossCircleAndLine(C c, L l) {
  vector<P> res;
  D al = l.b, be = -l.a, x0, y0;
  if (abs(l.a) < eps) {
    x0 = 0;
    y0 = -l.c / l.b;
  } else {
    y0 = 0;
    x0 = -l.c / l.a;
  }
  D A, B, C, t;
  A = sqr(al) + sqr(be);
  B = 2 * al * (x0 - c.o.x) + 2 * be * (y0 - c.o.y);
  C = sqr(x0 - c.o.x) + sqr(y0 - c.o.y) - sqr(c.r);
  D d = B * B - 4 * A * C;
  if (d < -eps) return res;
  if (d < 0) d = 0;
  t = (-B + sqrt(d)) / (2 * A);
  res.push_back(P(x0 + al * t,y0 + be * t));
  t = (-B - sqrt(d)) / (2 * A);
  res.push_back(P(x0 + al * t, y0 + be * t));
  return res;
}

vector<P> CrossTwoCircles(C c1, C c2) {
  D a, b, c;
  a = 2 * (c2.o.x - c1.o.x);
  b = 2 * (c2.o.y - c1.o.y);
  c = sqr(c2.r) - sqr(c1.r) + sqr(c1.o.x) - sqr(c2.o.x) + sqr(c1.o.y) - sqr(c2.o.y);
  return CrossCircleAndLine(c1, L(a, b, c));
}



bool Check(vector<P> p, const vector<double>& c, double t, int k) {
  int n = p.size();
  vector<C> circles(n);
  for (int i = 0; i < n; ++i) circles[i] = C(p[i], t / c[i]);
  vector<P> candidates = p;
  for (int i = 0; i < n; ++i) for (int j = i + 1; j < n; ++j) {
    vector<P> cr = CrossTwoCircles(circles[i], circles[j]);
    for (P cur : cr) candidates.push_back(cur);
  }
  for (P cur : candidates) {
    int cnt = 0;
    for (C circle : circles) {
      if ((circle.o - cur).Len() < circle.r + 1e-8) cnt++;
    }
    if (cnt >= k) return true;
  }
  return false;
}

int main()
{
  int n, k;
  cin >> n >> k;
  vector<P> p(n);
  vector<double> c(n);
  for (int i = 0; i < n; ++i) {
    p[i].Load();
    cin >> c[i];
  }
  double l = 0;
  double r = 1e10;
  while (r - l > 1e-9) {
    double m = (l + r) / 2;
    if (Check(p, c, m, k)) r = m; else l =m ;
  }
  printf("%.10lf\n", l);
  return 0;
}


Measured memory_bytes: 384