#include <bits/stdc++.h>
using namespace std;
using LL = long long int;
#define incID(i, l, r) for(int i = (l)    ; i <  (r); ++i)
#define decID(i, l, r) for(int i = (r) - 1; i >= (l); --i)
#define incII(i, l, r) for(int i = (l)    ; i <= (r); ++i)
#define decII(i, l, r) for(int i = (r)    ; i >= (l); --i)
#define inc(i, n)  incID(i, 0, n)
#define dec(i, n)  decID(i, 0, n)
#define inc1(i, n) incII(i, 1, n)
#define dec1(i, n) decII(i, 1, n)
#define inID(v, l, r) ((l) <= (v) && (v) <  (r))
#define inII(v, l, r) ((l) <= (v) && (v) <= (r))
#define PB push_back
#define EB emplace_back
#define MP make_pair
#define MT make_tuple
#define FI first
#define SE second
#define FR front()
#define BA back()
#define ALL(v) v.begin(), v.end()
#define RALL(v) v.rbegin(), v.rend()
auto setmin   = [](auto & a, auto b) { return (b <  a ? a = b, true : false); };
auto setmax   = [](auto & a, auto b) { return (b >  a ? a = b, true : false); };
auto setmineq = [](auto & a, auto b) { return (b <= a ? a = b, true : false); };
auto setmaxeq = [](auto & a, auto b) { return (b >= a ? a = b, true : false); };
#define SI(v) static_cast<int>(v.size())
#define RF(e, v) for(auto & e: v)
#define until(e) while(! (e))
#define if_not(e) if(! (e))
#define ef else if
#define UR assert(false)
#define IN(T, ...) T __VA_ARGS__; IN_(__VA_ARGS__);
void IN_() { };
template<typename T, typename ... U> void IN_(T &  a, U &  ... b) { cin >> a; IN_(b ...); };
template<typename T                > void OUT(T && a            ) { cout << a << endl; }
template<typename T, typename ... U> void OUT(T && a, U && ... b) { cout << a << " "; OUT(b ...); }

// ---- ----

template<LL M> class ModInt {
private:
	LL v;
	pair<LL, LL> ext_gcd(LL a, LL b) {
		if(b == 0) { assert(a == 1); return { 1, 0 }; }
		auto p = ext_gcd(b, a % b);
		return { p.SE, p.FI - (a / b) * p.SE };
	}
public:
	ModInt(LL vv = 0) { v = vv; if(abs(v) >= M) { v %= M; } if(v < 0) { v += M; } }
	LL get_v() { return v; }
	ModInt inv() { return ext_gcd(M, v).SE; }
	ModInt exp(LL b) {
		ModInt p = 1, a = v; if(b < 0) { a = a.inv(); b = -b; }
		while(b) { if(b & 1) { p *= a; } a *= a; b >>= 1; }
		return p;
	}
	friend bool      operator< (ModInt    a, ModInt   b) { return (a.v <  b.v); }
	friend bool      operator> (ModInt    a, ModInt   b) { return (a.v >  b.v); }
	friend bool      operator<=(ModInt    a, ModInt   b) { return (a.v <= b.v); }
	friend bool      operator>=(ModInt    a, ModInt   b) { return (a.v >= b.v); }
	friend bool      operator==(ModInt    a, ModInt   b) { return (a.v == b.v); }
	friend bool      operator!=(ModInt    a, ModInt   b) { return (a.v != b.v); }
	friend ModInt    operator+ (ModInt    a            ) { return ModInt(+a.v); }
	friend ModInt    operator- (ModInt    a            ) { return ModInt(-a.v); }
	friend ModInt    operator+ (ModInt    a, ModInt   b) { return ModInt(a.v + b.v); }
	friend ModInt    operator- (ModInt    a, ModInt   b) { return ModInt(a.v - b.v); }
	friend ModInt    operator* (ModInt    a, ModInt   b) { return ModInt(a.v * b.v); }
	friend ModInt    operator/ (ModInt    a, ModInt   b) { return a * b.inv(); }
	friend ModInt    operator^ (ModInt    a, LL       b) { return a.exp(b); }
	friend ModInt  & operator+=(ModInt  & a, ModInt   b) { return (a = a + b); }
	friend ModInt  & operator-=(ModInt  & a, ModInt   b) { return (a = a - b); }
	friend ModInt  & operator*=(ModInt  & a, ModInt   b) { return (a = a * b); }
	friend ModInt  & operator/=(ModInt  & a, ModInt   b) { return (a = a / b); }
	friend ModInt  & operator^=(ModInt  & a, LL       b) { return (a = a ^ b); }
	friend istream & operator>>(istream & s, ModInt & b) { s >> b.v; b = ModInt(b.v); return s; }
	friend ostream & operator<<(ostream & s, ModInt   b) { return (s << b.v); }
};

// ----

using MI = ModInt<1'000'000'007>;

template<typename T> istream & operator>>(istream & s, vector<T> & v) { RF(e, v) { s >> e; } return s; }
template<typename T> ostream & operator<<(ostream & s, vector<T> const & v) {
	inc(i, SI(v)) { s << (i == 0 ? "" : " ") << v[i]; }
	return s;
}

template<typename T> class opt {
private:
	bool f;
	T v;
public:
	opt() { f = false; }
	opt(T v) : v(v) { f = true; }
	void reset() { f = false; }
	bool setmin  (T a) { return (! f || a <  v ? v = a, f = true : false); }
	bool setmax  (T a) { return (! f || a >  v ? v = a, f = true : false); }
	bool setmineq(T a) { return (! f || a <= v ? v = a, f = true : false); }
	bool setmaxeq(T a) { return (! f || a >= v ? v = a, f = true : false); }
	bool has_val() { return f; }
	bool is_null() { return ! f; }
	T & val() { assert(f); return v; }
	friend T operator||(opt a, T e) { return (a.f ? a.v : e); }
	friend istream & operator>>(istream & s, opt<T> & a) { a.f = true; return (s >> a.v); }
	friend ostream & operator<<(ostream & s, opt<T>   a) { return (a.f ? s << a.v : s << "[null]"); }
};

struct Frac {
	LL a, b;
	Frac(LL aa = 0, LL bb = 1) {
		a = aa; b = bb;
		if(b < 0) { a *= -1; b *= -1; }
		LL d = gcd(abs(a), b);
		a /= d; b /= d;
	}
	Frac exp(LL y) {
		Frac p = 1, e = (* this);
		if(y < 0) { e = 1 / e; y = -y; }
		while(y) { if(y & 1) { p *= e; } e *= e; y >>= 1; }
		return p;
	}
	friend bool   operator< (Frac   x, Frac y) { return (x.a * y.b <  y.a * x.b); }
	friend bool   operator> (Frac   x, Frac y) { return (x.a * y.b >  y.a * x.b); }
	friend bool   operator<=(Frac   x, Frac y) { return (x.a * y.b <= y.a * x.b); }
	friend bool   operator>=(Frac   x, Frac y) { return (x.a * y.b >= y.a * x.b); }
	friend bool   operator==(Frac   x, Frac y) { return (x.a * y.b == y.a * x.b); }
	friend bool   operator!=(Frac   x, Frac y) { return (x.a * y.b != y.a * x.b); }
	friend Frac   operator+ (Frac   x        ) { return Frac(+x.a, x.b); }
	friend Frac   operator- (Frac   x        ) { return Frac(-x.a, x.b); }
	friend Frac   operator+ (Frac   x, Frac y) { return Frac(x.a * y.b + y.a * x.b, x.b * y.b); }
	friend Frac   operator- (Frac   x, Frac y) { return Frac(x.a * y.b - y.a * x.b, x.b * y.b); }
	friend Frac   operator* (Frac   x, Frac y) { return Frac(x.a * y.a, x.b * y.b); }
	friend Frac   operator/ (Frac   x, Frac y) { return Frac(x.a * y.b, x.b * y.a); }
	friend Frac   operator^ (Frac   x, LL   y) { return x.exp(y); }
	friend Frac & operator+=(Frac & x, Frac y) { return (x = x + y); }
	friend Frac & operator-=(Frac & x, Frac y) { return (x = x - y); }
	friend Frac & operator*=(Frac & x, Frac y) { return (x = x * y); }
	friend Frac & operator/=(Frac & x, Frac y) { return (x = x / y); }
	friend Frac & operator^=(Frac & x, LL   y) { return (x = x ^ y); }
	friend istream & operator>>(istream & is, Frac & x) { x.b = 1; return (is >> x.a); }
	friend ostream & operator<<(ostream & os, Frac   x) { return (x.b == 1 ? os << x.a : os << x.a << "/" << x.b); }
};

// ----

int main() {
	IN(LL, n, k);
	vector<LL> a(n);
	cin >> a;
	
	auto sgn = [&](auto x) {
		if(x == 0) { return 0; }
		return (x > 0 ? +1 : -1);
	};
	
	vector<pair<LL, LL>> v;
	RF(e, a) { v.EB(abs(e), sgn(e)); }
	sort(ALL(v));
	
	MI mi = 1;
	inc(i, k) { mi *= v[i].FI; }
	
	reverse(ALL(v));
	MI ma = 1;
	LL s = +1;
	opt<LL> pmi, mmi, pma, mma;
	inc(i, n) {
		auto [A, S] = v[i];
		if(i < k) {
			ma *= A;
			s  *= S;
			if(S == +1) { pmi.setmin(A); }
			if(S == -1) { mmi.setmin(A); }
		} else {
			if(S == +1) { pma.setmax(A); }
			if(S == -1) { mma.setmax(A); }
		}
	}
	if(s == -1) {
		opt<Frac> r;
		if(pma.has_val() && mmi.has_val()) { r.setmax(Frac(pma.val(), mmi.val())); }
		if(mma.has_val() && pmi.has_val()) { r.setmax(Frac(mma.val(), pmi.val())); }
		if(r.has_val()) {
			ma *= r.val().a;
			ma /= r.val().b;
			s *= -1;
		}
	}
	
	if(s == -1) { OUT(-mi); } else { OUT(ma); }
}


Measured memory_bytes: 9036