#include <bits/stdc++.h>

#pragma region Macro
#define rep(i, n) for(int i = 0; i < (int)(n); i++)
#define FOR(i, m, n) for(int i = m;i < n;i++)
#define SORT(v) sort(v.begin(), v.end())
#define pb(a) push_back(a)
#define eb(a) emplace_back(a)
#define vi vector<int>
#define vvi vector<vector<int>>
#define chmax(x,y) (x = max(x,y))
#define chmin(x,y) (x = min(x,y))

using namespace std;
typedef long long ll;
typedef pair<int, int> P;
#pragma endregion

#pragma region Debug
void debug_out() { cout << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	cout << H << " ";
	debug_out(T...);
}

#ifdef _DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif
#pragma endregion

// コンパイル時、エイリアス「debug」を使用 --> マクロが使えるように

// auto mod int
// source : https://github.com/atcoder-live/library
// https://youtu.be/L8grWxBlIZ4?t=9858
// https://youtu.be/ERZuLAxZffQ?t=4807 : optimize
// https://youtu.be/8uowVvQ_-Mo?t=1329 : division
const int MOD = 1000000007;
const int mod = 1000000007;
struct mint {
	ll x; // typedef long long ll;
	mint(ll x=0):x((x%mod+mod)%mod){}
	mint operator-() const { return mint(-x);}
	mint& operator+=(const mint a) {
		if ((x += a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator-=(const mint a) {
		if ((x += mod-a.x) >= mod) x -= mod;
		return *this;
	}
	mint& operator*=(const mint a) { (x *= a.x) %= mod; return *this;}
	mint operator+(const mint a) const { return mint(*this) += a;}
	mint operator-(const mint a) const { return mint(*this) -= a;}
	mint operator*(const mint a) const { return mint(*this) *= a;}
	mint pow(ll t) const {
		if (!t) return 1;
		mint a = pow(t>>1);
		a *= a;
		if (t&1) a *= *this;
		return a;
	}
	
	// for prime mod
	mint inv() const { return pow(mod-2);}
	mint& operator/=(const mint a) { return *this *= a.inv();}
	mint operator/(const mint a) const { return mint(*this) /= a;}
};
istream& operator>>(istream& is, const mint& a) { return is >> a.x;}
ostream& operator<<(ostream& os, const mint& a) { return os << a.x;}

ll pom(ll a,ll n,int m){ll x=1;for(a%=m;n;n/=2)n&1?x=x*a%m:0,a=a*a%m;return x;}

void solve(){
	#define int ll
	// ここに処理を記述
	// コンパイル時はエイリアス「gpp」--> c++17でコンパイル
	int n,k;
	cin >> n >> k;
	vi a(n);
	rep(i,n){
		cin >> a[i];
	}

	mint ans = 1;

	// 絶対値の降順にソート
	sort(a.begin(), a.end(), [](int i, int j) -> bool{
		return abs(i) > abs(j);
	});

	bool all_nega = true;
	rep(i,n){
		if(a[i] >= 0) all_nega = false;
	}
	// Kが奇数 かつ すべて負
	if(all_nega && k%2==1){
		debug("pass");
		for(int i=0; i<k; i++){
			ans *= a[n-1 - i];
		}
		cout << ans + MOD << endl;
		return;
	}

	// とりあえず絶対値上位k個の積を計算
	bool sign = false, zero = false;
	rep(i,k){
		ans *= a[i];
		if(a[i]<0) sign = !sign;
		if(a[i]==0) zero = true;
	}

	// K=Nの時 or 上位K個の積が非負
	if(sign==0||zero||k==n){
		cout << ans << endl;
		return;
	}

	// そうでないとき
	// 使ったもののうち、正負それぞれ絶対値最小を探す
	#define INF 1e9+9
	int p_min=INF, n_min=INF;
	rep(i,k){
		if(a[i]<0) n_min = a[i];
		else p_min = a[i];
	}
	// 使ってないもののうち、非負・負で絶対値最大を探す
	int p_max=INF, n_max=INF;
	for(int i=n-1; i>=k; i--){
		if(a[i]<0) n_max = a[i];
		else p_max = a[i];
	}

	#define invp(a,p)pom(a,p-2,p)

	if(p_max==INF){
		// 正の数-->負の数 とするしかない
		ans = ans * invp(p_min, MOD) * n_max;
	}
	else if(n_max==INF || p_min==INF){
		// 負の数-->非負 とするしかない
		ans = ans * invp(MOD+n_min, MOD) * p_max;
	}
	else{
		// 上記のうちどちらかを選ぶ
		if(p_max*p_min >= n_max*n_min){		// p_max/n_min >= n_max/p_min
			// 負の数 --> 非負
			ans = ans * invp(MOD+n_min, MOD) * p_max;
		}
		else{
			// 正の数 --> 負の数
			ans = ans * invp(p_min, MOD) * n_max;
		}
	}
	cout << ans + MOD << endl;
}

signed main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
	cout << fixed << setprecision(15);
	
	solve();
	return 0;
}

Measured memory_bytes: 4792