#include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;++i)
#define rep(i,n) REP(i,0,n)
#define fst first
#define snd second
#define pb push_back
#define ALL(x) x.begin(),x.end()
#define EPS (1e-9)
#define equals(a,b) (fabs((a)-(b))<EPS)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0


using namespace std;

bool LT(double a,double b) { return !equals(a,b) && a < b; }
bool LTE(double a,double b) { return equals(a,b) || a < b; }

const string YES = "";
const string NO  = "";

class Point{
public:
  double x,y;

  Point(double x = 0,double y = 0): x(x),y(y){}

  Point operator + (Point p){return Point(x+p.x,y+p.y);}
  Point operator - (Point p){return Point(x-p.x,y-p.y);}
  Point operator * (double a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  Point operator * (Point a){ return Point(x * a.x - y * a.y, x * a.y + y * a.x); }

  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:(!equals(y,p.y)&&y<p.y); }

  bool operator == (const Point& p)const{ return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS; }

};

struct Segment{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
  bool operator <  (const Segment& s) const { return ( p2 == s.p2 ) ? p1 < s.p1 : p2 < s.p2; }
  bool operator == (const Segment& s) const { return ( s.p1 == p1 && s.p2 == p2 ) || ( s.p1 == p2 && s.p2 == p1 ); }

};

typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

ostream& operator << (ostream& os,const Point& a){ return os << "(" << a.x << "," << a.y << ")"; }

ostream& operator << (ostream& os,const Segment& a){ return os << "( " << a.p1 << " , " << a.p2 << " )"; }

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){ return sqrt(norm(a)); }

//rad は角度をラジアンで持たせること
Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

// 度をラジアンに変換
double toRad(double agl){ return agl*M_PI/180.0; }

// a => prev, b => cur, c=> next
// prev から cur へ行って next へ行く際の角度を求める
double getArg(Point a,Point b,Point c){
  double arg1 = atan2(b.y-a.y,b.x-a.x);
  double arg2 = atan2(c.y-b.y,c.x-b.x);
  double arg = fabs( arg1 - arg2 );
  while( arg > M_PI ) arg -= 2.0 * M_PI;
  return fabs(arg);
}

int ccw(Point p0,Point p1,Point p2){
  Point a = p1-p0;
  Point b = p2-p0;
  if(cross(a,b) > EPS)return COUNTER_CLOCKWISE;
  if(cross(a,b) < -EPS)return CLOCKWISE;
  if(dot(a,b) < -EPS)return ONLINE_BACK;
  if(norm(a) < norm(b))return ONLINE_FRONT;
  return ON_SEGMENT;
}

Polygon andrewScan(Polygon s)
{
  Polygon u,l;
  if(s.size() < 3)return s;

  sort(s.begin(),s.end());

  u.push_back(s[0]);
  u.push_back(s[1]);
  l.push_back(s[s.size()-1]);
  l.push_back(s[s.size()-2]);

  for(int i=2;i<s.size();i++)
    {
      for(int n=u.size();n >= 2 && ccw(u[n-2],u[n-1],s[i]) != CLOCKWISE; n--)
	u.pop_back();
      u.push_back(s[i]);
    }

  for(int i=s.size()-3; i>=0 ; i--)
    {
      for(int n=l.size(); n >= 2 && ccw(l[n-2],l[n-1],s[i]) != CLOCKWISE; n--)
	l.pop_back();
      l.push_back(s[i]);
    }

  reverse(l.begin(),l.end());

  for(int i = u.size()-2; i >= 1; i--) l.push_back(u[i]);

  return l;
}

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


bool isIntersectCC(Circle a,Circle b){
  double d = sqrt(norm(a.p-b.p));
  double r1 = max(a.r,b.r);
  double r2 = min(a.r,b.r);
 
  if(!equals(d,r1+r2) && d > r1+r2)return false;
  if(!equals(d,r1-r2) && d < r1-r2)return false;  // verify
  return true;
}

pair<Point, Point> crosspointCC(Circle cx1, Circle cx2) {
  Point  C1 = cx1.p;
  double r1 = cx1.r;
  Point  C2 = cx2.p;
  double r2 = cx2.r;

  complex<double> c1(C1.x,C1.y);
  complex<double> c2(C2.x,C2.y);
  complex<double> A = conj(c2-c1), B = (r2*r2-r1*r1-(c2-c1)*conj(c2-c1)), C = r1*r1*(c2-c1);
  complex<double> D = B*B-4.0*A*C;
  complex<double> z1 = (-B+sqrt(D))/(2.0*A)+c1, z2 = (-B-sqrt(D))/(2.0*A)+c1;
  return pair<Point, Point>(Point(z1.real(),z1.imag()),Point(z2.real(),z2.imag()));
}



typedef long long ll;

int N,K;

struct Data {
  Point p;
  double c;
};

vector<Data> vec;

#define pow2(x) ((x)*(x))
double calc(double X,double Y) {
  vector<double> a;
  rep(i,N) {
    double tm = vec[i].c * sqrt( pow2(X-vec[i].p.x) + pow2(Y-vec[i].p.y) );
    a.pb(tm);
  }
  sort(ALL(a));
  return a[K-1];
}

double getDistancePP(Point p1,Point p2)
{
  return sqrt(pow(p1.x-p2.x,2)+pow(p1.y-p2.y,2));
}


bool check(vector<Circle> &kzyKT) {
  vector<Point> ps;
  rep(i,N) ps.pb(kzyKT[i].p);
  rep(i,N) {
    REP(j,i+1,N) {
      if( isIntersectCC(kzyKT[i], kzyKT[j]) ) {
	auto tmp = crosspointCC(kzyKT[i], kzyKT[j]);
	ps.pb(tmp.fst);
	ps.pb(tmp.snd);
      }
    }
  }
  sort(ALL(ps));
  ps.erase(unique(ALL(ps)),ps.end());
  rep(i,(int)ps.size()) {
    Point p = ps[i];
    int cnt = 0;
    rep(j,N) {
      double d = getDistancePP(p,kzyKT[j].p);
      if( LTE(d,kzyKT[j].r) ) {
	++cnt;
	if( cnt >= K ) return true;
      }
    }
  }
  return false;
}

void solve() {
  double L = 0, R = 100000000.0;
  rep(_,200) {
    double T = ( L + R ) * 0.5;
    vector<Circle> arr;
    rep(i,N) {
      Circle c;
      c.p = vec[i].p;
      c.r = T / vec[i].c;
      arr.pb(c);
    }
    if( check(arr) ) R = T;
    else             L = T;
  }
  printf("%.10f\n",L);
}

int main() {
  srand((unsigned int)time(NULL));
  cin >> N >> K;
  vec.resize(N);
  rep(i,N) cin >> vec[i].p.x >> vec[i].p.y >> vec[i].c;
  solve();
  return 0;
}


Measured memory_bytes: 384