#include <iostream>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <bitset>
#include <algorithm>
#include <cmath>
#include <tuple>
#include <climits>
#include <stdlib.h>
#include <queue>
#include <stack>


#define mp make_pair
#define pb push_back
#define forn(n) for(long long i=0;i<n;++i)
#define fast ios::sync_with_stdio(false), cin.tie(0)

#define ll long long
#define ull unsigned long long
#define mod 1000000007
typedef long double ld;
using namespace std;





ll reverse(ll n)
{
	ll s=0;
	while(n>0)
	{
       ll t=n%10;
	   s=s*10+t;
	   n/=10;
	}
	return s;
}
int count_setbits(int N)

{ int cnt=0;

while(N>0)

{

cnt+=(N&1);

N=N>>1;

}

return cnt;

}
ll power(ll x, ll y)  
{  
    int res = 1;     // Initialize result  
  
    x = x % mod; // Update x if it is more than or  
                // equal to p 
   
    if (x == 0) return 0; // In case x is divisible by p; 
  
    while (y > 0)  
    {  
        // If y is odd, multiply x with result  
        if (y & 1)  
            res = (res*x) % mod;  
  
        // y must be even now  
        y = y>>1; // y = y/2  
        x = (x*x) % mod;  
    }  
    return res;  
}  


  
   
/* 

to find the farthest node from root using dfs and its distance from root, we have to just 
change the dfs function a bit

void dfs(ll node,ll dis)
{
    vis[node]=true;
    // for any processing of the node, like printing it, please do it here
    if(dis>maxd)
    {
        maxd=dis;maxnode=node;
    }


    for(ll i=0;i<adj[node].size();i++)
    {
        ll child=adj[node][i];
        if(!vis[child])
        dfs(child,dis+1);

    }
}

*/
void radix_sort(vector< pair< pair<ll,ll>,ll> > &a)
{
    {
   ll n=a.size();
   vector<ll> cnt(n);
   for(auto x:a)
   {
       cnt[x.first.second]++;
   }
   vector< pair< pair<ll,ll>,ll> > a_new(n);
   vector<ll> pos(n);
   pos[0]=0;
   for(ll i=1;i<n;i++)
   pos[i]=pos[i-1]+cnt[i-1];
   for(auto x:a)
   {
       ll i=x.first.second;
       a_new[pos[i]]=x;
       pos[i]++;
   }
   a=a_new;
    }
    {
   ll n=a.size();
   vector<ll> cnt(n);
   for(auto x:a)
   {
       cnt[x.first.first]++;
   }
   vector< pair< pair<ll,ll>,ll> > a_new(n);
   vector<ll> pos(n);
   pos[0]=0;
   for(ll i=1;i<n;i++)
   pos[i]=pos[i-1]+cnt[i-1];
   for(auto x:a)
   {
       ll i=x.first.first;
       a_new[pos[i]]=x;
       pos[i]++;
   }
    
   a=a_new;
    }



}
vector<ll> suffix_array(string s)
{
   s+="$";
   ll n=s.size();
   vector<ll> p(n),c(n); // p is position array, c is equivalence array

   // if k==0
   vector< pair<char,ll> > a(n);
   for(ll i=0;i<n;i++)
   a[i]=make_pair(s[i],i);
   sort(a.begin(),a.end());
   for(ll i=0;i<n;i++)
   {
       p[i]=a[i].second;
   }
   c[p[0]]=0;
   for(ll i=1;i<n;i++)
   {
       if(a[i].first==a[i-1].first)
       c[p[i]]=c[p[i-1]];
       else
       {
           c[p[i]]=c[p[i-1]]+1;
       }
       
   }

   ll k=0;
   while((1<<k)<n)
   {
      vector< pair< pair<ll,ll>,ll> > a(n); // first pair will be equivalence class, second number of pair is index
      for(ll i=0; i<n;i++)
      {
          a[i]=make_pair(make_pair(c[i],c[(i+(1<<k))%n]),i);
      }
      radix_sort(a);
      for(ll i=0;i<n;i++)
   {
       p[i]=a[i].second;
   }
   c[p[0]]=0;
   for(ll i=1;i<n;i++)
   {
       if(a[i].first==a[i-1].first)
       c[p[i]]=c[p[i-1]];
       else
       {
           c[p[i]]=c[p[i-1]]+1;
       }
       
   }
k++;
   }
   return p;



}

bool vis[1000001];
ll dist[1000001];
int color[1000001];


vector<ll> adj[1000001];
vector<ll> edges;
ll maxd,maxnode;


void dfs(ll node)
{
    stack<ll> s;
    vis[node]=true;
    s.push(node);
    // for any processing of the node, like printing it, please do it here
    dist[node]=0;
   while(!s.empty())
   {
      ll curr=s.top();
      s.pop();
      for(ll i:adj[curr])
      {
          if(!vis[i])
        {
            s.push(i);
            vis[i]=1;
            dist[i]=dist[curr]+1;
        }
      }
     
   }  
}
void bfs(ll node)
{
    queue<ll> q;
    q.push(node);
    vis[node]=1;
    dist[node]=0;

    while(!q.empty())
    {
        ll curr=q.front();
        q.pop();

        for(ll i:adj[curr])
        {
            if(vis[i]==0)
            {
                q.push(i);
                dist[i]=dist[curr]+1;
                vis[i]=1;
            }
        }
    }
}

bool dfs_bipartite_check(ll node,int c)
{
    vis[node]=1;
    color[node]=c;
    for(ll i:adj[node])
    {
        if(vis[i]==0)
        {
           if(dfs_bipartite_check(i,c^1)==false) // if not visited, dfs call
           return false;
        }
        else
        {
            if(color[node]==color[i]) // if visited then check equality of colors
            return false;
        }
        
    }
    return true;
}

ll subsize[1000001];
ll subtree_size(ll node)
{
    vis[node]=1;
    ll curr_size=1;
    for(ll i=0;i<adj[node].size();i++)
    {
        ll child=adj[node][i];
        if(vis[child]==0)
        {
            curr_size+=subtree_size(child); // dfs call when child is not visited
        }

    }
    subsize[node]=curr_size;    // update size of subtree of the current node
    return curr_size;  // return size of subtree of the current node
    
}



bool cycle_detect(ll node,ll parent)
{
    vis[node]=1;
    for(ll child:adj[node])
    {
        if(vis[child]==0) {          // if not visited, make dfs call, and return true if dfs returns true
        if(cycle_detect(child,node))
        return true;
        }
        else
        {
            if(child!=parent)         // check if visited child is parent of current node or ancestor of current node
            return true; // returns true if child is ancestor and not parent of current node
        }
        
    }
    return false;
}

// for graph questions having multiple test cases, dont forget to clear adjacency list and clear visited array 
/* Just add these lines in each testcases

       for(ll i=1;i<=nodes;i++)
       adj[i].clear(),vis[i]=0;

*/

ull countBits(ull number) 
{       
      // log function in base 2  
      // take only integer part 
      return (ull)log2(number)+1; 
} 

// 2 4 6 8 1 3 7
// 8  6 7 
int main()
{
  fast;
  ll n,k;
  cin>>n>>k;
  bool pos_pres=false;
  vector<ll> a(n);ll maxm=INT_MIN;
  forn(n)
  {cin>>a[i];if(a[i]>maxm)maxm=a[i];
  
  }
  if(maxm==0 && k%2==1)
  {
      cout<<0<<"\n";
      return 0; 
  }
  if(maxm<0 && k%2==1)
  {
      ll product=1;
      sort(a.begin(),a.end());int ctr=n-1;
      while(k--)
      {
        product=((product%mod)*(a[ctr--]%mod))%mod;
      }
      cout<<mod+(product%mod)<<"\n";
      return 0;
  }
  if(k%2==0)
  {
    sort(a.begin(), a.end());
    ll left=0;ll right=n-1;ll ans=1;
    while(k>0)
    {
        ll p1=a[left]*a[left+1];
        ll p2=a[right]*a[right-1];
        
        if(p1>p2)
        {
            ans=((ans%mod)*(p1%mod))%mod;left+=2;
        }
        else
        {
            ans=((ans%mod)*(p2%mod))%mod;right-=2;
        }
        k-=2;
        
    }
     if(ans<0)
        cout<<mod+(ans%mod)<<"\n";
        else
        {
            cout<<(ans%mod)<<"\n";
        }
        
  
        return 0;

  }
  else
  {
      sort(a.begin(), a.end());
    ll left=0;ll right=n-2;ll ans=a[n-1];k--;
    while(k>0)
    {
        ll p1=a[left]*a[left+1];
        ll p2=a[right]*a[right-1];
        k-=2;
        if(p1>p2)
        {
            ans=((ans%mod)*(p1%mod))%mod;left+=2;
        }
        else
        {
            ans=((ans%mod)*(p2%mod))%mod;right-=2;
        }
        
    }
     if(ans<0)
        cout<<mod+(ans%mod)<<"\n";
        else
        {
            cout<<(ans%mod)<<"\n";
        }
  }
  




}


Measured memory_bytes: 27880