#include<bits/stdc++.h>
using namespace std;

using i64 = int64_t;

const double EPS = 1e-8;
const double INF = 1e12;
const double PI = acos(-1);

using Point = complex<double>;
using Polygon = vector<Point>;

inline int sgn(const double &a) { return (a < -EPS ? -1 : (a > EPS ? 1 : 0)); }

inline bool eq(const Point &a, const Point &b) { return abs(a - b) < EPS; }

namespace std {
inline bool operator<(const Point &a, const Point &b) {
    if (sgn(a.real() - b.real()))
        return sgn(a.real() - b.real()) < 0;
    return sgn(a.imag() - b.imag()) < 0;
}
} // namespace std

double dot(const Point &a, const Point &b) { return real(conj(a) * b); }

double det(const Point &a, const Point &b) { return imag(conj(a) * b); }

struct Line {
    Point p1, p2;

    Line(Point p1 = Point(), Point p2 = Point()) : p1(p1), p2(p2) {}

    bool operator<(const Line &rhs) const {
        if (eq(p2, rhs.p2))
            return p1 < rhs.p1;
        return p2 < rhs.p2;
    }
    bool operator==(const Line &rhs) const {
        return (eq(p1, rhs.p1) && eq(p2, rhs.p2)) ||
               (eq(p1, rhs.p2) && eq(p2, rhs.p1));
    }
};

inline Point curr(const Polygon &p, const int &i) { return p[i % p.size()]; }

inline Point next(const Polygon &p, const int &i) {
    return p[(i + 1) % p.size()];
}

inline Point prev(const Polygon &p, const int &i) {
    return p[(i + p.size() - 1) % p.size()];
}

struct Circle {
    Point p;
    double r;
    Circle(Point p = Point(), double r = 0) : p(p), r(r) {}
};

int intersectCC(Circle a, Circle b) {
    double dsq = norm(a.p - b.p);
    double rs = (a.r + b.r) * (a.r + b.r);
    double rd = (a.r - b.r) * (a.r - b.r);
    if (sgn(dsq - rs) == 1) // 重なっていない
        return 0;
    else if (sgn(rs - dsq) >= 0 && sgn(dsq - rd) >= 0) // 共有点をもつ
        return 1;
    else if (sgn(a.r - b.r) == 1) // BがAの内部にある
        return 2;
    else // AがBの内部にある
        return -2;
}

vector<Point> intersection(Circle c1, Circle c2) {
    double d = abs(c1.p - c2.p);
    vector<Point> res;
    if (intersectCC(c1, c2) != 1)
        return res;
    double rc = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
    double rs = sqrt(c1.r * c1.r - rc * rc);
    Point e = (c2.p - c1.p) / d;
    res.push_back(c1.p + e * Point(rc, rs));
    Point p = c1.p + e * Point(rc, -rs);
    if (res[0] == p)
        return res;
    res.push_back(p);
    if (res[1] < res[0])
        swap(res[1], res[0]);
    return res;
}

struct Yakiniku{
    double x, y, c;
};

int main(){
    int n, k;
    cin >> n >> k;
    vector<Yakiniku> v;
    for(int i=0;i<n;++i){
        double x, y, c;
        cin >> x >> y >> c;
        v.push_back({x, y, c});
    }
    double valid = INF, invalid = 0;
    while(abs(valid-invalid) > 1e-9){
        double mid = (valid + invalid) / 2.;
        vector<Circle> circles;
        vector<Point> points;
        for(int i=0;i<n;++i){
            circles.emplace_back(Point(v[i].x, v[i].y), mid/v[i].c);
            points.emplace_back(v[i].x, v[i].y);
        }
        for(int i=0;i<n;++i){
            for(int j=i+1;j<n;++j){
                auto intersections = intersection(circles[i], circles[j]);
                for(auto p: intersections){
                    points.push_back(p);
                }
            }
        }
        bool ok = false;
        for(auto p: points){
            int num = 0;
            for(int i=0;i<n;++i){
                if(sgn(abs(p-circles[i].p) - circles[i].r) <= 0)num++;
            }
            if(num >= k)ok = true;
        }
        if(ok)valid = mid;
        else invalid = mid;
    }

    printf("%.10lf\n", valid);

    return 0;
}

Measured memory_bytes: 384