unittest
{
	assert( [ "3 5", "4 2 1", "2 3 1" ].parse.expand.solve == 2 );
	assert( [ "3 8", "4 2 1", "2 3 1" ].parse.expand.solve == 0 );
	assert( [ "11 14", "3 1 4 1 5 9 2 6 5 3 5", "8 9 7 9 3 2 3 8 4 6 2" ].parse.expand.solve == 12 );
}



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

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

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto nk = input.front.split.to!( long[] );
	input.popFront;
	auto as = input.front.split.to!( long[] );
	input.popFront;
	auto fs = input.front.split.to!( long[] );
	return tuple( nk[ 1 ], as, fs );
}

auto solve( long k, long[] as, long[] fs )
{
	as.sort();
	fs.sort!( ( x, y ) => y < x );
	
	// 完食にかかる時間の最小値を二分探索
	auto l = 0L;
	auto r = 10L ^^ 6 * 10L ^^ 6;
	while( l < r )
	{
		// 完食にかかる時間を仮決めして、達成に必要な修行回数を計算
		auto c = ( l + r ) / 2;
		auto kk = 0L;
		foreach( a, f; lockstep( as, fs ) )
		{
			auto t = a * f;
			if( c < t ) kk += ( t - c + f - 1 ) / f;
		}
		
		// 必要な修行回数がK回以内なら実際に可能
		if( kk <= k ) r = c;
		else          l = c + 1;
	}
	return l;
}
