#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
#include <map>
#include <set>
#include <cassert>
#include <math.h>
#include <chrono>
#include <stdio.h>
#include <list>
#include <unordered_set>
#include <string>
#include <stdlib.h>
#include <random>
 
#define pair std::pair
#define P 1000000007
#define un_map std::unordered_map
#define ll long long int
#define string std::string
#define vec std::vector
//#define vec_out(v) for(auto x: v) std::cout<<x<<" "; std::cout<<'\n'
#define in(a) std::cin>>a
#define out(a) std::cout<<a<<std::endl
//#define vec_in(v,n) for(ll i=0;i<n;i++) std::cin>>v[i]
#define g_out(t,ans) std::cout<<"Case #"<<t<<": "<<ans<<std::endl
#define g_out2(t,x) x!=true ?  std::cout<<t<<" " : std::cout<<t<<std::endl
#define flush fflush(stdout)
#define big 1000000000
#define small -big
#define pb push_back
#define rep(i,n) for(ll i=0;i<n;i++)
#define in_rep(i,n) for(ll i=n-1;i>=0;i--) 
//#define hash gp_hash_table 
template<typename T> 
void vec_in(std::vector<T> &v,ll n){
    if(v.size() == 0){
        T input;
        for(ll i=0;i<n;i++){
            in(input);
            v.push_back(input);    
        }
    }
    else{
        for(ll i=0;i<n;i++) std::cin>>v[i];
    }
}  
template<typename T> 
void vec_out(std::vector<T> &v){
    for(T x : v){
        std::cout<<x<<" ";
    }
    std::cout<<'\n';
}
 
template<typename T> 
void vec_out(std::vector<T> && v){
    for(T x : v){
        std::cout<<x<<" ";
    }
    std::cout<<'\n';
}
 
 
//bool des
 
 
 
//Hash Table
/*
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
 
 
const int RANDOM = std::chrono::high_resolution_clock::now().time_since_epoch().count();
struct chash {
    int operator()(int x) const { return x ^ RANDOM; }
};
*/
 
//gp_hash_table<int, int, chash> ta;
 
//Hash Table finished 


//Graph

 
void flatten(vec< vec<ll> >& adj,vec< pair<ll,ll> >& flat,vec<ll> & time,ll node,vec<bool>des){  //Des True - Visited False - Not Visited
 
    flat[node].first = time.size();
 
    time.push_back(node);
 
    //out(node);
 
    des[node] = true;
 
    for(ll x : adj[node]){
        
        if(des[x] == false){
 
            flatten(adj,flat,time,x,des);
 
        }
        
 
 
    }
 
    flat[node].second = time.size();
 
    //out(node)
 
    time.pb(node);
 
    return;
 
}
 

//Number Theory

constexpr ll max_number = 100000;

ll fac[max_number];

long long int  gcd(long long int  a,long long int  b) {
 
        a = a >=0 ? a: -a;
 
        b = b >=0 ? b: -b;
 
        //if(a>b) a^=b^=a^=b;
        
        if(b==0) return a;
        else return gcd(b,a%b);
}
 
 long long int  lcm(long long int  a,long long int  b) {
    
        return (a/gcd(a,b))*b;
 
 }
 
 long long int  mod_exp(long long int  a,long long int b,long long int mod){
     
     long long int  pro = 1;
 
     a%=mod;
 
     while(b>0){
         
         if(b%2){
            pro *= a;
 
            pro%= mod;
 
            pro = (pro+mod)%mod;
         }
 
         a*=a;
         
         a%=mod;
 
         a= (a+mod)%mod;
 
         b>>=1;
 
 
     }
 
     return pro;
 
 }
 
long long int  inverse(long long int  a,long long int b){
 
    return mod_exp(a,b-2,b);
 }
 
bool check_power_2(ll x){
    //out(x);
    ll index = 0;
    while(index<40 && (1<<index)!= x) index++;
    if(index==40) return false;
    else return true;
 }

void fac_init(ll p){

    fac[0] = 1;
    
    for (int i=1 ; i<max_number; i++) 
            fac[i] = fac[i-1]*i%p;

}

ll nCr(ll n, ll r, ll mod){ 
   if (r==0) 
      return 1;
   else if(n >= r){   
        return (fac[n]* inverse(fac[r], mod) % mod * 
            inverse(fac[n-r], mod) % mod) % mod;
    }
    else{
        return 0;
    } 

}
 
//ll A = 500000000;
 
//int num_query = 0;
 
string g_query(ll x,ll y){
    //num_query++;
    g_out2(x,0); g_out2(y,1);
    //flush;
    string answer; in(answer);
    if(answer == "WRONG"){
        exit(0);
    }
    else{
        return answer;
    }
 }
 
ll binary_search_1(ll start,ll end,bool x){  
     
     double mid2 = ((double)(start+end))/2;
 
     ll mid = floor(mid2)-start < ceil(mid2)-start ? floor(mid2) : ceil(mid2);
 
     while(mid != start && mid != end){
         
         string ans; 
 
         if(x){
            ans = g_query(mid,0);
         }
         else{
            ans = g_query(0,mid);
         }
 
         if(ans != "CENTER"){
 
            if(ans == "HIT"){
                
                 return binary_search_1(mid,end,x);
 
             }
             else{
 
                 return binary_search_1(start,mid,x);
 
             }
         }
         else{
            return big;
         }
 
    }
 
    return start;
 
}
 
//Segment Tree Section

//ll tree[seg_number][64]; //bool lazy[seg_number];

int* tree;
 
void build(vec<ll>& arr,ll node, ll start, ll end)
{

    if(start == end)
    {

        tree[node] = arr[start];

    }

    else
    {
        ll mid = (start + end) / 2;
 
        build(arr,2*node, start, mid);
        
        build(arr,2*node+1, mid+1, end);
        
        for(ll i=0;i<40;i++){
            
            tree[node] = tree[2*node] + tree[2*node + 1];

        }
 
        
         
    }
}
 
void update(vec<ll>& arr,ll node, ll start, ll end, ll idx, ll val)
{
    if(start == end)
    {
        arr[idx] += val;

        tree[node] += val;
    }
    else
    {
        ll mid = (start + end) / 2;
        if(start <= idx and idx <= mid)
        {
            update(arr,2*node, start, mid, idx, val);
        }
        else
        {
            update(arr,2*node+1, mid+1, end, idx, val);
        }
 
        tree[node] = tree[2*node] + tree[2*node+1];
    }
}
 
void rangeUpdate(vec<ll>& tree,vec<ll>& lazy,ll node, ll start, ll end, ll l,ll r,ll value)
{
    if(r < start or end < l)
    {
        return;
    }
 
    else if(l <= start and end <= r)
    {    
 
         lazy[node] +=  value;
 
         if(start == end){
            
            tree[node] += lazy[node];
 
            lazy[node] = 0;
 
         }
 
 
    }
    else{
 
        if(lazy[node] != 0){
            
            lazy[2*node] += lazy[node];
 
            lazy[2*node  + 1] += lazy[node];
 
            lazy[node] = 0;
 
        }
       
        ll mid = (start + end) / 2;
 
        rangeUpdate(tree,lazy,2*node, start, mid, l, r,value);
 
        rangeUpdate(tree,lazy,2*node+1, mid+1, end, l, r,value);
        
 
        tree[node] = (tree[2*node]+lazy[2*node])  + (tree[2*node +1] + lazy[2*node +1]);
 
 
    }
    
}
 
ll lazy_query(vec<ll>& tree,vec<ll>& lazy,int node, int start, int end, int l, int r)
{
 
    if(r < start or end < l)
    {
        return 0;
    }
 
    else if(l <= start and end <= r)
    {
        if(lazy[node] != 0){
 
            if(start == end){
                
                tree[node] += lazy[node];
 
                lazy[node] = 0;
 
                return tree[node];
 
               
            }
            else{
 
                lazy[2*node] += lazy[node];
 
                lazy[2*node  + 1] += lazy[node];
 
                lazy[node] = 0;
                
                tree[node] = (tree[2*node]+lazy[2*node])  + (tree[2*node +1] + lazy[2*node +1]);
 
                return tree[node];
 
            }
            
 
 
        }
        else{
 
          return tree[node];
        } 
 
        
    }
    else{
 
        if(lazy[node] != 0){
            
            lazy[2*node] += lazy[node];
 
            lazy[2*node  + 1] += lazy[node];
 
            lazy[node] = 0;
 
 
        }
    
        ll mid = (start + end) / 2;
 
        ll p1 = lazy_query(tree,lazy,2*node, start, mid, l, r);
 
        ll p2 = lazy_query(tree,lazy,2*node+1, mid+1, end, l, r);
        
        tree[node] = (tree[2*node]+lazy[2*node])  + (tree[2*node +1] + lazy[2*node +1]); 
 
        //vec_out<ll>(p1.arr); vec_out<ll>(p2.arr);
 
        return (p1+p2);
    }
}
 
ll query(int node, int start, int end, int l, int r)
{
 
    if(r < start or end < l)
    {
        return 0;
    }
 

    else if(l <= start and end <= r)
    {
        
        return tree[node]; 
        
    }
    else{
    
        ll mid = (start + end) / 2;
 
        ll p1 = query(2*node, start, mid, l, r);
 
        ll p2 = query(2*node+1, mid+1, end, l, r);
 
        return p1+p2;
    }
}

void find(vec<ll>&arr,ll node, ll start,ll end,ll val){

    if(start == end){

        arr[start] -=1;

        tree[node] -= 1;

        return ;

    }
    
    ll mid = (start + end) / 2;

    if(tree[2*node] >= val){

       find(arr,2*node,start,mid,val);

       tree[node] = tree[2*node] + tree[2*node + 1]; 

    }
    else{

       find(arr,2*node + 1,mid+1,end,val-tree[2*node]);

       tree[node] = tree[2*node] + tree[2*node + 1];

    }

    return ;


}


//Trie

class Trie{

public:
    char c;
    ll count;
    vec<Trie*> next;
public:
    Trie() : c(0),count(0){

    }
public:
    static void insert(Trie* root,string arg,int index= 0){

       ll n = arg.size();

        for(Trie* x : root->next){
             
             if(x->c == arg[index]){

                if(index < n-1){

                    return insert(x,arg,index + 1);
                }
                else{

                    x->count += 1;

                    return;

                }
                
             }

        }

        Trie* node = new Trie[1];

        node->c = arg[index]; node->count = 0;

        (root->next).push_back(node);

        if(index == n-1){
           
            node->count = 1;

            return ;

        }
        else{

            return insert(node,arg,index + 1);

        }

    }
    

public:
    static void print(Trie* root){

        //out(root->c);

       for(auto x: root->next){
          
          g_out2(x->c,0); g_out2(x->count,0);              
          
       }

       out("");

       for(auto x : root->next){
          print(x);
       }

    }


};

void count_dig(ll number, string str,vec< vec<char> >&ans){
      
   vec<ll>dig;

   while(number){
      
      dig.push_back(number%10);
      
      number /=10;

   }

   if(str.size() == dig.size()){ 
          
      ans[dig[dig.size()-1]].push_back(str[0]);

      return ;

   }
   else{
     return ;
   }


}

ll gcd_arr(vec<ll>& arr,ll st,ll en){
     
     ll gcd1 = arr[0];

     for(ll i=st;i<en;i++) gcd1 = gcd(gcd1,arr[i]);

    return gcd1;

}

bool check_size(vec< vec<ll> >& freq,ll size){
     
    int n = freq.size();

    for(ll i = 0;i<n-size+1;i++){

        bool cool = true;

        for(ll j =0;j<3;j++){

           if(i==0 && freq[i+size-1][j] == 0 ){

              cool = false;
              break;
           }

           if(i!=0 && freq[i+size-1][j] - freq[i-1][j] == 0){
             cool = false;
             break;
           }

        }

        if(cool){
            return true;
        }

          

    }
    return false;

}


ll bit[(ll)(1e6+1)];

ll query_bit(ll index){

    ll sum = 0;

    while(index){

        sum += bit[index];

        index -= index&(-index); 

    }

    return sum;   

}

void update_bit(ll index,ll val,ll n){

     while(index < n){

         bit[index] += val;

         index += index&(-index);

     }

     return;

}
int find(ll mask,ll tar,ll index,ll n){

     if(index <0 || tar == 0){
         
         return mask;

     }

     //std::cout<<tar<<" "<<bit[mask|(1<<index)]<<" "<<(mask|(1<<index))<<'\n';

     if((mask|(1<<index)) < n && tar > bit[mask|(1<<index)] ){

        return find(mask|(1<<index),tar-bit[mask|(1<<index)],index -1,n);         

     } 
     else{
        

        return find(mask,tar,index -1,n);



     }


}

ll binary_search_1(ll start,ll end,vec<ll>& prefix,ll des){
 
     while(start - end > 1){

         ll mid = end + (start - end)/2;
 
         if(mid <= prefix[mid] - prefix[des]){
           
           start = mid;
            
         }
         else{

           end=mid;

            
         }
 
    }
 
    return start;
 
}

ll binary_search_2(ll start,ll end,vec<ll>& prefix){
 
     while(start - end > 1){

         ll mid = end + (start - end)/2;
 
         if(mid <= prefix[mid]){
           
           start = mid;
            
         }
         else{

           end=mid;

            
         }
 
    }
 
    return start;
 
}

namespace ranges
{
    template<typename Range, typename Generator>
    void generate(Range& range, Generator generator)
    {
        return std::generate(begin(range), end(range), generator);
    }
}

class RandomNumberBetween
{
public:
    RandomNumberBetween(int low, int high)
    : random_engine_{std::random_device{}()}
    , distribution_{low, high}
    {
    }
    int operator()()
    {
        return distribution_(random_engine_);
    }
private:
    std::mt19937 random_engine_;
    std::uniform_int_distribution<int> distribution_;
};

#include <limits.h>


void dfs_topo_2(vec<vec<ll> > &arr, vec<ll>& visited,ll a, vec< vec<ll> >&dis){ 

    std::list<ll> queue;

    visited[a] = 0;

    dis.push_back({a});

    queue.push_back(a); 
  
    while(!queue.empty()) 
    {  
        a = queue.front();

        queue.pop_front();

        for (ll i : arr[a]) 
        { 

            if (visited[i] == -1) 
            {

                visited[i] = visited[a] + 1;

                queue.push_back(i);

                while(dis.size() - 1 < visited[i]){

                    dis.push_back({});

                }

                dis[visited[i]].push_back(i);


            } 
        
        } 
    
    } 

}

void graph_input(vec< vec<ll> >&arr,ll& edj,ll& ver){

        edj = 19984650;//950327;

        ver = 0;

        vec< pair<ll,ll> >edjes(edj);

        for(int i=0;i<edj;i++){

            ll n ,m; in(n); in(m);

            ver = std::max(ver,std::max(n,m));

            edjes[i].first =n;

            edjes[i].second = m;   


        }

        ver += 1;

        arr = vec<vec<ll>>(ver);

        for(int i=0;i<edj;i++){

            ll n = edjes[i].first , m = edjes[i].second;

            arr[n].push_back(m);

            arr[m].push_back(n);   


        }


}
 
ll maxSubArraySum(vec<ll>& a) 
{ 
    ll max_so_far = INT_MIN, max_ending_here = 0;

    ll size = a.size(); 
  
    for (int i = 0; i < size; i++) 
    { 
        max_ending_here = max_ending_here + a[i];

        if (max_so_far < max_ending_here) 
            max_so_far = max_ending_here; 
  
        if (max_ending_here < 0) 
            max_ending_here = 0; 
    } 
    return max_so_far; 
}

 
bool check(vec<ll>& a,vec<ll>& b,ll number){

    ll last = number;

   for(ll i =1;i < a.size();i++){
          
       ll assign =  std::max(last + a[i] - b[i-1],(ll)0);

       if(assign >  b[i]){

           return false;

       }

       last = assign;

       if(i == a.size() -1 && assign != 0){
               
            return false;
         
       }

   }

   

   return true;


}

#define sort(a) std::sort(a.begin(),a.end());



ll max_n(ll i,ll j,ll n,ll m){

    ll count = 0;

    if(i+1 < n){

        count++;

    }

    if(i -1 >=0){

        count++;



    }

    if(j+1 <m){
        count++;
    }

    if(j- 1 >=0){
        count++;
    }

    return count;


}


ll sat(ll i,ll j,ll n,ll m,vec< vec<ll> >&v){

     ll count = 0;

    if(i+1 < n){

        if(v[i+1][j] != 0){

            count += 1;

        }

    }

    if(i -1 >=0){

        if(v[i-1][j] != 0) count++;



    }

    if(j+1 <m){
        if(v[i][j+1] != 0 ) count++;
    }

    if(j- 1 >=0){
        if(v[i][j-1] != 0) count++;
    }

    return count;





}

void set(ll i,ll j,ll n,ll m,vec< vec<ll> >&v, vec< vec<bool> >&des){

    if(i+1 < n){

        if(v[i+1][j] == 0){

            des[i+1][j] = false;

        }

    }

    if(i -1 >=0){

        if(v[i-1][j] == 0) des[i-1][j] =  false;



    }

    if(j+1 <m){
        if(v[i][j+1] == 0 ) des[i][j+1] = false;
    }

    if(j- 1 >=0){
        if(v[i][j-1] == 0) des[i][j-1] = false;
    }

    return ;





}

bool set2(ll i,ll j,ll n,ll m,vec< vec<ll> >&v, vec< vec<bool> >&des, ll number){

    ll count = number;

    if(count && i+1 < n){

        if(v[i+1][j] == 0 && des[i+1][j]){
              
              v[i+1][j] += 1;

              count--;
              
 
        }

    }

    if(count && i -1 >=0){

        if(v[i-1][j] == 0 && des[i-1][j]){
            v[i-1][j] += 1;

            count--;
        }



    }

    if(count && j+1 <m){
        if(v[i][j+1] == 0 && des[i][j+1]){
            v[i][j+1] += 1;
            count--;
        }
    }

    if(count && j- 1 >=0){
        if(v[i][j-1] == 0 && des[i][j-1]) {
            v[i][j-1] += 1;

            count--;
        }
    }

    if(count) return false;
    

    return true;





}

ll mex(vec<ll>&b){
     
     for(ll i =0;i<b.size();i++){

         if(b[i] == 0){
            return i;
         }  


     }


}



int main(){
    
    ll test_case  = 1; //in(test_case);

    while(test_case--){

        ll n; in(n); ll s; in(s);

        vec<ll>a; vec_in<ll>(a,n); 

        sort(a);

        ll num_positive = 0,num_zero = 0,num_negative = 0;

        for(ll i=0;i<n;i++){
            
            if(a[i] > 0) num_positive += 1;
            else if(a[i] == 0) num_zero += 1;
            else num_negative += 1;

        } 

        if(num_positive > 0){

            if(num_positive + num_negative >= s){

                ll i = n-std::min(s,num_positive), j = s - std::min(s,num_positive);

                if(j%2){
                   i++; j++;
                }

                while(i < n){

                    if(i +1 < n && j + 1 < n){

                        if(a[i+1] * a[i] < a[j+1]*a[j]){

                              i+= 2;

                              j+= 2; 

                        }
                        else{
                            break;
                        }




                    }
                    else{
                        break;
                    }



                }

                ll pro = 1; 

                ll prime = 1000000007;

                for(ll k=i;k<n;k++){
                   
                     pro *= a[k];

                     pro = (pro + prime)%prime;

                     pro %= prime;

                     pro = (pro + prime)%prime;


                }


                for(ll k= j-1;k >=0;k--){

                    pro *= a[k];

                    pro = (pro + prime)%prime;

                    pro %= prime;

                    pro = (pro + prime)%prime;


                }

                out(pro);
            }
            else{
                out(0);
            }

        }
        else if(num_positive == 0){

            if(num_zero == 0){
            
                if(s%2){
                    
                    ll pro = 1; 

                    ll prime = 1000000007;

                    for(ll k=n-1;k>=n-s;k--){
                       
                         pro *= a[k];

                         pro = (pro + prime)%prime;

                         pro %= prime;

                         pro = (pro + prime)%prime;


                    }

                    out(pro);


                }
                else{

                    ll pro = 1; 

                    ll prime = 1000000007;

                    for(ll k= 0 ;k < s;k++){
                       
                         pro *= a[k];

                         pro = (pro + prime)%prime;

                         pro %= prime;

                         pro = (pro + prime)%prime;


                    }

                    out(pro);




                }

            }
            else{

                if(s%2){

                    out(0);


                }
                else{

                    ll pro = 1; 

                    ll prime = 1000000007;

                    for(ll k= 0 ;k < s;k++){
                       
                         pro *= a[k];

                         pro = (pro + prime)%prime;

                         pro %= prime;

                         pro = (pro + prime)%prime;


                    }

                    out(pro);




                }

            }
 

        }


        






    }
}

        
         




    
 
 


Measured memory_bytes: 5380