#include<cmath>
#include<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>

#ifdef LOCAL
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#else
#define NDEBUG
#define eprintf(...) do {} while (0)
#endif
#include<cassert>

using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}
namespace GEOMETRY {

using Double = long double;
const Double EPS = 1e-8;
const Double INF = 1e20;
const Double PI = acos((Double)(-1));

int sgn(Double x) {
    return x < -EPS? -1: x > EPS? 1: 0;
}

int cmp(Double x, Double y) {
    return sgn(x-y);
}

Double sq(Double x) { return x*x; }

//////////////////////////////////////////////////
// Point
//////////////////////////////////////////////////
struct Point {
    Double x, y;

    Point(): x(), y() { }
    Point(const Double x_, const Double y_): x(x_), y(y_) { }

    double fx() const { return (double)x; }
    double fy() const { return (double)y; }
    Double& real() { return x; }
    Double& imag() { return y; }
    const Double& real() const { return x; }
    const Double& imag() const { return y; }

    Point& operator+=(const Point &o) { x += o.x; y += o.y; return *this; }

    Point& operator-=(const Point &o) { x -= o.x; y -= o.y; return *this; }

    Point& operator*=(const Point &o) {
	const Double tmp = x * o.x - y * o.y;
	y = x * o.y + y * o.x;
	x = tmp;
	return *this;
    }

    Point& operator/=(const Point &o) {
	const Double tmp = x * o.x + y * o.y;
	const Double n = sq(o.x) + sq(o.y);
	y = (y * o.x - x * o.y) / n;
	x = tmp / n;
	return *this;
    }

    Point& operator*=(Double o) { x *= o; y *= o; return *this; }

    Point& operator/=(Double o) { x /= o; y /= o; return *this; }
    
    Point operator+(const Point &b) const { return Point(*this) += b; }
    Point operator-(const Point &b) const { return Point(*this) -= b; }
    Point operator-() const { return Point(-x, -y); }
    Point operator*(const Point &b) const { return Point(*this) *= b; }
    Point operator/(const Point &b) const { return Point(*this) /= b; }

    Point operator*(Double b) const { return Point(*this) *= b; }
    friend Point operator*(Double a, const Point &b) { return Point(a * b.x, a * b.y); }
    Point operator/(Double b) const { return Point(*this) /= b; }

    // Strict comparison operators;
    bool operator==(const Point &b) const { return x == b.x && y == b.y; }
    bool operator!=(const Point &b) const { return !(*this == b); }

    bool operator<(const Point &b) const { return x < b.x || (x == b.x && y < b.y); }
    bool operator>(const Point &b) const { return b < (*this); }
    bool operator<=(const Point &b) const { return !(b < (*this)); }
    bool operator>=(const Point &b) const { return !((*this) < b); }

    string to_string() const {
	return string(1, '(') + ::to_string(x) + "," + ::to_string(y) + ")";
    }
}; // struct Point;

const Point ZERO(0.0, 0.0);
const Point REAL(1.0, 0.0);
const Point IMAG(0.0, 1.0);
const Point INF_INF(INF, INF);

string to_string(const Point &a) {
    return a.to_string();
}

Double norm(const Point &a) {
    return sq(a.x) + sq(a.y);
}

Double abs(const Point &a) {
    // std::hypot may slow;
    return sqrt(sq(a.x) + sq(a.y));
}

Point polar(Double rho, Double theta) {
    return Point(rho * cos(theta), rho * sin(theta));
}

Point conj(const Point &a) {
    return Point(a.x, -a.y);
}

Point rot(const Point &a, Double theta) {
    return a * Point(cos(theta), sin(theta));
}

Point rot90(const Point &a) {
    return Point(-a.y, a.x);
}

Point rot270(const Point &a) {
    return Point(a.y, -a.x);
}

Double dot(const Point &a, const Point &b) {
    return a.x * b.x + a.y * b.y;
}

Double cross(const Point &a, const Point &b) {
    return a.x * b.y - a.y * b.x;
}

// +1: CCW;
// -1: CW;
// 0: line;
int ccw_zero(const Point &b, const Point &c) {
    return sgn(cross(b, c));
}

int ccw(const Point &a, const Point &b, const Point &c) {
    return sgn(cross(b-a, c-a));
}

int ccw2(const Point &a, Point b, Point c) {
    b -= a; c -= a;
    int t = sgn(cross(b, c));
    if (t == 1) return 1; // CCW;
    if (t == -1) return -1; // CW;
    if (sgn(dot(b, c)) < 0) return 2; // ONLINE c--a--b;
    if (cmp(norm(b), norm(c)) < 0) return -2; // ONLINE a--b--c;
    return 0; // ONLINE a--c--b;
}

// return [0 .. PI];
Double angle(const Point &a, const Point &b) {
    return acos(dot(a, b) / abs(a) / abs(b));
}

// arg(complex<double>);
// return [-PI .. PI];
Double angle2(const Point &a) {
    return atan2(a.y, a.x);
}

// from a to b;
Double angle2(const Point &a, const Point &b) {
    Double s = angle2(b) - angle2(a);
    if (s > PI) return s - 2.0 * PI;
    if (s < -PI) return s + 2.0 * PI;
    return s;
}

template<class Iter> void sort_by_angle(Iter ps, Iter ps_end) {
    int n = ps_end - ps;
    vector<pair<Double, Point> > h;
    h.reserve(n);
    REP (i, n) h.emplace_back(angle2(ps[i]), ps[i]);
    sort(h.begin(), h.end());
    REP (i, n) ps[i] = h[i].second;
}

template<class Iter> VI sort_index_by_angle(Iter ps, Iter ps_end) {
    int n = ps_end - ps;
    vector<pair<Double, Point> > h;
    h.reserve(n);
    REP (i, n) h.emplace_back(angle2(ps[i]), i);
    sort(h.begin(), h.end());
    VI ret(n);
    REP (i, n) ret[i] = h[i].second;
    return ret;
}

}; // namespace GEOMETRY;

namespace GEOMETRY {

//////////////////////////////////////////////////
// Circle
//////////////////////////////////////////////////
struct Circle {
    Point c; // center;
    Double r; // radius;
    Circle(): c(), r() {}
    Circle(const Point &c_, const Double r_): c(c_), r(r_) {
	assert(r >= 0.0);
    }
};

string to_string(const Circle &c) {
    return "Circle(" + to_string(c.c) + "," + ::to_string(c.r) + ")";
}

// c contains p?;
bool contains(const Circle &c, const Point &p) {
    return cmp(norm(p - c.c), sq(c.r)) <= 0;
}

// c contains d?;
bool contains(const Circle &c, const Circle &d) {
    return cmp(norm(d.c - c.c) + d.r, sq(c.r)) <= 0;
}

// // verified: CGL_7_F;
// vector<Line> tangent(const Circle &c, const Point &p) {
//     Point a = p - c.c;
//     int cmp_ = cmp(norm(a), sq(c.r));
//     if (cmp_ < 0) return {}; // c contains p;
//     Point v = rot90(a);
//     if (cmp_ == 0) return { Line(p, p + v) }; // p is inscribe to c;
//     Double na = norm(a), g = na - sq(c.r);
//     v *= c.r * sqrt(g) / na;
//     a *= sq(c.r) / na;
//     return { Line(p, c.c + a + v), Line(p, c.c + a - v) };
// }

// // Common tangent;
// // returns [Line(a, b)]: a must on c, b may on d;
// // verified: CGL_7_G;
// vector<Line> tangent(Circle c, Circle d) {
//     if (c.r < d.r) {
// 	vector<Line> ret = tangent(d, c);
// 	if (ret.size() >= 2u) {
// 	    swap(ret[0].a, ret[0].b);
// 	    swap(ret[1].a, ret[1].b);
// 	}
// 	if (ret.size() >= 4u) {
// 	    swap(ret[2].a, ret[2].b);
// 	    swap(ret[3].a, ret[3].b);
// 	}
// 	return ret;
//     }
//     Point v = d.c - c.c;
//     Double norm_ = norm(v), abs_ = sqrt(norm_);
//     if (sgn(norm_) == 0) return {}; // same origin;
//     if (cmp(abs_ + d.r, c.r) < 0) return {}; // inside;
//     Point u = v / abs_;
//     if (cmp(abs_ + d.r, c.r) == 0) { // inner touch;
// 	Point t = u * c.r + c.c;
// 	return { Line(t, t + rot90(u)) };
//     }
//     vector<Line> ret;
//     {
// 	Double cos_ = (c.r - d.r) / abs_;
// 	Double sin_ = sqrt(1.0 - sq(c.r - d.r) / norm_);
// 	Point uc = u * cos_, vs = rot90(u) * sin_;
// 	ret.emplace_back(c.c + (uc + vs) * c.r, d.c + (uc + vs) * d.r);
// 	ret.emplace_back(c.c + (uc - vs) * c.r, d.c + (uc - vs) * d.r);
//     }
//     Double h = sq(c.r + d.r) / norm_;
//     if (cmp(h, 1.0) == 0) { // outer touch;
// 	Point t = u * c.r + c.c;
// 	ret.emplace_back(t, t + rot90(u));
//     } else if (cmp(h, 1.0) < 0) { // outside;
// 	Double cos_ = (c.r + d.r) / abs_;
// 	Double sin_ = sqrt(1.0 - h);
// 	Point uc = u * cos_, vs = rot90(u) * sin_;
// 	ret.emplace_back(c.c + (uc + vs) * c.r, d.c - (uc + vs) * d.r);
// 	ret.emplace_back(c.c + (uc - vs) * c.r, d.c - (uc - vs) * d.r);
//     }
//     return ret;
// }

// returns 0, 1, 2 points;
// verified: CGL_7_E;
vector<Point> cross_point(Circle c, Circle d) {
    if (c.r < d.r) swap(c, d);
    Point v = d.c - c.c;
    Double norm_ = norm(v), abs_ = sqrt(norm_);
    if (sgn(norm_) == 0) return {}; // same origin;
    if (cmp(abs_ + d.r, c.r) < 0) return {}; // inside;
    if (cmp(abs_, c.r + d.r) > 0) return {}; // outside;
    Point u = v / abs_;
    Double cos_ = (sq(c.r) + norm_ - sq(d.r)) / (2.0 * c.r * abs_);
    if (cmp(abs_ + d.r, c.r) == 0 || cmp(abs_, c.r + d.r) == 0 || sgn(1.0 - sq(cos_)) <= 0) {
	// inner or outer touch;
	return { u * c.r + c.c };
    }
    Double sin_ = sqrt(1.0 - sq(cos_));
    Point uc = cos_ * c.r * u, vs = sin_ * c.r * rot90(u);
    return { c.c + uc + vs, c.c + uc - vs };
}

// // returns 0, 1, 2 points;
// // verified: CGL_7_D;
// vector<Point> cross_point(Circle c, Line l) {
//     Point u = l.vec(), v = l.a - c.c;
//     Double a = norm(u), b = dot(u, v) / a, t = (norm(v) - sq(c.r)) / a;
//     Double delta = b*b - t;
//     if (sgn(delta) < 0) return {};
//     if (sgn(delta) == 0) return {l.a - b*u};
//     Double d = sqrt(delta);
//     return { l.a - (b + d) * u, l.a - (b - d) * u };
// }
// 
// Circle bounding_circle(const Point &a, const Point &b) {
//     Point p = (a + b) / 2.0;
//     return Circle(p, abs(a - p));
// }
// 
// Circle circumscribed_circle(const Point &a, const Point &b, const Point &c) {
//     assert(ccw(a, b, c) != 0);
//     Point u = rot90(b-a), v = c-a;
//     Point o = (a + b + u * dot(c-b, v) / dot(u, v)) / 2.0;
//     return Circle(o, abs(a-o));
// }
// 
// // Shuffle ps;
// // LP-type problems;
// template<class Random> Circle minimum_bounding_circle(vector<Point> &ps, Random &engine) {
//     int n = ps.size();
//     assert(n >= 1);
//     if (n == 1) return Circle(ps[0], 0.0);
//     shuffle(ps.begin(), ps.end(), engine());
//     Circle c = bounding_circle(ps[0], ps[1]);
//     for (int i=2; i<n; i++) if (!contains(c, ps[i])) {
// 	c = bounding_circle(ps[0], ps[i]);
// 	for (int j=1; j<i; j++) if (!contains(c, ps[j])) {
// 	    c = bounding_circle(ps[j], ps[i]);
// 	    for (int k=0; k<j; k++) if (!contains(c, ps[k])) {
// 		c = circumscribed_circle(ps[k], ps[j], ps[i]);
// 	    }
// 	}
//     }
//     return c;
// }
// 
}; // namespace GEOMETRY;

using namespace GEOMETRY;

int N, K;
int X[61], Y[61];
int C[61];

Circle ci[61];

bool ok(double mid) {
    if (N <= 1) return true;

    REP (i, N) {
	ci[i] = Circle(Point(X[i], Y[i]), mid / C[i]);
    }

    REP (i, N) {
	int cnt = 0;
	REP (k, N) {
	    if (k == i || contains(ci[k], ci[i].c)) cnt++;
	}
	if (cnt >= K) return true;
    }
    REP (i, N) REP (j, i) {
	auto v = cross_point(ci[i], ci[j]);
	EACH (e, v) {
	    int cnt = 0;
	    REP (k, N) {
		if (k == i || k == j || contains(ci[k], *e)) cnt++;
	    }
	    if (cnt >= K) return true;
	}
    }
    return false;
}

void MAIN() {
    scanf("%d%d", &N, &K);
    REP (i, N) scanf("%d%d%d", X+i, Y+i, C+i);

    double lo = 0, hi = 1;
    while (!ok(hi)) {
	lo = hi;
	hi += hi;
    }
    REP (t, 120) {
	double mid = (lo + hi) / 2;
	(ok(mid)? hi: lo) = mid;
    }

    printf("%.12f\n", hi);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}



Measured memory_bytes: 256