Problem:
Score : 500 points

Problem Statement

Given are N integers A_1,\ldots,A_N.

We will choose exactly K of these elements. Find the maximum possible product of the chosen elements.

Then, print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Constraints

1 \leq K \leq N \leq 2\times 10^5

|A_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N K
A_1 \ldots A_N

Output

Print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Sample Input 1

4 2
1 2 -3 -4

Sample Output 1

12

The possible products of the two chosen elements are 2, -3, -4, -6, -8, and 12, so the maximum product is 12.

Sample Input 2

4 3
-1 -2 -3 -4

Sample Output 2

1000000001

The possible products of the three chosen elements are -24, -12, -8, and -6, so the maximum product is -6.

We print this value modulo (10^9+7), that is, 1000000001.

Sample Input 3

2 1
-1 1000000000

Sample Output 3

1000000000

The possible products of the one chosen element are -1 and 1000000000, so the maximum product is 1000000000.

Sample Input 4

10 10
1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1

Sample Output 4

999983200

Be sure to print the product modulo (10^9+7).

Solution in C++ (GCC 9.2.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
#include <functional> // for less
#include <iostream>
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(ar) ar.begin(), ar.end()
#define mp make_pair
#define sot(bello) bello.begin(), bello.end()
#define bitc __builtin_popcountl
#define fr(i, a, b) for (int i = (a), _b = (b); i <= _b; i++)
#define frr(i, a, b) for (int i = (a), _b = (b); i >= _b; i--)
#define rep(i, n) for (int i = 0, _n = (n); i < _n; i++)
#define repr(i, n) for (int i = n - 1; i >= 0; i--)
#define fill(ar, val) rep(i, sizeof(ar) / sizeof(ll)) ar[i] = val
#define fill0(ar) fill((ar), 0)
#define foreach(it, ar) for (typeof(ar.begin()) it = ar.begin(); it != ar.end(); it++)
#define fillinf(ar, n) fr(i, 0, (n)) ar[i] = INF
#define MOD 1000000007
#define MOD1 998244353
#define print(x) {  \
             cout<<x<<endl; \
             cerr<<endl; \
             return;    \
}
#define debug(x) cerr << #x << ": " << x << endl
#define arr1d(a, n)                  \
    cout << #a << " : ";             \
    fr(_, 1, n) cout << a[_] << ' '; \
    cout << endl;
#define arr1d0(a, n)               \
    cout << #a << " : ";           \
    rep(_, n) cout << a[_] << ' '; \
    cout << endl;
#define arr2d(a, n, m)                        \
    cout << #a << " :" << endl;               \
    fr(_, 1, n)                               \
    {                                         \
        fr(__, 1, m) cout << a[_][__] << ' '; \
        cout << endl;                         \
    }
#define arr2d0(a, n, m)                     \
    cout << #a << " :" << endl;             \
    rep(_, n)                               \
    {                                       \
        rep(__, m) cout << a[_][__] << ' '; \
        cout << endl;                       \
    }
#define clr(a) memset(a, 0, sizeof(a))
#define dbug(x) cerr << #x << ": " << x << " "
auto clk = clock();
#define PI 3.1415926535897932385
#define fi first
#define se second
#define arr1d(a, n)                  \
    cout << #a << " : ";             \
    fr(_, 1, n) cout << a[_] << ' '; \
    cout << endl;
#define arr1d0(a, n)               \
    cout << #a << " : ";           \
    rep(_, n) cout << a[_] << ' '; \
    cout << endl;
#define arr2d(a, n, m)                        \
    cout << #a << " :" << endl;               \
    fr(_, 1, n)                               \
    {                                         \
        fr(__, 1, m) cout << a[_][__] << ' '; \
        cout << endl;                         \
    }
#define arr2d0(a, n, m)                     \
    cout << #a << " :" << endl;             \
    rep(_, n)                               \
    {                                       \
        rep(__, m) cout << a[_][__] << ' '; \
        cout << endl;                       \
    }

#define INF 1000000000000000000
const ld PI2 = acos(-1) / 2.0l;
const int dx[] = {0, 0, -1, 1}, dy[] = {-1, 1, 0, 0};
const int dx8[] = {-1, -1, -1, 0, 1, 1, 1, 0}, dy8[] = {-1, 0, 1, 1, 1, 0, -1, -1};
/* This Template is authored by Ankit Anvesh */

using namespace std;

mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
// gcd for negatives too
/* ll gcd(ll a, ll b) {
 if (a == 0) return b;
 if (b == 0) return a;
 if (b < 0) return gcd(a, -1 * b);
 if (a < 0) return gcd(-1 * a, b);
 if (a > b) return gcd(b, a);
 return gcd(b%a, a);
}
 */

//gcd

const ll MAXN=100010;

ll Gcd(ll a, ll b)
{
    if (a % b == 0)
        return b;
    return Gcd(b, a % b);
}
//max
ll Max(ll a, ll b)
{
    if (a > b)
        return a;
    return b;
}
//min
ll Min(ll a, ll b)
{
    if (a < b)
        return a;
    return b;
}

void printvector(std::vector<ll> v)
{
    for (int i = 0; i < v.size(); ++i)
    {
        cout << v[i] << " ";
    }
    cout << "" << endl;
}
void printarray(ll a[], ll n)
{
    for (ll i = 0; i < n; ++i)
    {
        cout << a[i] << " ";
    }
    cout << "" << endl;
}

ll findlcm(vector<ll> arr, ll n)
{
    // Initialize result
    ll ans = arr[0];

    // ans contains LCM of arr[0], ..arr[i]
    // after i'th iteration,
    for (int i = 1; i < n; i++)
        ans = (((arr[i] * ans)) /
               (Gcd(arr[i], ans)));

    return ans;
}

ll power(ll x, ll y, ll p)
{
    ll res = 1;
    x = x % p;
    while (y > 0)
    {
        if (y & 1)
            res = (res * x) % p;

        y = y >> 1;
        x = (x * x) % p;
    }
    return res;
}

ll lowerbound(ll k, vector<ll> v)
{
    //lowerbound to be used when first index such that
    // ar[index]>=k is needed

    ll l = 0;
    ll size = v.size();
    ll r = size - 1;
    ll mid;
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (v[mid] < k)
            l = mid + 1;
        else
        {
            r = mid - 1;
        }
    }
    return l;
}

ll upperbound(ll k, vector<ll> v)
{
    //lowerbound to be used when first index such that
    // ar[index]>k is needed
    ll l = 0;
    ll size = v.size();
    ll r = size - 1;
    ll mid;
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (v[mid] > k)
            r = mid - 1;
        else
        {
            l = mid + 1;
        }
    }
    return l;
}

ll spf[MAXN];

void sieve()
{
    spf[1] = 1;
    for (int i = 2; i < MAXN; i++)
        spf[i] = i;
    for (int i = 4; i < MAXN; i += 2)
        spf[i] = 2;

    for (int i = 3; i * i < MAXN; i++)
    {
        if (spf[i] == i)
        {
            for (int j = i * i; j < MAXN; j += i)
                if (spf[j] == j)
                    spf[j] = i;
        }
    }
}

//Segment Tree Implementation

//const ll N = 100000;

ll n, m;

// BIT tree
/*
start indexing from 1
ll BIT[100010];
void update(ll x,ll val){
 
  for (; x <=n ; x +=(x&(-x)) )
     BIT[x]+=val;

}
ll query(ll x){
  ll sum=0;
  for(;x>0;x -= (x&(-x)) )
    sum+=BIT[x];
  return sum;

}*/

//Dijkstra's Algorithm
// if x->y (weight=w) then v[x].push_back(mp(y,w));

vector<ll> shortPath(vector<pair<ll, ll>> v[], ll src, ll V = 0)
{
    set<pair<ll, ll>> setds;

    ll sizee = V;
    ll IN = INF;
    vector<ll> dist(sizee, IN);
    vector<bool> vis(sizee, false);
    setds.insert(make_pair(0, src));
    dist[src] = 0;

    while (!setds.empty())
    {
        pair<ll, ll> tmp = *(setds.begin());
        setds.erase(setds.begin());

        ll u = tmp.second;
        if (vis[u])
            continue;
        vis[u] = true;
        vector<pair<ll, ll>>::iterator i;
        for (auto i = v[u].begin(); i != v[u].end(); ++i)
        {
            ll v = (*i).first;
            ll weight = (*i).second;
            if (dist[v] > dist[u] + weight)
            {
                if (dist[v] != INF)
                    setds.erase(setds.find(make_pair(dist[v], v)));

                dist[v] = dist[u] + weight;
                setds.insert(make_pair(dist[v], v));
            }
        }
    }
    return dist;
}










ll root(ll a[], ll r)
{
    if (a[r] == r)
    {
        return r;
    }
    else
    {
        ll x = root(a, a[r]);
        a[r] = x;
        return x;
    }
}

void unio(ll a[], ll size[], ll x, ll y)
{
    x = root(a, x);
    y = root(a, y);
    if (x == y)
    {
        return;
    }
    if (size[x] >= size[y])
    {
        a[y] = x;
        size[x] += size[y];
    }
    else
    {
        a[x] = y;
        size[y] += size[x];
    }
}

// Sieve Implementation
/* 
for (ll i=2;i<=100005;i++)
        if (p[i]==0)
        for (ll j=2*i;j<=100005;j+=i) p[j]=1; */

// Dfs search

//do not use n , m , N , C

// Using iterators in C++
//set<ll>:: iterator it;
// string to integer stuuu()
// string to long long stoll()
// string to float stof
// string.substr(position,length);
// integer to string to_string();
// intialize 2d vector vector<vector<ll>> dp(105,vector<ll>(105));
// for taking ceil use (num+den-1)/den
// for declaring min heap use this complicated shit priority_queue<ll,vector<ll>,greater<ll>> q;











void CV(ll txt)
{
   cin>>n;
   ll k;cin>>k;
   vector<ll> ar(n);
   vector<pair<ll,ll>> v;
   ll ne=0;
   rep(i,n){
       cin>>ar[i];
       if(ar[i]>0){
           v.push_back({ar[i],1});
       }
       else
       {
           ne++;
           v.push_back({-ar[i],-1});
       }
       
   }

   sort(sot(v));
   reverse(sot(v)); 
   
   ll ni=0;
   ll prod=1;
   rep(i,k){
       if(v[i].second==-1) ni++;
       prod=(prod*v[i].first)%MOD;
   }
   if(n==k){
       prod=(prod+MOD)%MOD;
       print(prod);
   }
   if(ne==n){
       if(k%2==0){
        print(prod);      
       }
       prod=1;
       ll oi=0;
       while(oi<k){
           prod=(prod*v[n-oi-1].first*-1)%MOD;
           oi++;
       }
       prod=(prod+MOD)%MOD;
       
       //debug(prod);
       print(prod);
   }
   if(ni%2==0){
       print(prod);
   }
   ll lp=-1;
   for(ll i=k;i<n;i++){
       if(v[i].second==1){
           lp=v[i].first;
           break;
       }
   }
   ll ln=-1;
   for(ll i=k;i<n;i++){
       if(v[i].second==-1){
           ln=v[i].first;
           break;
       }
   }
   ll rp=-1;
   ll rn=-1;
   for(ll i=k-1;i>=0;i--){
       if(v[i].second==-1){
           rn=v[i].first;
           break;
       }
   }
   for(ll i=k-1;i>=0;i--){
       if(v[i].second==1){
           rp=v[i].first;
           break;
       }
   }
   // first choice is replace rn by lp
   // second choice is replace rp by ln
   dbug(rn); debug(lp);
   dbug(rp); debug(ln); 
  
    ld lnn=ln;
    if((rn==-1 || lp==-1) and (rp==-1 || ln==-1)){
       prod=(prod+MOD)%MOD;
       print(prod); 
    }        
    if(rn==-1 || lp==-1){
        prod=(prod*ln)%MOD;
        prod=(prod*power(rp,MOD-2,MOD))%MOD;
        print(prod);
    }
    if(rp==-1 || ln==-1){
        prod=(prod*lp)%MOD;
        prod=(prod*power(rn,MOD-2,MOD))%MOD;
        print(prod);
    }
    if((lp*rp)>(ln*rn)){
        ll prod1=(prod*lp)%MOD;
    prod1=(prod1*power(rn,MOD-2,MOD))%MOD;
    print(prod1);
    }
    else
    {
        ll prod2=(prod*ln)%MOD;
    prod2=(prod2*power(rp,MOD-2,MOD))%MOD;
    print(prod2);     
    }
    
    
    //print(max(prod1,prod2));


    

   //sort(sot(ar));


   

    





   
   
   return;
}



int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    ll x68 = 1;
   // cin >> x68;
   for (ll vi = 1; vi <= x68; vi++)
    {
        CV(vi);
    }

    return 0;
}