/*
解説AC.
この問題ではある時間Tを考えた時, 「T秒以内にK個の肉が焼けるか」という
問題として捉えると, 肉が焼けるまでの時間の式を見ると円の公式っぽいので
時間としてTを設定すると「半径T/C[i]の各円がK個以上重なるか」という風に
考えることができる.
このような問題として考えると円がK個以上重なるという事象には時間に対して
単調性があることがわかるため, 二部探索が使えると判断できる.
そこで, 答えとなる時間を二部探索し, 各時間において円がK個以上重なるかを
判定する方法を考える.
普通に考えると円が重なる範囲に含まれる点は無数にあるが, 重なっている範囲を
考えた時, その部分は必ずある2つの円の交点かある円の中心となるため,
それらの点のみを探索候補として考えれば良い.
したがって, ある2つの円同士の交点2つと各円の中心をO(N^2)個だけ列挙して
それらの点の中でK個以上の円に内包されているかを調べれば良いため,
ある時間を設定してその時間内にK個以上の肉が焼けるかを判定するのにO(N^3)かかる.
下手に二次元座標クラスとかを用意しなくてもSTLの複素数ライブラリを使った方が
楽なことがわかった.
ただ内積とか外積の計算はちょっと考えないといけないので注意が必要.
*/
#include<iostream>
#include<iomanip>
#include<complex>
#include<vector>
#include<string>
#define rep(i, start, end) for (int i = (int)start; i < (int)end; ++i)
#define rrep(i, start, end) for (int i = (int)start - 1; i >= end; --i)
#define iter(i, c) for (auto i = (c).begin(); i != (c).end(); ++i)
#define all(x) (x).begin(), (x).end()
using namespace std;
using ll = long long;
template<typename T> inline bool chmax(T& a, T b) {if (a < b) {a = b; return true;} return 0;}
template<typename T> inline bool chmin(T& a, T b) {if (a > b) {a = b; return true;} return 0;}

using pos = complex<double>;

const double EPS = 1e-9;

struct circle {
    pos center_;
    double r_;
    circle(pos center, double r):center_(center), r_(r) {}
};

vector<pos> getCrossPoint(const circle& c1, const circle& c2) {
    double d = abs(c1.center_ - c2.center_);
    if (d < EPS) {
        return vector<pos>();
    }
    if (d > c1.r_ + c2.r_ + EPS) {
        return vector<pos>();
    }
    if (d < abs(c1.r_ - c2.r_) - EPS) {
        return vector<pos>();
    }
    double rc = (d * d + c1.r_ * c1.r_ - c2.r_ * c2.r_) / (2 * d);
    double rs = c1.r_ - abs(rc) < EPS ? 0 : sqrt(c1.r_ * c1.r_ - rc * rc);
    pos diff = (c2.center_ - c1.center_) / d;
    pos p1 = c1.center_ + diff * pos(rc, rs);
    pos p2 = c1.center_ + diff *  pos(rc, -rs);
    vector<pos> res;
    res.push_back(p1);
    res.push_back(p2);
    return res;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    int N, K;
    cin >> N >> K;
    vector<double> X(N), Y(N), C(N);
    rep(i, 0, N) {
        cin >> X[i] >> Y[i] >> C[i];
    }
    double l = 0.0, r = 1000000.0;
    rep(_, 0, 100) {
        double mid = (l + r) / 2;
        vector<circle> CC;
        rep(i, 0, N) {
            CC.emplace_back(pos(X[i], Y[i]), mid / C[i]);
        }
        vector<pos> target_points;
        rep(i, 0, N) {
            target_points.emplace_back(X[i], Y[i]);
        }
        rep(i, 0, N) rep(j, i + 1, N) {
            vector<pos> cross_points = getCrossPoint(CC[i], CC[j]);
            for (auto p : cross_points) {
                target_points.push_back(p);
            }
        }
        bool is_ok = false;
        for (auto p : target_points) {
            int cnt = 0;
            rep(i, 0, N) {
                double d = abs(p - CC[i].center_);
                if (d <= CC[i].r_ + EPS) {
                    ++cnt;
                }
            }
            if (cnt >= K) {
                is_ok = true;
                break;
            }
        }
        if (is_ok) {
            r = mid;
        }
        else {
            l = mid;
        }
    }
    cout << fixed << setprecision(10) << r << endl;
    return 0;
}

Measured memory_bytes: 512