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

using i64 = int64_t;

#define rep(i, x, y) for (i64 i = i64(x), i##_max_for_repmacro = i64(y); i < i##_max_for_repmacro; ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

template <i64 p>
class fp {
public:
    i64 x;
    fp() : x(0) {}
    fp(i64 x_) : x((x_ % p + p) % p) {}
    fp operator+() const { return fp(x); }
    fp operator-() const { return fp(-x); }
    fp& operator+=(const fp& y) {
        x += y.x;
        if (x >= p) x -= p;
        return *this;
    }
    fp& operator-=(const fp& y) { return *this += -y; }
    fp& operator*=(const fp& y) {
        x = x * y.x % p;
        return *this;
    }
    fp& operator/=(const fp& y) { return *this *= fp(inverse(y.x)); }
    fp operator+(const fp& y) const { return fp(x) += y; }
    fp operator-(const fp& y) const { return fp(x) -= y; }
    fp operator*(const fp& y) const { return fp(x) *= y; }
    fp operator/(const fp& y) const { return fp(x) /= y; }
    bool operator==(const fp& y) const { return x == y.x; }
    bool operator!=(const fp& y) const { return !(*this == y); }
    i64 extgcd(i64 a, i64 b, i64& x, i64& y) {
        i64 d = a;
        if (b != 0) {
            d = extgcd(b, a % b, y, x);
            y -= (a / b) * x;
        } else {
            x = 1;
            y = 0;
        }
        return d;
    }
    i64 inverse(i64 a) {
        i64 x, y;
        extgcd(a, p, x, y);
        return (x % p + p) % p;
    }
};

template <i64 p>
i64 abs(const fp<p>& x) { return x.x; }

template <i64 p>
ostream& operator<<(ostream& os, const fp<p>& x) {
    os << x.x;
    return os;
}

template <typename T, typename U>
ostream& operator<<(ostream& os, const pair<T, U>& p) {
    os << "(" << p.first << ", " << p.second << ")";
    return os;
}

template <typename T>
ostream& operator<<(ostream& os, const vector<T>& vec) {
    os << "[";
    for (const auto& v : vec) {
        os << v << ",";
    }
    os << "]";
    return os;
}

template <typename T>
bool chmin(T& a, const T& b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}

template <typename T>
bool chmax(T& a, const T& b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template <typename A, typename T, size_t size>
void fill(A (&ary)[size], const T& val) {
    fill((T*)ary, (T*)(ary + size), val);
}

// x未満の要素の個数を返す
template <typename T>
i64 count_less(const vector<T>& v, T x) {
    return lower_bound(begin(v), end(v), x) - begin(v);
}

// x以下の要素の個数を返す
template <typename T>
i64 count_less_or_equal(const vector<T>& v, T x) {
    return upper_bound(begin(v), end(v), x) - begin(v);
}

// xより大きい要素の個数を返す
template <typename T>
i64 count_greater(const vector<T>& v, T x) {
    return end(v) - upper_bound(begin(v), end(v), x);
}

// x以上の要素の個数を返す
template <typename T>
i64 count_greater_or_equal(const vector<T>& v, T x) {
    return end(v) - lower_bound(begin(v), end(v), x);
}

// x未満の要素のうち最大のものを返す
template <typename T>
T max_less(const vector<T>& v, T x) {
    return *(lower_bound(begin(v), end(v), x) - 1);
}

// x以下の要素のうち最大のものを返す
template <typename T>
T max_less_or_equal(const vector<T>& v, T x) {
    return *(upper_bound(begin(v), end(v), x) - 1);
}

// xより大きい要素のうち最小のものを返す
template <typename T>
T min_greater(const vector<T>& v, T x) {
    return *upper_bound(begin(v), end(v), x);
}

// x以上の要素のうち最小のものを返す
template <typename T>
T min_greater_or_equal(const vector<T>& v, T x) {
    return *lower_bound(begin(v), end(v), x);
}

constexpr int inf = 1.01e9;
constexpr i64 inf64 = 4.01e18;
constexpr long double eps = 1e-9;

int sgn(const long double& a, const long double& epsilon = eps) {
    if (a < -epsilon) return -1;
    if (a > epsilon) return 1;
    return 0;
}

long double tolerance(const long double& a, const long double& b, const long double& epsilon = eps) {
    return epsilon * max({1.l, abs(a), abs(b)});
}

// a==bか?
bool is_equal(const long double& a, const long double& b, const long double& epsilon = eps) {
    return abs(a - b) <= tolerance(a, b, epsilon);
}

// a<bか?
bool is_less(const long double& a, const long double& b, const long double& epsilon = eps) {
    return a < b - tolerance(a, b, epsilon);
}

// a<=bか?
bool is_less_or_equal(const long double& a, const long double& b, const long double& epsilon = eps) {
    //return is_less(a, b, epsilon) or is_equal(a, b, epsilon);
    return a<=b+tolerance(a,b,epsilon);
}

// a>bか?
bool is_greater(const long double& a, const long double& b, const long double& epsilon = eps) {
    return a > b + tolerance(a, b, epsilon);
}

// a>=bか?
bool is_greater_or_equal(const long double& a, const long double& b, const long double& epsilon = eps) {
    return is_greater(a, b, epsilon) or is_equal(a, b, epsilon);
}

typedef complex<long double> point;
typedef pair<point, point> line;
point polar(const long double& r, const long double& th) { return point(r * cosl(th), r * sinl(th)); }
bool equal(const long double x1, const long double x2) { return abs(x1 - x2) < eps; }
bool equal(const point& a, const point& b) { return equal(a.real(), b.real()) and equal(a.imag(), b.imag()); }
long double length(const point& a) { return abs(a); }
long double distance(const point& a, const point& b) { return abs(a - b); }
long double dot(const point& a, const point& b) { return a.real() * b.real() + a.imag() * b.imag(); }
long double cross(const point& a, const point& b) { return a.real() * b.imag() - a.imag() * b.real(); }
bool is_orthogonal(const point& a1, const point& a2, const point& b1, const point& b2) { return equal(dot(a1 - a2, b1 - b2), 0.0); }
bool is_orthogonal(const line& l, const line& m) { return is_orthogonal(l.first, l.second, m.first, m.second); }
bool is_parallel(const point& a1, const point& a2, const point& b1, const point& b2) { return equal(cross(a1 - a2, b1 - b2), 0.0); }
bool is_parallel(const line& l, const line& m) { return is_parallel(l.first, l.second, m.first, m.second); }
int ccw(point a, point b, point c) {
    b -= a;
    c -= a;
    if (cross(b, c) > 0) return +1;    // counter clockwise
    if (cross(b, c) < 0) return -1;    // clockwise
    if (dot(b, c) < 0) return +2;      // c--a--b on line
    if (norm(b) < norm(c)) return -2;  // a--b--c on line
    return 0;
}
bool intersectLL(const line& l, const line& m) {
    return abs(cross(l.second - l.first, m.second - m.first)) > eps ||  // non-parallel
           abs(cross(l.second - l.first, m.first - l.first)) < eps;     // same line
}
bool intersectLS(const line& l, const line& s) {
    return cross(l.second - l.first, s.first - l.first) *  // s.first is left of l
           cross(l.second - l.first, s.second - l.first) <
           eps;  // s.second is right of l
}
bool intersectLP(const line& l, const point& p) {
    return abs(cross(l.second - p, l.first - p)) < eps;
}
bool intersectSS(const line& s, const line& t) {
    return ccw(s.first, s.second, t.first) * ccw(s.first, s.second, t.second) <= 0 &&
           ccw(t.first, t.second, s.first) * ccw(t.first, t.second, s.second) <= 0;
}
bool intersectSP(const line& s, const point& p) {
    return abs(s.first - p) + abs(s.second - p) - abs(s.second - s.first) < eps;  // triangle inequality
}
point projection(const line& l, const point& p) {
    long double t = dot(p - l.first, l.first - l.second) / norm(l.first - l.second);
    return l.first + t * (l.first - l.second);
}
point reflection(const line& l, const point& p) {
    return p + point((projection(l, p) - p).real() * 2, (projection(l, p) - p).imag() * 2);
}
long double distanceLP(const line& l, const point& p) {
    return abs(p - projection(l, p));
}
long double distanceLL(const line& l, const line& m) {
    return intersectLL(l, m) ? 0 : distanceLP(l, m.first);
}
long double distanceLS(const line& l, const line& s) {
    if (intersectLS(l, s)) return 0;
    return min(distanceLP(l, s.first), distanceLP(l, s.second));
}
long double distanceSP(const line& s, const point& p) {
    const point r = projection(s, p);
    if (intersectSP(s, r)) return abs(r - p);
    return min(abs(s.first - p), abs(s.second - p));
}
long double distanceSS(const line& s, const line& t) {
    if (intersectSS(s, t)) return 0;
    return min(min(distanceSP(s, t.first), distanceSP(s, t.second)),
               min(distanceSP(t, s.first), distanceSP(t, s.second)));
}
// a1,a2を通る直線とb1,b2を通る直線の交点計算
point intersection_l(const point& a1, const point& a2, const point& b1, const point& b2) {
    const point &a = a2 - a1, b = b2 - b1;
    return a1 + a * cross(b, b1 - a1) / cross(b, a);
}
point intersection_l(const line& l, const line& m) {
    return intersection_l(l.first, l.second, m.first, m.second);
}

//直線の単位法線ベクトルを求める
line get_unit_normalV(const point& a, const point& b) {
    line l;
    l.first = ((b - a) * point(0, 1)) / abs(b - a);
    l.second = ((b - a) * point(0, -1)) / abs(b - a);
    return l;
}

//線分sを距離dだけ平行移動
pair<line, line> get_translation(const line& s, long double d) {
    line v = get_unit_normalV(s.first, s.second);
    pair<line, line> res;
    res.first = line(s.first + v.first * d, s.second + v.first * d);
    res.second = line(s.first + v.second * d, s.second + v.second * d);
    return res;
}

struct circle {
    point o;
    long double r;
    circle() {}
    circle(const point o, const long double r) : o(o), r(r) {}
};

//2円の交差判定
int icc(const circle &c, const circle &d) {
    /*
      1 : intersect
      0 : distinct
      -1: c < d
      -2: c > d

      intersect or contain : true
      distinct             : false
    */
    long double od = abs((c.o - d.o));
    return c.r + d.r < od + eps ? 0 : od + c.r < d.r + eps ? -1 : od + d.r < c.r + eps ? -2 : 1;
}

pair<point, point> ccc(const circle &c1, const circle &c2) {
    if (!icc(c1, c2)) return pair<point, point>(c1.o, c2.o);
    long double w = abs(c2.o - c1.o), th = arg(c2.o - c1.o);
    long double dth = acosl((c1.r * c1.r + w * w - c2.r * c2.r) / (2. * c1.r * w));
    return pair<point, point>(c1.o + polar(c1.r, th - dth), c1.o + polar(c1.r, th + dth));
}

void solve() {
    //constexpr i64 mod = 1'000'000'007;
    i64 N,K;
    cin >> N >> K;

    vector<long double> x(N),y(N),c(N);
    vector<point> xy;

    rep(i,0,N){
        cin >> x[i] >> y[i] >> c[i];
        xy.emplace_back(point(x[i],y[i]));
    }

    if(K==1){
        cout << 0 << endl;
        return;
    }

    auto ok=[&](long double t){
        vector<point> os;

        rep(i,0,N){
            rep(j,i+1,N){
                const auto p=xy[i],q=xy[j];
                const long double pd=t/c[i],qd=t/c[j];
                const circle pc(p,pd),qc(q,qd);

                const auto s=icc(pc,qc);
                if(s==0) continue;
                if(s==-1){
                    os.emplace_back(p);
                    continue;
                }
                if(s==-2){
                    os.emplace_back(q);
                    continue;
                }
                const auto tmp=ccc(pc,qc);
                os.emplace_back(tmp.first);
                os.emplace_back(tmp.second);
            }
        }

        bool res=false;
        for(const auto& o:os){
            i64 cnt=0;
            rep(i,0,N){
                const auto& p=xy[i];
                const long double d=distance(o,p);
                if(c[i]*d<=t+tolerance(c[i]*d,t)) ++cnt;
            }
            if(cnt>=K){
                res=true;
                break;
            }
        }

        return res;
    };

    long double lb=0,ub=inf64;
    rep(loop,0,200){
        long double t=(lb+ub)/2;
        if(ok(t)) ub=t;
        else lb=t;
    }

    cout << ub << endl;
}

int main() {
    std::cin.tie(0);
    std::ios::sync_with_stdio(false);
    cout.setf(ios::fixed);
    cout.precision(16);
    solve();
    return 0;
}


Measured memory_bytes: 540