#include<bits/stdc++.h>
using namespace std;
#define ALL(obj) (obj).begin(),(obj).end()
#define RALL(obj) (obj).rbegin(),(obj).rend()
#define REP(i, n) for(int i=0;i<(n);++i)
#define RANGE(i, a, b) for(int i=(a);i<(b);++i)
#define RREP(i, n) for(int i=(n)-1;i>= 0;--i)

#define endl '\n'
#define pb push_back
#define eb emplace_back
#define pque priority_queue
#define umap unordered_map
#define uset unordered_set
#define BIG 2000000000
#define VERYBIG 1000000000000000ll
#define dcout cout<<fixed<<setprecision(15)
#define _popcnt __builtin_popcount

constexpr long long dx[]={1,0,-1,0,1,1,-1,-1}, dy[]={0,-1,0,1,1,-1,1,-1};
constexpr long long MOD = 1e9+7;

// typedef long long lint;
#define int long long
// #define double long double

template<typename T> inline T GCD(T a,T b){T c;while(b!=0){c=a%b;a=b;b=c;}return a;}
template<typename T> inline T LCM(T a,T b){T c=GCD(a,b);a/=c;return a*b;}
template<typename T> inline T nCr(T a,T b){T i,r=1;for(i=1;i<=b;i++){r*=(a+1-i);r/=i;}return r;}
template<typename T> inline T nHr(T a,T b){return nCr(a+b-1,b);}
template<class T> inline bool chmax(T& a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T> inline bool chmin(T& a,T b){if(a>b){a=b;return 1;}return 0;}

typedef pair<int, int> INTP;
typedef vector<int> INTV;
struct edge2 {int to, cost;};
struct edge3 {int from, to, cost;};

const double eps = 1e-8, pi = acos(-1);
using DD = long double;

struct Point{
  DD x, y;
  Point(DD x = 0.0, DD y = 0.0) : x(x), y(y){}
};
inline Point operator+ (const Point &p, const Point &q) {return Point(p.x+q.x, p.y+q.y);}
inline Point operator- (const Point &p, const Point &q) {return Point(p.x-q.x, p.y-q.y);}
inline Point operator* (const Point &p, DD a) {return Point(p.x*a, p.y*a);}
inline Point operator* (DD a, const Point &p) {return Point(p.x*a, p.y*a);}
inline Point operator/ (const Point &p, DD a) {return Point(p.x/a, p.y/a);}
inline DD cross(const Point &p, const Point &q) {return p.x*q.y - p.y*q.x;}
inline DD dot(const Point &p, const Point &q) {return p.x*q.x + p.y*q.y;}
inline DD abs(const Point &p) {return sqrt(dot(p, p));}
inline bool eq(const Point &p, const Point &q) {return abs(p-q) < eps;}

struct Circle : Point {
  DD r;
  Circle(Point p = Point(0.0, 0.0), DD r = 0.0) : Point(p), r(r){}
};

using Points = vector<Point>;
using Circles = vector<Circle>;

int checker(Circle c1, Circle c2) {
  if(c1.r < c2.r) swap(c1, c2);
  DD d = abs(c1 - c2);
  if(c1.r + c2.r < d) return 4;
  if(eq(c1.r + c2.r, d)) return 3;
  if(c1.r - c2.r < d) return 2;
  if(eq(c1.r - c2.r, d)) return 1;
  return 0;
}

bool intersect(const Circle &c1, const Circle &c2){
  int tmp = checker(c1, c2);
  return 1 <= tmp and tmp <= 3;
}

Points crosspoint(const Circle &c1, const Circle &c2){
  Points res;
  DD d = abs(c1-c2);
  DD a = acos((c1.r*c1.r + d*d - c2.r*c2.r) / (2 * c1.r * d)); // 余弦定理
  DD t = atan2(c2.y - c1.y, c2.x - c1.x);
  Point p1 = c1 + Point(cos(t+a) * c1.r, sin(t+a) * c1.r);
  Point p2 = c1 + Point(cos(t-a) * c1.r, sin(t-a) * c1.r);
  res.pb(p1);
  if(!eq(p1, p2)) res.pb(p2);
  return res;
}

signed main(void){
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N, K; cin >> N >> K;
  Points P(N); vector<DD> C(N);
  REP(i, N) cin >> P[i].x >> P[i].y >> C[i];

  DD left = 0.0, right = 1000000.0;
  REP(_, 40){
    DD R = (left+right) / 2.0;
    Circles cs(N);
    REP(i, N) cs[i] = Circle(P[i], R / C[i]);
    Points alt;
    REP(i, N) {
      alt.pb(P[i]);
      RANGE(j, i+1, N){
        if(!intersect(cs[i], cs[j])) continue;
        auto cro = crosspoint(cs[i], cs[j]);
        for(auto p : cro) alt.pb(p);
      }
    }
    bool ok = 0;
    for(auto pt : alt){
      int cnt = 0;
      REP(i, N){
        DD dist = abs(pt - P[i]);
        if(dist <= cs[i].r + eps) cnt++;
      }
      ok |= (cnt >= K);
    }
    if(ok) right = R;
    else left = R;
  }
  dcout << right << endl;
}

Measured memory_bytes: 516