Problem:
Score : 500 points

Problem Statement

Given are N integers A_1,\ldots,A_N.

We will choose exactly K of these elements. Find the maximum possible product of the chosen elements.

Then, print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Constraints

1 \leq K \leq N \leq 2\times 10^5

|A_i| \leq 10^9

Input

Input is given from Standard Input in the following format:

N K
A_1 \ldots A_N

Output

Print the maximum product modulo (10^9+7), using an integer between 0 and 10^9+6 (inclusive).

Sample Input 1

4 2
1 2 -3 -4

Sample Output 1

12

The possible products of the two chosen elements are 2, -3, -4, -6, -8, and 12, so the maximum product is 12.

Sample Input 2

4 3
-1 -2 -3 -4

Sample Output 2

1000000001

The possible products of the three chosen elements are -24, -12, -8, and -6, so the maximum product is -6.

We print this value modulo (10^9+7), that is, 1000000001.

Sample Input 3

2 1
-1 1000000000

Sample Output 3

1000000000

The possible products of the one chosen element are -1 and 1000000000, so the maximum product is 1000000000.

Sample Input 4

10 10
1000000000 100000000 10000000 1000000 100000 10000 1000 100 10 1

Sample Output 4

999983200

Be sure to print the product modulo (10^9+7).

Solution in Rust (1.42.0) (judge verdict: Runtime Error)

#![allow(unused_imports)]
#![allow(clippy::many_single_char_names)]

// language: Rust(1.42.0)
// check available crates on AtCoder at "https://atcoder.jp/contests/language-test-202001"
// My Library Repo' is at "https://github.com/Loptall/prcn_lib"

/*
    そう甘くはないんだな〜w
*/

// from std...
use std::cmp::{
    max, min, Ordering,
    Ordering::{Equal, Greater, Less},
    Reverse,
};
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
use std::convert::TryInto;
use std::mem::swap;
use std::num::{NonZeroU32, ParseIntError};
use std::ops::{
    Add, AddAssign, BitAnd, BitAndAssign, BitOr, BitOrAssign, BitXor, BitXorAssign, Div, DivAssign,
    Index, IndexMut, Mul, MulAssign, Neg, Rem, RemAssign, Shl, ShlAssign, Shr, ShrAssign, Sub,
    SubAssign,
};
use std::process::exit;
use std::{f32, f64, i128, i16, i32, i64, i8, isize, u128, u16, u32, u64, u8, usize};

// Dep' crates are...
use itertools::*;
use itertools_num::*;
use lazy_static::lazy_static;
use maplit::{btreemap, btreeset, hashmap, hashset};
use num_bigint::{BigInt, BigUint};
use num_complex::Complex;
use num_integer::{binomial, gcd, lcm, multinomial, Integer};
use num_rational::Rational;
use num_traits::{clamp, one, pow, zero, Num, NumAssignOps, NumOps, One, Pow, Zero};
use permutohedron::Heap;
use proconio::{
    fastout, input, is_stdin_empty,
    marker::{Bytes, Chars, Isize1, Usize1},
};
use rand::random;

pub const MOD10E9_7: i64 = 1000000007;
pub const MOD99_: usize = 998244353;
pub const MAX: usize = std::usize::MAX;
pub const PI: f64 = f64::consts::PI;
pub const A: u8 = 65;

// code...
// #[fastout]
fn main() {
    input! {
        n: usize, k: usize,
        mut a: [i64; n]
    }

    a.sort_by_key(|x| x.abs());

    if k == n {
        let mut i = 1;
        for e in a {
            i *= e;
            // dbg!(i);
            i %= MOD10E9_7;
        }
        if i < 0 {
            i += MOD10E9_7;
        }
        println!("{}", i);
    } else if a.iter().all(|x| *x < 0) && k.is_odd() {
        let mut i = 1;
        for e in a.into_iter().take(k) {
            i *= e;
            i %= MOD10E9_7;
        }
        if i < 0 {
            i += MOD10E9_7;
        }
        println!("{}", i);
    } else {
        let mut i = 1;
        let mut used = HashSet::new();
        for e in a.iter().rev().take(k) {
            used.insert(e);
            i *= e;
            // dbg!(i);
            i %= MOD10E9_7;
        }

        if i >= 0 {
            println!("{}", i);
        } else {
            let p = {
                let x = a.iter().find(|z| used.contains(*z) && **z >= 0).unwrap();
                let y = a.iter().rfind(|z| !used.contains(*z) && **z < 0).unwrap();
                i / x * y
            };
            let q = {
                let x = a.iter().rfind(|z| !used.contains(*z) && **z >= 0).unwrap();
                let y = a.iter().find(|z| used.contains(*z) && **z < 0).unwrap();
                i / y * x
            };

            let mut ans = max(p, q) % MOD10E9_7;
            if ans < 0 {
                ans += MOD10E9_7;
            }
            println!("{}", ans);
        }
    }
}