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

typedef long long ll;
#define REP(i,n) for(int i=0,_n=(int)(n);i<_n;++i)
#define ALL(v) (v).begin(),(v).end()
#define CLR(t,v) memset(t,(v),sizeof(t))
template<class T1,class T2>ostream& operator<<(ostream& os,const pair<T1,T2>&a){return os<<"("<<a.first<<","<<a.second<< ")";}
template<class T>void pv(T a,T b){for(T i=a;i!=b;++i)cout<<(*i)<<" ";cout<<endl;}
template<class T>void chmin(T&a,const T&b){if(a>b)a=b;}
template<class T>void chmax(T&a,const T&b){if(a<b)a=b;}


int nextInt() { int x; scanf("%d", &x); return x;}
ll nextLong() { ll x; scanf("%lld", &x); return x;}

using D = long double;
const D PI = acos(-1.0);
const D EPS = 1e-10;
struct P {
  D x, y;
  P(D x=0, D y=0) : x(x), y(y) {}

  P& operator+=(const P& o) { x += o.x; y += o.y; return *this; }
  P& operator-=(const P& o) { x -= o.x; y -= o.y; return *this; }
  P& operator*=(const P& o) { return *this = {x*o.x - y*o.y, x*o.y + y*o.x}; }
  P& operator*=(const D& r) { x *= r; y *= r; return *this; }
  P& operator/=(const D& r) { x /= r; y /= r; return *this; }
  P operator-() const { return {-x, -y}; }

  D norm() const { return x*x + y*y; }
  D abs() const { return sqrt(norm()); }
  D arg() const { return atan2(y, x); }
  bool isZero() const { return std::abs(x) < EPS && std::abs(y) < EPS; }
  /** 象限 */
  int orth() const { return y >= 0 ? (x >= 0 ? 1 : 2) : (x < 0 ? 3 : 4); }
  static P polar(const D& rho, const D& theta = 0) { return {rho * cos(theta), rho * sin(theta)}; }
};
std::ostream &operator<<(std::ostream &os, P const &p) { return os << "(" << p.x << ", " << p.y << ")"; }
P operator+(const P& p, const P& q) { return P(p) += q; }
P operator-(const P& p, const P& q) { return P(p) -= q; }
P operator*(const P& p, const P& q) { return P(p) *= q; }
P operator*(const P& p, const D& r) { return P(p) *= r; }
P operator/(const P& p, const D& r) { return P(p) /= r; }
P operator*(const D& r, const P& p) { return P(p) *= r; }
P operator/(const D& r, const P& p) { return P(p) /= r; }

struct C : public P {
  D r;
  C() {}
  C(const P &p, D r):P(p),r(r){}
};

// 2円の交点
vector<P> intersectionCC(const C& c1, const C& c2) {
  vector<P> ret;
  D d = (c1 - c2).abs();
  P diff = (c2 - c1) / d;
  if( c1.r + c2.r < d - EPS ) {                        // 離れていて交点0

  } else if( d < EPS && abs(c1.r - c2.r) < EPS ) {     // 2円が重なる

  } else if( abs( c1.r + c2.r - d ) < EPS ) {          // 外側で1点で接する
    ret.push_back( c1 + diff * c1.r );
  } else if( abs( c1.r - c2.r ) > d + EPS ) {          // 内側に含む。交点0

  } else if( abs( abs( c1.r - c2.r ) - d ) < EPS) {    // 内側で1点で接する
    ret.push_back( c1 + diff * c1.r );
  } else {                                            // 2点で交わる
//     assert( d < c1.r + c2.r );
    D rc = (d*d + c1.r*c1.r - c2.r*c2.r) / (2*d);
    D rs = sqrt(c1.r*c1.r - rc*rc);

    ret.push_back( c1 + diff * P(rc, -rs) );
    ret.push_back( c1 + diff * P(rc, rs) );
  }
  return ret;
}

bool possible(int N, int K, const vector<C> cs) {
  vector<P> cand;
  REP(i, N) cand.push_back(cs[i]);
  REP(i, N) {
    REP(j, i) {
      auto v = intersectionCC(cs[i], cs[j]);
      for (P p : v)
        cand.push_back(p);
    }
  }
  for (P p : cand) {
    int in = 0;
    REP(i, N) {
      if ((cs[i] - p).abs() <= cs[i].r + EPS) in++;
    }
    if (in >= K) return true;
  }
  return false;
}

int main2() {
  int N = nextInt();
  int K = nextInt();

  vector<C> vs(N);
  vector<double> c(N);
  REP(i, N) {
    double x = nextInt();
    double y = nextInt();
    vs[i] = C(P(x, y), 0);
    c[i] = nextInt();
  }

  double hi = 1000000000;
  double lo = 0;
  REP(step, 200) {
    double ans = (hi + lo) / 2.0;
    REP(i, N) {
      vs[i].r = ans / c[i];
    }
    if (possible(N, K, vs)) {
      hi = ans;
    } else {
      lo = ans;
    }
  }
  printf("%.10f\n", hi);
  return 0;
}

int main() {

#ifdef LOCAL
  for (;!cin.eof();cin>>ws)
#endif
    main2();
  return 0;
}

Measured memory_bytes: 432