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

//////////////////////////////   Begin Macros

#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
#define in(x, a, b) (a <= x and x < b)
#define rep(i, N) for (int i = 0; i < (int)(N); i++)
#define reprev(i, N) for (int i = (int)(N)-1; i >= 0; i--)
#define rep1(i, N) for (int i = 1; i <= (int)(N); i++)
#define rep1rev(i, N) for (int i = (int)(N); i >= 0; i--)
#define forbe(i, b, e) for (int i = (b); i < (e); i++)
#define forberev(i, b, e) for (int i = (e)-1; i >= (b); i--)
#define forfl(i, f, l) for (int i = (f); i <= (l); i++)
#define forflrev(i, f, l) for (int i = (l); i >= (f); i--)
using ll = long long;
using pii = pair<int, int>;
using pil = pair<int, ll>;
using pli = pair<ll, int>;
using pll = pair<ll, ll>;

template <typename T>
bool chmax(T &m, const T q)
{
  if (m < q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T>
bool chmin(T &m, const T q)
{
  if (m > q)
  {
    m = q;
    return true;
  }
  else
    return false;
}
template <typename T1, typename T2>
pair<T1, T2> operator+(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first + r.first, l.second + r.second}; }
template <typename T1, typename T2>
pair<T1, T2> operator-(const pair<T1, T2> &l, const pair<T1, T2> &r) { return {l.first - r.first, l.second - r.second}; }
template <typename T>
pair<T, T> operator*(const pair<T, T> &l, const T &r) { return {l.first * r, l.second * r}; }
template <typename T>
pair<T, T> operator/(const pair<T, T> &l, const T &r) { return {l.first / r, l.second / r}; }
template <typename T>
istream &operator>>(istream &is, vector<T> &vec)
{
  for (auto &v : vec)
    is >> v;
  return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &vec)
{
  os << "[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const deque<T> &vec)
{
  os << "deq[";
  for (auto v : vec)
    os << v << ",";
  os << "]";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_set<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const unordered_multiset<T> &vec)
{
  os << "{";
  for (auto v : vec)
    os << v << ",";
  os << "}";
  return os;
}
template <typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &pa)
{
  is >> pa.first >> pa.second;
  return is;
}
template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &pa)
{
  os << "(" << pa.first << "," << pa.second << ")";
  return os;
}
template <typename... Ts>
istream &operator>>(istream &is, tuple<Ts...> &theTuple)
{
  apply([&is](Ts &... tupleArgs) { ((is >> tupleArgs), ...); }, theTuple);
  return is;
}
template <typename... Ts>
ostream &operator<<(ostream &os, const tuple<Ts...> &theTuple)
{
  apply([&os](const Ts &... tupleArgs) {
    os << '(';
    size_t n(0);
    ((os << tupleArgs << (++n < sizeof...(Ts) ? "," : "")), ...);
    os << ')';
  },
        theTuple);
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}
template <typename TK, typename TV>
ostream &operator<<(ostream &os, const unordered_map<TK, TV> &mp)
{
  os << "{";
  for (auto v : mp)
    os << v.first << "=>" << v.second << ",";
  os << "}";
  return os;
}

template <typename T>
void reset(vector<T> &v, const T reset_to)
{
  for (auto &x : v)
    x = reset_to;
}
inline int popcount(const unsigned int x) { return __builtin_popcount(x); }
#define dbg(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ") " << __FILE__ << endl;

ll nC2(ll n)
{
  return n * (n - 1) / 2;
}

const int intinf = numeric_limits<int>::max();
const ll llinf = numeric_limits<ll>::max();
const pii udlr[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

//////////////////////////////   End Macros

// Geometry.h start--------------------------------------------
// references:
// https://ei1333.github.io/luzhiled/snippets/geometry/template.html
// https://dai1741.github.io/maximum-algo-2012/cpp/geometry/geometries2d.h

struct Real
{
  static double eps;
  double value;
  Real(double value = 0.0) : value(value) {}
  inline Real operator+() const { return *this; }
  inline Real operator-() const { return Real(-value); }
  inline Real &operator+=(const Real &rhs)
  {
    value += rhs.value;
    return *this;
  }
  inline Real &operator-=(const Real &rhs)
  {
    value -= rhs.value;
    return *this;
  }
  inline Real &operator*=(const Real &rhs)
  {
    value *= rhs.value;
    return *this;
  }
  inline Real &operator/=(const Real &rhs)
  {
    value /= rhs.value;
    return *this;
  }
};
double Real::eps = 1e-8;
bool operator==(const Real &lhs, const Real &rhs) { return abs(lhs.value - rhs.value) < Real::eps; }
bool operator!=(const Real &lhs, const Real &rhs) { return !(lhs == rhs); }
bool operator<=(const Real &lhs, const Real &rhs) { return lhs.value < rhs.value + Real::eps; }
bool operator>=(const Real &lhs, const Real &rhs) { return lhs.value + Real::eps > rhs.value; }
bool operator>(const Real &lhs, const Real &rhs) { return !(lhs <= rhs); }
bool operator<(const Real &lhs, const Real &rhs) { return !(lhs >= rhs); }
Real operator+(const Real &lhs, const double &rhs) { return Real(lhs) += rhs; }
Real operator+(const double &lhs, const Real &rhs) { return rhs + lhs; }
Real operator+(const Real &lhs, const Real &rhs) { return Real(lhs) += rhs; }
Real operator-(const Real &lhs, const double &rhs) { return Real(lhs) -= rhs; }
Real operator-(const double &lhs, const Real &rhs) { return rhs - lhs; }
Real operator-(const Real &lhs, const Real &rhs) { return Real(lhs) -= rhs; }
Real operator*(const Real &lhs, const double &rhs) { return Real(lhs) *= rhs; }
Real operator*(const double &lhs, const Real &rhs) { return rhs * lhs; }
Real operator*(const Real &lhs, const Real &rhs) { return Real(lhs) *= rhs; }
Real operator/(const Real &lhs, const double &rhs) { return Real(lhs) /= rhs; }
Real operator/(const double &lhs, const Real &rhs) { return rhs / lhs; }
Real operator/(const Real &lhs, const Real &rhs) { return Real(lhs) /= rhs; }
istream &operator>>(istream &lhs, Real &rhs) { return lhs >> rhs.value; }
ostream &operator<<(ostream &lhs, const Real &rhs) { return lhs << rhs.value; }
Real radian_to_degree(Real r) { return r * 180.0 / M_PI; }
Real degree_to_radian(Real d) { return d * M_PI / 180.0; }

struct Point : public complex<double>
{
  using complex<double>::complex;
  Point(const complex<double> &c) : complex<double>(c) {}
  Point(complex<double> &&c) : complex<double>(c) {}
  Point(const Real &x, const Real &y) : Point(x.value, y.value) {}

  inline Real x() const { return real(); };
  inline Real y() const { return imag(); };

  inline Point &operator*=(const double &rhs)
  {
    complex<double>::operator*=(rhs);
    return *this;
  }
  inline Point &operator*=(const Real &rhs) { return *this *= rhs.value; }
  inline Point &operator/=(const double &rhs)
  {
    complex<double>::operator/=(rhs);
    return *this;
  }
  inline Point &operator/=(const Real &rhs) { return *this /= rhs.value; }
};
bool operator<(const Point &a, const Point &b)
{
  return a.x() != b.x() ? a.x() < b.x() : a.y() < b.y();
}
Point operator*(const Point &lhs, const double &rhs) { return Point(lhs) *= rhs; }
Point operator*(const double &lhs, const Point &rhs) { return rhs * lhs; }
Point operator*(const Point &lhs, const Real &rhs) { return Point(lhs) *= rhs; }
Point operator*(const Real &lhs, const Point &rhs) { return rhs * lhs; }
Point operator/(const Point &lhs, const double &rhs) { return Point(lhs) /= rhs; }
Point operator/(const double &lhs, const Point &rhs) { return rhs / lhs; }
Point operator/(const Point &lhs, const Real &rhs) { return Point(lhs) /= rhs; }
Point operator/(const Real &lhs, const Point &rhs) { return rhs / lhs; }
istream &operator>>(std::istream &lhs, Point &rhs)
{
  Real x, y;
  lhs >> x >> y;
  rhs = {x, y};
  return lhs;
}

Point rotate(const Real &theta, const Point &p) { return Point(cos(theta.value), sin(theta.value)) * p; }
Real dot(const Point &a, const Point &b) { return (conj(a) * b).real(); }
Real cross(const Point &a, const Point &b) { return (conj(a) * b).imag(); }
Real get_angle(const Point &a, const Point &b, const Point &c)
{
  const Point v(a - b), w(c - b);
  double alpha = atan2(v.y().value, v.x().value), beta = atan2(w.y().value, w.x().value);
  double theta = abs(alpha - beta);
  return min(theta, 2 * M_PI - theta);
}
int ccw(const 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"
  if (norm(b) < norm(c))
    return -2; // "a-b--c" (a--b--c or ab--c)
  return 0;    // "a-c-b"
}

struct Line : public pair<Point, Point>
{
  Point a, b;
  Line(const Point &a, const Point &b) : a(a), b(b) { assert(a != b); } // a--b
  Line(const Real &A, const Real &B, Real const &C)                     // Ax+By=C
  {
    assert(!(A == 0 and B == 0));
    if (A == 0)
    {
      a = Point(0, C / B), b = Point(1, C / B);
    }
    else if (B == 0)
    {
      a = Point(C / A, 0), b = Point(C / A, 1);
    }
    else
    {
      a = Point(0, C / B), b = Point(C / A, 0);
    }
  }
};
ostream &operator<<(std::ostream &lhs, const Line &rhs) { return lhs << rhs.a << " to " << rhs.b; }
bool parallel(const Line &l, const Line &m) { return cross(l.a - l.b, m.a - m.b) == 0.0; }
bool orthogonal(const Line &l, const Line &m) { return dot(l.a - l.b, m.a - m.b) == 0.0; }
Point projection(const Line &l, const Point &p)
{
  Real t = dot(p - l.a, l.a - l.b) / norm(l.a - l.b);
  return l.a + (l.a - l.b) * t;
}
Point reflection(const Line &l, const Point &p)
{
  return p + (projection(l, p) - p) * 2.0;
}
bool intersect(const Line &l, const Point &p)
{
  return abs(ccw(l.a, l.b, p)) != 1;
}
bool intersect(const Point &p, const Line &l) { return intersect(l, p); }
bool operator==(const Line &lhs, const Line &rhs) { return intersect(lhs, rhs.a) and intersect(lhs, rhs.b); }
bool intersect(const Line &l, const Line &m)
{
  return not parallel(l, m) or (l == m);
}

struct Segment : Line
{
  using Line::Line;
};

bool intersect(const Segment &s, const Point &p)
{
  return ccw(s.a, s.b, p) == 0;
}
bool intersect(const Point &p, const Segment &s) { return intersect(s, p); }

bool intersect(const Line &l, const Segment &s)
{
  return ccw(l.a, l.b, s.a) * ccw(l.a, l.b, s.b) <= 0;
}

bool intersect(const Segment &s, const Line &l) { return intersect(l, s); }

bool intersect(const Segment &s, const Segment &t)
{
  return intersect((Line)s, t) and intersect(s, (Line)t);
}

Real distance(const Point &p, const Point &q)
{
  return abs(p - q);
}

Real distance(const Line &l, const Point &p)
{
  return distance(p, projection(l, p));
}
Real distance(const Point &p, const Line &l)
{
  return distance(l, p);
}

Real distance(const Line &l, const Line &m)
{
  return intersect(l, m) ? 0 : distance(l, m.a);
}

Real distance(const Segment &s, const Point &p)
{
  Point r = projection(s, p);
  if (intersect(s, r))
    return distance(r, p);
  return min(distance(s.a, p), distance(s.b, p));
}
Real distance(const Point &p, const Segment &s) { return distance(s, p); }

Real distance(const Segment &s, const Segment &t)
{
  if (intersect(s, t))
    return 0;
  return min({distance(s, t.a), distance(s, t.b), distance(s.a, t), distance(s.b, t)});
}

Real distance(const Line &l, const Segment &s)
{
  if (intersect(l, s))
    return 0;
  return min(distance(l, s.a), distance(l, s.b));
}

struct Circle
{
  Point p;
  Real r;
  Circle(const Point &p, const Real &r) : p(p), r(r) {}
};

Point crosspoint(const Line &l, const Line &m)
{
  Real A = cross(l.b - l.a, m.b - m.a);
  Real B = cross(l.b - l.a, l.b - m.a);
  if (A == 0.0 and B == 0.0)
    return l.a;
  if (A == 0.0)
    throw runtime_error("no intersection");
  return m.a + (m.b - m.a) * B / A;
}

Point crosspoint(const Line &l, const Segment &s)
{
  if (not intersect(l, s))
    throw runtime_error("no intersection");
  if (parallel(l, s))
  {
    if (intersect(l, s.a))
      return s.a;
    if (intersect(l, s.b))
      return s.b;
  }
  return crosspoint(l, Line(s));
}
Point crosspoint(const Segment &s, const Line &l) { return crosspoint(l, s); }

Point crosspoint(const Segment &s, const Segment &t)
{
  if (not intersect(s, t))
    throw runtime_error("no intersection");
  if (parallel(s, t))
  {
    if (intersect(s.a, t))
      return s.a;
    if (intersect(s.b, t))
      return s.b;
  }
  return crosspoint(Line(s), Line(t));
}

int intersect(const Circle &c, const Line &l)
{
  if (distance(c.p, l) > c.r)
    return 0;
  if (distance(c.p, l) == c.r)
    return 1;
  return 2;
}
int intersect(const Line &l, const Circle &c) { return intersect(c, l); }

bool intersect(const Circle &c, const Point &p)
{
  return abs(p - c.p) == c.r;
}
bool intersect(const Point &p, const Circle &c) { return intersect(c, p); }

int intersect(const Circle &c, const Segment &s)
{
  // intersection number
  const Point h = projection(s, c.p);
  if (abs(h - c.p) > c.r)
    return 0;
  Real d1 = abs(c.p - s.a), d2 = abs(c.p - s.b);
  if (d1 < d2)
    swap(d1, d2);
  if (d1 < c.r)
    return 0;
  if (d2 < c.r)
    return 1;
  Real dot_ = dot(s.a - h, s.b - h);
  if (dot_ < 0)
    return 2;
  if (d2 == c.r or dot_ == 0)
    return 1;
  return 0;
}
int intersect(const Segment &s, const Circle &c) { return intersect(c, s); }

int intersect(Circle c1, Circle c2)
{
  if (c1.r < c2.r)
    swap(c1, c2);
  Real d = abs(c1.p - c2.p);
  if (c1.r + c2.r < d)
    return 4; // separated
  if (c1.r + c2.r == d)
    return 3; // circumscribed
  if (c1.r - c2.r < d)
    return 2; // intersected
  if (c1.r - c2.r == d)
    return 1; // inscribed
  return 0;   // included
}

// edit--------------------------

vector<Point> crosspoint(const Circle &c, const Line &l)
{
  vector<Point> ps;
  int intersect_ = intersect(c, l);
  if (intersect_ == 0)
    return ps;
  Point pr = projection(l, c.p);
  Point e = (l.b - l.a) / abs(l.b - l.a);
  double base = sqrt((c.r * c.r - norm(pr - c.p)).value);
  ps.push_back(pr + e * base);
  if (intersect_ == 2)
    ps.push_back(pr - e * base);
  return ps;
}
vector<Point> crosspoint(const Line &l, const Circle &c) { return crosspoint(c, l); }

vector<Point> crosspoint(const Circle &c, const Segment &s)
{
  auto ps = crosspoint(c, Line(s));
  vector<Point> res;
  for (auto p : ps)
    if (intersect(s, p))
      res.emplace_back(p);
  return res;
}
vector<Point> crosspoint(const Segment &s, const Circle &c) { return crosspoint(c, s); }

vector<Point> crosspoint(const Circle &c1, const Circle &c2)
{
  vector<Point> ps;
  int intersect_ = intersect(c1, c2);
  if (intersect_ == 0 or intersect_ == 4)
    return ps;
  Real d = distance(c1.p, c2.p);
  Real crL = (d * d + c1.r * c1.r - c2.r * c2.r) / (2 * d);
  Point e12 = (c2.p - c1.p) / d;
  Point en = e12 * Point(0, 1);
  Point abn = en * sqrt((c1.r * c1.r - crL * crL).value);
  Point cp = c1.p + crL * e12;
  ps.push_back(cp + abn);
  if (intersect_ == 2)
    ps.push_back(cp - abn);
  return ps;
}

// Geometry.h end--------------------------------------------

void solve()
{
  const Real t_max = 15e4;
  int N, K;
  cin >> N >> K;
  vector<tuple<int, int, int>> xyc(N);
  cin >> xyc;
  vector<Point> meets;
  vector<int> difficulties;
  rep(i, N)
  {
    auto [x, y, c] = xyc[i];
    meets.emplace_back(x, y);
    difficulties.push_back(c);
  }

  Real l = 0.0, r = t_max; // (l,r]
  while (l != r)
  {
    Real m = (l + r) / 2;
    bool is_ok = false;

    vector<Circle> circles;
    rep(i, N) circles.emplace_back(meets[i], m / difficulties[i]);

    vector<Point> ps;
    rep(i, N) ps.emplace_back(circles[i].p);
    rep(i, N) forbe(j, i + 1, N)
    {
      auto cps = crosspoint(circles[i], circles[j]);
      ps.insert(ps.end(), all(cps));
    }

    for (auto p : ps)
    {
      int cnt = 0;
      rep(j, N)
      {
        auto c = circles[j];
        if (distance(p, c.p) <= c.r)
          cnt++;
      }
      if (cnt >= K)
      {
        is_ok = true;
        break;
      }
    }

    if (is_ok)
      r = m;
    else
      l = m;
  }
  cout << r << endl;
}

int main()
{
  cerr << "start" << endl;
  // srand(time(0));
  cout << fixed << setprecision(15);

  solve();
  return 0;
}


Measured memory_bytes: 3940