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 C# (.NET Core 3.1.201) (judge verdict: Runtime Error)

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace AtCoder
{
	public class ABC
	{
		static public void Main(string[] args)
		{
			Console.SetOut(new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
			Solve();
			Console.Out.Flush();
		}

		const int mod = 1000000007;  // 10^9+7
		static int Mod(long x, int m) { return (int)((x % m + m) % m); }
		static long Mod(long x, long m) { return (x % m + m) % m; }

		static public void Solve()
		{
			//string s = Console.ReadLine();
			//int n = int.Parse(Console.ReadLine());
			//long x = long.Parse(Console.ReadLine());
			//int[] vs = Console.ReadLine().Split().Select(int.Parse).ToArray();
			//long[] vs = Console.ReadLine().Split().Select(long.Parse).ToArray();

			int[] vs = Console.ReadLine().Split().Select(int.Parse).ToArray();
			int n = vs[0];
			int k = vs[1];
			int[] a = Console.ReadLine().Split().Select(int.Parse).ToArray();

			long ans = 1;
			List<int> posi = new List<int>();
			List<int> nega = new List<int>();
			for (int i = 0; i < n; i++) {
				if (a[i] < 0) {
					nega.Add(a[i]);
				} else {
					posi.Add(a[i]);
				}
			}
			posi.Sort((x, y) => y.CompareTo(x));
			nega.Sort();
			System.Diagnostics.Debug.WriteLine(string.Join(" ", posi));
			System.Diagnostics.Debug.WriteLine(string.Join(" ", nega));
			System.Diagnostics.Debug.WriteLine("");

			if (nega.Count == 0) {
				for (int i = 0; i < k; i++) {
					ans = Mod(ans * posi[i], mod);
				}
			} else if (posi.Count == 0) {
				for (int i = 1; i <= k; i++) {
					ans = Mod(ans * nega[nega.Count - i], mod);
				}
			} else if (k == 1) {
				if (posi[0] > -nega[0]) {
					ans = Mod(posi[0], mod);
				} else {
					ans = Mod(nega[nega.Count - 1], mod);
				}
			} else {
				int pi = 0, ni = 0;
				for (int i = k; i > 0; i--) {
					if (i == 1) {
						if (posi.Count > pi) {
							ans = Mod(ans * posi[pi], mod);
							pi++;
						} else {
							ans = Mod(ans * nega[ni], mod);
							ni++;
						}
					} else if (i == 2) {
						if (posi.Count == pi + 1 && nega.Count == ni + 1) {
							ans = Mod(ans * posi[pi], mod);
							pi++;
							ans = Mod(ans * nega[ni], mod);
							ni++;
						} else if (nega.Count == ni + 1 || (posi.Count != pi + 1 && posi[pi] * posi[pi + 1] >= nega[ni] * nega[ni + 1])) {
							ans = Mod(ans * posi[pi], mod);
							pi++;
							ans = Mod(ans * posi[pi], mod);
							pi++;
						} else {
							ans = Mod(ans * nega[ni], mod);
							ni++;
							ans = Mod(ans * nega[ni], mod);
							ni++;
						}
						break;
					} else {
						if (posi[pi] * posi[pi + 1] >= nega[ni] * nega[ni + 1]) {
							ans = Mod(ans * posi[pi], mod);
							pi++;
						} else {
							ans = Mod(ans * nega[ni], mod);
							ni++;
							i--;
							ans = Mod(ans * nega[ni], mod);
							ni++;
						}
					}
				}
			}
			Console.WriteLine(ans);
		}
	}
}