unittest
{
	assert( [ "4 2", "1 2 -3 -4" ].solve == 12 );
	assert( [ "4 3", "-1 -2 -3 -4" ].solve == 1000000001 );
	assert( [ "2 1", "-1 1000000000" ].solve == 1000000000 );
	assert( [ "10 10", "1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1" ].solve == 999983200 );
	
	assert( [ "3 1", "2 0 -2" ].solve == 2 );		// 追加ケース
	assert( [ "3 2", "2 0 -2" ].solve == 0 );		// 追加ケース
	assert( [ "3 3", "2 0 -2" ].solve == 0 );		// 追加ケース
	assert( [ "5 3", "2 4 -4 -4 -2" ].solve == 64 );		// 追加ケース
	assert( [ "3 2", "2 -2 -2" ].solve == 4 );		// 追加ケース
}



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

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 );
	input.popFront;
	auto as = input.front.split.to!( long[] );
	
	const M = 10L ^^ 9 + 7;
	auto tss = as.sort().trisect( 0 );
	
	// プラスにしたときの最大値を計算
	{
		auto ans = ModWorld!M( 1L );
		auto m = 0L;
		auto p = 0L;
		auto ok = true;
		while( ok && p + m < k )
		{
			if( p + m + 1 < k && m + 1 < tss[ 0 ].length && p + 1 < tss[ 2 ].length )
			{
				auto mt = tss[ 0 ][ m ] * tss[ 0 ][ m + 1 ];
				auto pt = tss[ 2 ][ $ - 1 - p ] * tss[ 2 ][ $ - 2 - p ];
				if( pt <= mt )
				{
					ans *= -tss[ 0 ][ m ];
					ans *= -tss[ 0 ][ m + 1 ];
					m += 2;
				}
				else
				{
					ans *= tss[ 2 ][ $ - 1 - p ];
					p++;
				}
			}
			else if( p + m + 1 < k && m + 1 < tss[ 0 ].length )
			{
				ans *= -tss[ 0 ][ m ];
				ans *= -tss[ 0 ][ m + 1 ];
				m += 2;
			}
			else if( p < tss[ 2 ].length )
			{
				ans *= tss[ 2 ][ $ - 1 - p ];
				p++;
			}
			else
			{
				ok = false;
			}
		}
		if( ok ) return ans.n;
	}
	
	// ゼロにできるか判定
	if( !tss[ 1 ].empty ) return 0L;
	
	// マイナスにしたときの最大値を計算
	{
		auto ans = ModWorld!M( 1L );
		auto m = 1L;
		auto p = 0L;
		auto ok = ( m <= tss[ 0 ].length );
		if( ok && m == 1 ) ans *= -tss[ 0 ][ $ - 1 ];
		while( ok && p + m < k )
		{
			if( p + m + 1 < k && m + 1 < tss[ 0 ].length && p + 1 < tss[ 2 ].length )
			{
				auto mt = tss[ 0 ][ $ - 1 - m ] * tss[ 0 ][ $ - 2 - m ];
				auto pt = tss[ 2 ][ p ] * tss[ 2 ][ p + 1 ];
				if( mt <= pt )
				{
					ans *= -tss[ 0 ][ $ - 1 - m ];
					ans *= -tss[ 0 ][ $ - 2 - m ];
					m += 2;
				}
				else
				{
					ans *= tss[ 2 ][ p ];
					p++;
				}
			}
			else if( m + 1 < tss[ 0 ].length )
			{
				ans *= -tss[ 0 ][ $ - 1 - m ];
				ans *= -tss[ 0 ][ $ - 2 - m ];
				m += 2;
			}
			else if( p < tss[ 2 ].length )
			{
				ans *= tss[ 2 ][ p ];
				p++;
			}
			else
			{
				ok = false;
			}
		}
		if( ok ) return M - ans.n;
	}
	
	assert( false );
}

// モジュラ整数型（n mod M）
struct ModWorld( long M )
{
	long n;
	
	void opUnary( string OP )() if( OP == "++" ){ this.n = ( this.n + 1 ) % M; }
	void opUnary( string OP )() if( OP == "--" ){ this.n = ( this.n + M - 1 ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "+"  ){ this.n = ( this.n + r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "-"  ){ this.n = ( this.n + M - r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "*"  ){ this.n = ( this.n * r.n ) % M; }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "/"  ){ this *= r ^^ ModWorld( M - 2 ); }
	void opOpAssign( string OP )( ModWorld r ) if( OP == "^^" )
	{
		auto a = this.n;
		this.n = 1L;
		for( auto i = r.n; 0 < i; i >>= 1 )
		{
			if( i & 1 ) this.n = ( this.n * a ) % M;
			a = ( a * a ) % M;
		}
	}
	auto opBinary( string OP )( ModWorld r ){ auto l = this; l.opOpAssign!OP( r ); return l; }
	
	void opAssign( long r ){ this.n = r; }
	void opOpAssign( string OP )( long r ){ this.opOpAssign!OP( ModWorld( r ) ); }
	auto opBinary( string OP )( long r ){ return this.opBinary!OP( ModWorld( r ) ); }
	auto opBinaryRight( string OP )( long l ){ return ModWorld( l ).opBinary!OP( this ); }
	auto opEquals( long r ){ return this.n == r; }
	
	auto toString(){ return this.n.to!string; }
}


Measured memory_bytes: 12368