unittest
{
	assert( [ "4 3", "-1 0 3", "0 0 3", "1 0 2", "1 1 40" ].solve == "2.400000" );
	assert( [ "10 5", "-879 981 26", "890 -406 81", "512 859 97", "362 -955 25", "128 553 17", "-885 763 2", "449 310 57", "-656 -204 11", "-270 76 40", "184 170 16" ].solve == "7411.225279" );
}



import std.algorithm;
import std.conv;
import std.format;
import std.math;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.solve.writeln;
}

auto solve( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto n = 0L;
	auto k = 0L;
	input.front.formattedRead!"%s %s"( n, k );
	auto pcs = new Tuple!( Point, long )[ n ];
	foreach( ref pc; pcs )
	{
		input.popFront;
		auto ts = input.front.split.to!( long[] );
		pc = tuple( Point( ts[ 0 ], ts[ 1 ] ), ts[ 2 ] );
	}
	
	// 所要時間を二分探索
	auto ans = real.max;
	auto f( real t )
	{
		Point[] ps;
		foreach( i, a; pcs )
		{
			// 肉aの場所を候補に入れる
			ps ~= [ a[ 0 ] ];
			
			// 肉aがt秒以内に焼ける範囲円と肉bがt秒以内に焼ける範囲円の交点を候補に入れる
			foreach( b; pcs[ i + 1 .. $ ] )
			{
				auto ab = a[ 0 ].distance( b[ 0 ] );
				auto ac = t / a[ 1 ];
				auto bc = t / b[ 1 ];
				if( abs( ac - bc ) < ab && ab <= ac + bc )
				{
					auto ra = angle( ab, ac, bc );
					auto v1 = Vector( a[ 0 ], b[ 0 ] ).turn( ra );
					auto v2 = Vector( a[ 0 ], b[ 0 ] ).turn( -ra );
					v1.m = ac;
					v2.m = ac;
					ps ~= [ a[ 0 ] + v1, a[ 0 ] + v2 ];
				}
			}
		}
		
		// 候補の位置に熱源を置いた場合のt秒以内に焼ける肉の枚数を集計
		foreach( p; ps )
		{
			auto c = 0L;
			foreach( pc; pcs )
			{
				if( p.distance( pc[ 0 ] ) * pc[ 1 ] <= t + 10.0L ^^ -8 )		// 誤差補正
				{
					c++;
					if( k <= c )
					{
						ans = min( ans, t );
						return true;
					}
				}
			}
		}
		return false;
	}
	bisect!f( 0, 100 * hypot( 1000, 1000 ) );
	return format( "%0.6f", ans );
}

// 座標
struct Point
{
	real x = 0;
	real y = 0;
	
	void opOpAssign( string OP )( Vector v ) if( OP == "+" ){ this.x += v.x; this.y += v.y; }
	void opOpAssign( string OP )( Vector v ) if( OP == "-" ){ this.x -= v.x; this.y -= v.y; }
	auto opBinary( string OP )( Vector v ){ auto l = this; l.opOpAssign!OP( v ); return l; }
	
	auto distance( Point p ){ return hypot( p.x - this.x, p.y - this.y ); }
	auto angle( Point p ){ return atan2( p.y - this.y, p.x - this.x ); }
	auto toString(){ return format( "Point(%f, %f)", this.x, this.y ); }
}

// ベクトル
struct Vector
{
	real m = 0;
	real d = 0;		// 0が+x方向、PI_2が+y方向、PIが-x方向、PI_2*3が-y方向
	
	this( real m, real d )
	{
		this.m = m;
		this.d = d;
		if( this.d < -2 * PI || 2 * PI < this.d ) this.d %= PI * 2;
		if( this.d < -PI ) this.d += PI * 2;
		if(  PI < this.d ) this.d -= PI * 2;
	}
	
	this( Point a, Point b )
	{
		this = Vector( a.distance( b ), a.angle( b ) );
	}
	
	auto opUnary( string OP )() if( OP == "+" ){ return this; }
	auto opUnary( string OP )() if( OP == "-" ){ return Vector( m, d + PI ); }
	void opOpAssign( string OP )( real m ) if( OP == "+"  ){ this.m += m; }
	void opOpAssign( string OP )( real m ) if( OP == "-"  ){ this.m -= m; }
	void opOpAssign( string OP )( real m ) if( OP == "*"  ){ this.m *= m; }
	void opOpAssign( string OP )( real m ) if( OP == "/"  ){ this.m /= m; }
	void opOpAssign( string OP )( real m ) if( OP == "^^" ){ this.m ^^= m; }
	auto opBinary( string OP )( real m ){ auto l = this; l.opOpAssign!OP( m ); return l; }
	
	void opOpAssign( string OP )( Vector v ) if( OP == "+" ){ this = Point( 0, 0 ).vector( Point( 0, 0 ) + this + v ); }
	void opOpAssign( string OP )( Vector v ) if( OP == "-" ){ this = Point( 0, 0 ).vector( Point( 0, 0 ) + this - v ); }
	auto opBinary( string OP )( Vector v ){ auto l = this; l.opOpAssign!OP( v ); return l; }
	
	auto turn( real d ){ return Vector( this.m, this.d + d ); }
	auto x(){ return this.m * cos( this.d ); }
	auto y(){ return this.m * sin( this.d ); }
	auto angleBetween( Vector v ){ auto d = abs( this.d - v.d ); return ( d <= PI ) ? d : 2 * PI - d; }
	auto toString(){ return format( "Vector(%f, %f)", this.m, this.d ); }
}

// 余弦定理で辺ab,ac,bcの長さから角aの角度(radian)を計算
auto angle( T )( T ab, T ac, T bc )
{
	return acos( ( ab ^^ 2 + ac ^^ 2 - bc ^^ 2 ) / cast( real )( 2 * ab * ac ) );
}

// 単調増加or減少関数の二分探索
auto bisect( alias pred )( real ng, real ok )
if( is( typeof( pred( ng ) ) : bool ) )
{
	foreach( i; 0 .. 100 )
	{
		auto x = ( ok + ng ) / 2;
		if( pred( x ) ) ok = x;
		else            ng = x;
	}
	return ok;
}


Measured memory_bytes: 4980