// dfmt off
T lread(T=long)(){return readln.chomp.to!T;}T[] lreads(T=long)(long n){return iota(n).map!((_)=>lread!T).array;}
T[] aryread(T=long)(){return readln.split.to!(T[]);}void arywrite(T)(T a){a.map!text.join(' ').writeln;}
void scan(L...)(ref L A){auto l=readln.split;foreach(i,T;L){A[i]=l[i].to!T;}}alias sread=()=>readln.chomp();
void dprint(L...)(lazy L A){debug{auto l=new string[](L.length);static foreach(i,a;A)l[i]=a.text;arywrite(l);}}
static immutable MOD=10^^9+7;alias PQueue(T,alias l="b<a")=BinaryHeap!(Array!T,l);import std;
// dfmt on

void main()
{
    long N, K;
    scan(N, K);
    auto A = aryread();
    long p, n, z;
    foreach (a; A)
    {
        p += 0 < a;
        n += a < 0;
        z += a == 0;
    }
    A.sort();

    auto Nega = A[0 .. n];
    auto Zero = A[n .. n + z];
    auto Posi = A[n + z .. $];

    if (p + n < K)
    {
        writeln(0);
        return;
    }
    if (K == 1)
    {
        writeln((MOD + A.reduce!(max)) % MOD);
        return;
    }
    long ans = 1;
    if (n == 0)
    {
        foreach (x; Posi[$ - K .. $])
        {
            ans *= x;
            ans %= MOD;
        }
        writeln(ans);
        return;
    }
    if (n + z == N && z != 0)
    {
        writeln(0);
        return;
    }
    if (n + z == N && (K & 1))
    {
        foreach (x; Nega[$ - K .. $])
        {
            ans *= (MOD + x) % MOD;
            ans %= MOD;
        }
        writeln(ans);
        return;
    }
    if (n + z == N && !(K & 1))
    {
        foreach (x; Nega[0 .. K])
        {
            ans *= (MOD + x) % MOD;
            ans %= MOD;
        }
        writeln(ans);
        return;
    }
    assert(0 < p);
    assert(0 < n);
    assert(K <= p + n);
    if ((K & 1) && p < K)
    {
        ans = (Nega[0] * Nega[1]) % MOD;
        alias T = Tuple!(long, bool);
        T[] tmp;
        foreach (i; 0 .. p / 2)
        {
            tmp ~= T(Posi[$ - 1 - i * 2] * Posi[$ - 2 - i * 2], true);
        }
        foreach (i; 1 .. n / 2)
        {
            tmp ~= T(Nega[i * 2] * Nega[i * 2 + 1], false);
        }
        tmp.sort!"b<a"();
        long cnt;
        foreach (t; tmp[0 .. max(K / 2 - 1, 0)])
        {
            ans *= t[0] % MOD;
            ans %= MOD;
            cnt += t[1];
        }
        writeln(ans * Posi[$ - (cnt * 2 + 1)] % MOD);
        return;
    }
    if (K & 1)
    {
        alias T = Tuple!(long, bool);
        T[] tmp;
        foreach (i; 0 .. p / 2)
        {
            tmp ~= T(Posi[$ - 1 - i * 2] * Posi[$ - 2 - i * 2], true);
        }
        foreach (i; 0 .. n / 2)
        {
            tmp ~= T(Nega[i * 2] * Nega[i * 2 + 1], false);
        }
        tmp.sort!"b<a"();
        long cnt;
        foreach (t; tmp[0 .. max(K / 2, 0)])
        {
            ans *= t[0] % MOD;
            ans %= MOD;
            cnt += t[1];
        }
        writeln(ans * Posi[$ - (cnt * 2 + 1)] % MOD);
        return;
    }
    {
        alias T = Tuple!(long, bool);
        T[] tmp;
        foreach (i; 0 .. p / 2)
        {
            tmp ~= T(Posi[$ - 1 - i * 2] * Posi[$ - 2 - i * 2], true);
        }
        foreach (i; 0 .. n / 2)
        {
            tmp ~= T(Nega[i * 2] * Nega[i * 2 + 1], false);
        }
        tmp.sort!"b<a"();
        long cnt;
        foreach (t; tmp[0 .. max(K / 2, 0)])
        {
            ans *= t[0] % MOD;
            ans %= MOD;
            cnt += t[1];
        }
        writeln(ans);
        return;
    }
}
