/* {{{ */ #if __has_include(".precompiled/my_template.h") && !defined(MY_IDE)
#include ".precompiled/my_template.h"
#else
#include <bits/stdc++.h>

namespace utils{
using namespace std;
constexpr bool use_stdio = false;
ostream* out = &cout;
FILE* stdio_out = stdout;
const bool __ = [](){ if constexpr(!use_stdio){ ios_base::sync_with_stdio(false); cin.tie(nullptr);
  cout << fixed; cout << setprecision(12); cerr << fixed; cerr << setprecision(12); } return true; }();
template<typename ...> using to_void = void;
template<typename T, typename = void> struct is_container : false_type {};
template<typename T> struct is_container<T, to_void<decltype(declval<T>().begin()), decltype(declval<T>().end())>> : true_type {};
template<typename V, typename N> struct resize { V& v; function<N()> n;
  resize(V& vv, function<N()> nn) : v(vv), n(nn) {} ~resize() { v.resize(n()); } };

inline void rd(int& x) { if constexpr(use_stdio) scanf("%d", &x); else cin >> x; }
inline void rd(long long& x) { if constexpr(use_stdio) scanf("%lld", &x); else cin >> x; }
inline void rd(double& x) { if constexpr(use_stdio) scanf("%lf", &x); else cin >> x; }
inline void rd(long double& x) { if constexpr(use_stdio){ double y; scanf("%lf", &y); x=y; } else cin >> x; }
inline void rd(char& x) { if constexpr(use_stdio) scanf(" %c", &x); else cin >> x; }
inline void rd(char* x) { if constexpr(use_stdio) scanf("%s", x); else cin >> x; }
inline void rd(string& x) { if constexpr(use_stdio) assert(false); else cin >> x; }
template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void rd(T& x) { cin >> x; }
template<typename T> inline void rd(T* x);
template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x);
template<typename... Ts> inline void rd(tuple<Ts...>& x);
template<typename V, typename N> inline void rd(const resize<V, N>& x);
template<typename T, typename U> inline void rd(pair<T, U>& x) { rd(x.first); rd(x.second); }
template<typename V, typename N> inline void rd(const resize<V, N>& x) { const_cast<V&>(x.v).resize(x.n()); rd(x.v); }
template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void rd(T& x) { for(auto& v : x) rd(v); }
template<typename T, typename U, typename... Ts> inline void rd(T&& t, U&& u, Ts&&... ts) {
  rd(forward<T>(t)); rd(forward<U>(u), forward<Ts>(ts)...); }
template<typename... Ts> inline void rd(tuple<Ts...>& x) { static_assert(sizeof...(Ts) > 0);
  constexpr auto apply_rd = [](auto&&... xs) { rd(xs...); }; apply(apply_rd, x); }
template<typename T> inline void rd(T* x) { rd(*x); }

inline void prt(const int& x) { if constexpr(use_stdio) fprintf(stdio_out, "%d", x); else *out << x; }
inline void prt(const long long& x) { if constexpr(use_stdio) fprintf(stdio_out, "%lld", x); else *out << x; }
inline void prt(const double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", x); else *out << x; }
inline void prt(const long double& x) { if constexpr(use_stdio) fprintf(stdio_out, "%.12f", (double)x); else *out << x; }
inline void prt(const char& x) { if constexpr(use_stdio) fprintf(stdio_out, "%c", x); else *out << x; }
inline void prt(const char* x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x); else *out << x; }
inline void prt(const string &x) { if constexpr(use_stdio) fprintf(stdio_out, "%s", x.c_str()); else *out << x; }
template<typename T, typename enable_if<!use_stdio && is_integral<T>::value>::type* = nullptr> inline void prt(const T& x) { *out << x; }
template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x);
template<typename... Ts> inline void prt(const tuple<Ts...>& x);
template<typename T, typename U> inline void prt(const pair<T, U>& x) { prt(x.first); prt(' '); prt(x.second); }
template<typename T, typename enable_if<is_container<T>::value>::type* = nullptr> inline void prt(const T& x) {
  if (x.begin() != x.end()) { prt(*x.begin()); for(auto it = x.begin(); ++it != x.end(); ) { prt(' '); prt(*it); } } }
template<typename T, typename U, typename... Ts> inline void prt(T&& t, U&& u, Ts&&... ts) {
  prt(forward<T>(t)); prt(' '); prt(forward<U>(u), forward<Ts>(ts)...); }
template<typename... Ts> inline void prt(const tuple<Ts...>& x ) { static_assert(sizeof...(Ts) > 0);
  constexpr auto apply_prt = [](auto&&... xs) { prt(xs...); }; apply(apply_prt, x); }
inline void wt() { prt('\n'); }
template<typename... Ts> inline void wt(Ts&&... ts) { prt(forward<Ts>(ts)...); wt(); }

#ifdef MY_DEBUG_FLAG
inline void enter_db() { if constexpr(use_stdio) stdio_out = stderr; else out = &cerr; }
inline void leave_db() { if constexpr(use_stdio) stdio_out = stdout; else out = &cout; }
inline void db() { enter_db(); prt('\n'); leave_db(); }
template<typename... Ts> inline void db(Ts&&... ts) { enter_db(); prt(forward<Ts>(ts)...); wt(); leave_db(); }
#define db(...) utils::db("Debug(", #__VA_ARGS__, ") == (", __VA_ARGS__, ")")
#else
#define db(...)
#endif // define(MY_DEBUG_FLAG)
inline int slen(char*s){ return (int) strlen(s); }
inline void flush() { if constexpr(use_stdio) fflush(stdout); else cout << std::flush; }
}
#endif // __has_include(".precompiled/my_template.h")
using namespace std; /* }}} */

/* {{{ */ using ll = long long;
using ld = long double;
using pii = pair<int, int>;
using vi = vector<int>;
using utils::rd, utils::prt, utils::wt, utils::slen, utils::flush;

#ifdef MY_DEBUG_FLAG
#define assertd(...) assert(__VA_ARGS__)
#else
#define assertd(...)
#endif // define(MY_DEBUG_FLAG)

#define pb emplace_back
#define x first
#define y second
#define sz(a) ((int)(a).size())
#define rep(i,a,b) for(int i=(a); i<(b); i++)
#define dec(i,n,a) for(int i=(n); i>=(a); i--)
#define clr(a,v) memset(a, v, sizeof(a))
#define all(a) (a).begin(),(a).end()
#define resz(v, n) utils::resize<decltype(v), decltype(n)>(v, [&](){ return (n); }) /* }}} */

constexpr int inf = 0x3f3f3f3f;
constexpr ld eps = 1e-9;
constexpr int maxn = 2e5 + 10;
constexpr ll mod = 1000000007;

void solve() {
  int n, k;
  vector<ll> vet;
  rd(n, k, resz(vet, n));
  vector<ll> pos, neg;
  for (auto v : vet) if (v > 0) pos.pb(v); else if (v < 0) neg.pb(v);
  if (sz(neg) + sz(pos) < k) {
    wt(0);
    return;
  }
  if (k == sz(pos) + sz(neg) && k < n && (sz(neg)&1)) {
    wt(0);
    return;
  }
  if (pos.empty() && (k&1) && sz(pos) + sz(neg) != n) {
    wt(0);
    return;
  }
  if ((pos.empty() && (k&1)) || (k == sz(pos) + sz(neg) && (sz(neg)&1))) {
    sort(all(neg));
    reverse(all(neg));
    ll ans = 1;
    for (ll v : pos) ans = ans*v%mod;
    rep(i,0,k-sz(pos)) ans = (ans*neg[i]%mod + mod);
    wt(ans);
    return;
  }
  sort(all(pos));
  reverse(all(pos));
  sort(all(neg));
  rep(i,0,sz(neg)) neg[i] *= -1;
  vector<ld> logp(sz(pos)), logn(sz(neg));
  auto prep = pos, pren = neg;
  if (!pos.empty()) logp[0] = log(pos[0]);
  if (!neg.empty()) logn[0] = log(neg[0]);
  rep(i,1,sz(pos)) prep[i] = prep[i] * prep[i-1] % mod, logp[i] = log(pos[i]) + logp[i - 1];
  rep(i,1,sz(neg)) pren[i] = pren[i] * pren[i-1] % mod, logn[i] = log(neg[i]) + logn[i - 1];
  ll ans = 0;
  ld lgans = -inf;
  rep(i,0,k/2+1) {
    int qn = 2 * i;
    if (qn <= sz(neg) && k - qn <= sz(pos)) {
      ld cur = (qn == 0 ? (ld) 0 : logn[qn - 1]) + (k == qn ? (ld) 0 : logp[k - qn - 1]);
      if (lgans < cur) {
        lgans = cur;
        ans = (qn == 0 ? 1LL : pren[qn - 1]) * (k == qn ? 1LL : prep[k - qn - 1]) % mod;
      }
    }
  }
  wt(ans);
}

int main() {
  int test_count = 1;
  // rd(test_count);
  while (test_count--) solve();
}



Measured memory_bytes: 11168