#include<bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp> //required
//#include <ext/pb_ds/tree_policy.hpp> 
#define ll long long
#define lb long double
#define pb push_back
#define loop(i,start,n) for(ll i=start;i<n;i++)
#define rloop(i,n,start)for(ll i=n;i>=start;i--)
#define mod 1000000007
#define endl "\n"
#define INF     1e15
#define NEG_INF -1e15
#define pll pair<ll,ll>
#define x first
#define y second
#define all(x) x.begin(),x.end()
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
void __print(int x) {cerr << x;}
void __print(long x) {cerr << x;}
void __print(long long x) {cerr << x;}
void __print(unsigned x) {cerr << x;}
void __print(unsigned long x) {cerr << x;}
void __print(unsigned long long x) {cerr << x;}
void __print(float x) {cerr << x;}
void __print(double x) {cerr << x;}
void __print(long double x) {cerr << x;}
void __print(char x) {cerr << '\'' << x << '\'';}
void __print(const char *x) {cerr << '\"' << x << '\"';}
void __print(const string &x) {cerr << '\"' << x << '\"';}
void __print(bool x) {cerr << (x ? "true" : "false");}
 
template<typename T, typename V>
void __print(const pair<T, V> &x) {cerr << '{'; __print(x.first); cerr << ','; __print(x.second); cerr << '}';}
template<typename T>
void __print(const T &x) {int f = 0; cerr << '{'; for (auto &i: x) cerr << (f++ ? "," : ""), __print(i); cerr << "}";}
void _print() {cerr << "]\n";}
template <typename T, typename... V>
void _print(T t, V... v) {__print(t); if (sizeof...(v)) cerr << ", "; _print(v...);}
#ifndef ONLINE_JUDGE
#define debug(x...) cerr << "[" << #x << "] = ["; _print(x)
#else
#define debug(x...)
#endif
//using namespace __gnu_pbds;
//template <typename T> using ordered_set =  tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>; 
ll gcdExtended(ll a, ll b, ll *x, ll *y) { 
    // Base Case 
    if (a == 0) { 
        *x = 0, *y = 1; 
        return b; 
    } 
  
    ll x1, y1; // To store results of recursive call 
    ll gcd = gcdExtended(b%a, a, &x1, &y1); 
  
    // Update x and y using results of recursive 
    // call 
    *x = y1 - (b/a) * x1; 
    *y = x1; 
    return gcd; 
} 
ll modInverse(ll a, ll m) { 
    ll x, y; 
    ll g = gcdExtended(a, m, &x, &y); 
    if (g != 1) 
        assert(0);
    else{ 
         
        ll res = (x%m + m) % m; 
        return res; 
    } 
}
int main(){
	IOS;
	ll n, k;
	cin >> n >> k;
	ll a[n + 1];
	vector<ll> pos, neg;
	loop(i, 1, n + 1){
		cin >> a[i];
		if(a[i] > 0)
			pos.pb(a[i]);
		else
			neg.pb(abs(a[i]));
	}

	sort(all(pos));reverse(all(pos));
	sort(all(neg));reverse(all(neg));
	ll ok = 0;
	loop(i, 0, neg.size() + 1){
		if(i * 2 <= min((ll)neg.size(), k) && pos.size() + i * 2 >= k){
			ok = 1;
			break;
		}
	}
	ll ans = 1;
	debug(ok);
	if(ok){
		loop(i, 0, min(k, (ll)pos.size())){
			ans = (ans * pos[i]) % mod;
		}

		ll rem = k - min(k, (ll)pos.size()), i = min(k, (ll)pos.size()) - 1, j = 0;
		//debug(i, j, rem);
		if(rem % 2 == 1){
			rem++;
			ans = (ans * modInverse(pos.back(), mod)) % mod;
			i--;
		}
		while(rem != 0){
			ans = (ans * neg[j]) % mod;
			j++;
			rem--;
		}
		debug(ans, i, j);
		while(i > 0 && j + 1 < neg.size() && neg[j] * neg[j + 1] > pos[i] * pos[i - 1]){
			ans = (ans * modInverse(pos[i], mod)) % mod;
			ans = (ans * modInverse(pos[i - 1], mod)) % mod;
			ans = (ans * neg[j]) % mod;
			ans = (ans * neg[j + 1])% mod;
			i -= 2;
			j += 2;
		}

	}
	else{
		sort(all(pos)), sort(all(neg));
		ll i = 0, j = 0, curr = 0;
	
		while(curr < k && i < pos.size() && j < neg.size()){
			if(pos[i] < neg[j])
				ans = (ans * pos[i++]) % mod;
			else
				ans = (ans * neg[j++]) % mod;
			curr++;
		}

		while(curr < k && i < pos.size()){
			ans = (ans * pos[i++]) % mod;
			curr++;
		}
		while(curr < k && j < neg.size()){
			ans = (ans * neg[j++]) % mod;
			curr++;
		}
		
		ans = (ans * -1) % mod;
		ans = (ans + mod) % mod;
	}

	cout << ans << endl;
}

Measured memory_bytes: 7076