#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 vector<double> VD;

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+(P a) {
return P(x + a.x, y + a.y);
}
P operator-(P a) {
return P(x - a.x, y - a.y);
}
P operator*(D k) {
return P(x * k, y * k);
}
D operator *(P a) {
return x * a.y - y * a.x;
}
D operator ^(P a) {
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==(P a) {
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, VD 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-7) 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