#define ll long long
#define dd long double
#define pub push_back
#define pob pop_back
#define puf push_front
#define pof pop_front
#define mp make_pair
#define mt make_tuple
#define fo(i , n) for(ll i = 0 ; i < n ; i++)
//#include<bits/stdc++.h>
#include<iomanip>
#include<cmath>
#include<cstdio>
#include<utility>
#include<iostream>
#include<vector>
#include<string>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<sstream>
#include<bitset>
dd pi = acos(-1) ;
ll z =  1000000007 ;
ll inf = 100000000000000000 ;
ll p1 = 37 ;
ll p2 = 53 ;
ll mod1 =  202976689 ;
ll mod2 =  203034253 ;
ll fact[100] ;
ll gdp(ll a , ll b){return (a - (a%b)) ;}
ll ld(ll a , ll b){if(a < 0) return -1*gdp(abs(a) , b) ; if(a%b == 0) return a ; return (a + (b - a%b)) ;} // least number >=a divisible by b
ll gd(ll a , ll b){if(a < 0) return(-1 * ld(abs(a) , b)) ;    return (a - (a%b)) ;} // greatest number <= a divisible by b
ll gcd(ll a , ll b){ if(b > a) return gcd(b , a) ; if(b == 0) return a ; return gcd(b , a%b) ;}
ll e_gcd(ll a , ll b , ll &x , ll &y){ if(b > a) return e_gcd(b , a , y , x) ; if(b == 0){x = 1 ; y = 0 ; return a ;}
ll x1 , y1 ; e_gcd(b , a%b , x1 , y1) ; x = y1 ; y = (x1 - ((a/b) * y1)) ; return e_gcd(b , a%b , x1 , y1) ;}
ll power(ll a ,ll b , ll p){if(b == 0) return 1 ; ll c = power(a , b/2 , p) ; if(b%2 == 0) return ((c*c)%p) ; else return ((((c*c)%p)*a)%p) ;}
ll inverse(ll a ,ll n){return power(a , n-2 , n) ;}
ll max(ll a , ll b){if(a > b) return a ; return b ;}
ll min(ll a , ll b){if(a < b) return a ; return b ;}
ll left(ll i){return ((2*i)+1) ;}
ll right(ll i){return ((2*i) + 2) ;}
ll ncr(ll n , ll r){if(n < r|| (n < 0) || (r < 0)) return 0 ; return ((((fact[n] * inverse(fact[r] , z)) % z) * inverse(fact[n-r] , z)) % z);}
void swap(ll&a , ll&b){ll c = a ; a = b ; b = c ; return ;}
//ios_base::sync_with_stdio(0);
//cin.tie(0); cout.tie(0);
using namespace std ;
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
using namespace __gnu_pbds; 
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// ordered_set s ; s.order_of_key(val)  no. of elements strictly less than val
// s.find_by_order(i)  itertor to ith element (0 indexed)
//__builtin_popcount(n) -> returns number of set bits in n
// ll seed;
//mt19937 rnd(seed=chrono::steady_clock::now().time_since_epoch().count()); // include bits
#define pll pair<ll, ll> 

bool comp(ll a , ll b)
{
    ll x = abs(a) ;
    ll y = abs(b) ;

    if(x < y)
        return true ;
    return false ;
}

ll get_ans(ll arr[] , ll n , ll m)
{
    vector<ll> pos , neg ;
    fo(i , m)
    {
        if(arr[i] >= 0)
            pos.pub(arr[i]) ;
        else
            neg.pub(arr[i]) ;
    }
    if(neg.size() % 2 == 0)
    {
        ll ans = 1 ;
        fo(i , pos.size())
        {
            ans *= pos[i] ;
            ans %= z ;
        }
        fo(i , neg.size())
        {
            ans *= (-neg[i]) ;
            ans %= z ;
        }
        return ans ;
    }
    ll trp , trn , tap , tan , flag_1 = 0 , flag_2 = 0 ;
    //ll ans_1 = 1 , ans_2 = 1 ;
    for(ll i = m ; i < n ; i++)
    {
        
        if(arr[i] >= 0)
        {
            if(neg.size() == 0 || flag_1 == 1)
                continue ;
            flag_1 = 1 ;
            ll curr = neg[neg.size()-1] ;
            trn = curr ;
            tap = arr[i] ;
    
        }
        if(arr[i] < 0)
        {
            if(pos.size() == 0 || flag_2 == 1)
                continue ;
            ll curr = pos[pos.size()-1] ;
            flag_2 = 1 ;
            trp = curr ;
            tan = arr[i] ;
        }
    }

    if(flag_1 == 1 && flag_2 == 1)
    {
        tan = abs(tan) ;
        trn = abs(trn) ;

        if(tan * trn > tap*trp)
        {
            ll ans = 1 ;
            ans *= tan ;
            ans %= z ;
            fo(i , neg.size())
            {
                ans *= (-neg[i]) ;
                ans %= z ;
            }
            pos.pob() ;
            fo(i , pos.size())
            {
                ans *= pos[i] ;
                ans %= z ;
            }
            return ans ;
        }
        ll ans = 1 ;
        neg.pob() ;
        fo(i , neg.size())
        {
            ans *= (-neg[i]) ;
            ans %= z ;
        }
        fo(i , pos.size())
        {
            ans *= pos[i] ;
            ans %= z ;
        }
        ans *= tap ;
        ans %= z ;
        return ans ;
    }

    if(flag_1 == 1)
    {
        // trn , tap
        neg.pob() ;
        ll ans = (tap%z) ;
        fo(i , pos.size())
        {
            ans *= pos[i] ;
            ans %= z ; 
        }
        fo(i , neg.size())
        {
            ans *= (-neg[i]) ;
            ans %= z ;
        }
        return ans ;
    }

    if(flag_2 == 1)
    {
        // trp , tan 
        pos.pob() ;
        ll ans = (-tan)%z ;
        fo(i , neg.size())
        {
            ans *= (-(neg[i])) ;
            ans %= z ;
        }
        fo(i , pos.size())
        {
            ans *= pos[i] ;
            ans %= z ;
        }
        return ans ;
    }

    ll ans = 1 ;
    for(ll i = n-1 , j = 0; i >= 0 && j < m ; i-- , j++)
    {
        ans *= (arr[i]) ;
        ans %= z ;
        ans += z ;
        ans %= z ;
    }
    return ans ;
}

void solve()
{
    ll n ,m ;
    cin >> n >> m ;
    ll arr[n] ;
    fo(i , n)
    {
        cin >> arr[i] ;
    }
    sort(arr , arr + n , comp) ;
    reverse(arr , arr + n) ;
    /*fo(i , n)
    {
        cout << arr[i] << ' ';
    }*/

    ll ans = get_ans(arr , n , m) ;
    cout << ans << endl ;
    return ;
}

int main()
{
    /*ios_base::sync_with_stdio(0);
    cin.tie(0); cout.tie(0);
    #ifndef ONLINE_JUDGE
    freopen("inputf.txt" , "r" , stdin) ;
    freopen("outputf.txt" , "w" , stdout) ;
    freopen("error.txt" , "w" , stderr) ;
    #endif*/

   
    
    ll t ;
    //cin >> t ;
    t = 1 ;
   
    while(t--)
    {
        solve() ;
    }
    
    //cerr << "Time : " << 1000 * ((double)clock()) / (double)CLOCKS_PER_SEC << "ms\n";
 
    return 0;
}

Measured memory_bytes: 6932