Problem p02616 (C++) — buggy submission, verdict: Runtime Error

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Alexander Agulenko
 */

#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iostream>

/**
 *  This solution uses cpplib (prewritten code library)
 *  More info: https://github.com/agul/algolib/tree/master/cpplib
 */

#pragma comment(linker, "/STACK:66777216")
#pragma warning(disable : 4996)
#define _USE_MATH_DEFINES
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#pragma hdrstop

// todo[c++17]: replace with std::disjunction_v
template <bool... Bools> struct Disjunction : std::false_type {};

template <bool First, bool... Others>
// todo[c++14] use bool_constant
struct Disjunction<First, Others...>
    : std::integral_constant<bool, First || Disjunction<Others...>::value> {};

#if __cplusplus >= 201703L
template <bool... Bools>
constexpr bool DisjunctionV = Disjunction<Bools...>::value;

static_assert(!DisjunctionV<>, "");
static_assert(!DisjunctionV<false, false>, "");
static_assert(DisjunctionV<true>, "");
static_assert(DisjunctionV<false, true>, "");
static_assert(DisjunctionV<true, false>, "");
static_assert(DisjunctionV<false, false, true, true>, "");
#endif

#include <iterator>

template <typename T>
constexpr auto has_begin(int) -> decltype(std::begin(std::declval<T>()), true) {
  return true;
}

template <typename T> constexpr bool has_begin(...) { return false; }

template <typename T>
using is_container = std::integral_constant<bool, has_begin<T>(0)>;

template <typename T, typename... Types>
// todo[c++17] use is_same_v
// todo[c++17] use variable template
using is_one_of = Disjunction<std::is_same<T, Types>::value...>;

// todo[c++14] use remove_cv_t
// todo[c++17] use is_integral_v
// todo[c++17] use  variable template
template <typename T>
using is_sane_integer = std::integral_constant<
    bool,
    std::is_integral<T>::value &&
        !is_one_of<typename std::remove_cv<T>::type, char, signed char,
                   unsigned char, bool, char16_t, char32_t, wchar_t>::value>;

std::string to_string(const std::string &s) { return '"' + s + '"'; }

std::string to_string(const char *s) { return to_string(std::string(s)); }

std::string to_string(const char ch) { return {'\\'', ch, '\\''}; }

std::string to_string(const bool b) { return (b ? "true" : "false"); }

template <typename T,
          typename std::enable_if<Disjunction<
              is_sane_integer<T>::value,
              std::is_floating_point<T>::value>::value>::type * = nullptr>
std::string to_string(const T value) {
  return std::to_string(value);
}

template <typename A, typename B>
std::string to_string(const std::pair<A, B> &);

template <typename T,
          typename std::enable_if<is_container<T>::value>::type * = nullptr>
std::string to_string(const T &container) {
  bool is_first = true;
  std::string res = "{";
  for (const auto &x : container) {
    if (!is_first) {
      res += ", ";
    }
    is_first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
std::string to_string(const std::pair<A, B> &p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

std::vector<std::string> vec_splitter(std::string s) {
  s += ',';
  std::vector<std::string> res;
  while (!s.empty()) {
    const size_t pos = s.find(',');
    res.emplace_back(s.substr(0, pos));
    s = s.substr(pos + 1);
  }
  return res;
}

void debug_out(std::vector<std::string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  std::cerr << std::endl;
}

template <typename Head, typename... Tail>
void debug_out(std::vector<std::string> args, int idx, int LINE_NUM, Head H,
               Tail... T) {
  std::stringstream ss;
  ss << to_string(H);
  if (idx > 0) {
    std::cerr << ", ";
  } else {
    std::cerr << "Line(" << LINE_NUM << ") ";
  }
  const std::string &arg = args[idx];
  const std::string value = ss.str();
  if (arg == value) {
    std::cerr << arg;
  } else {
    std::cerr << arg << " = " << value;
  }
  debug_out(args, idx + 1, LINE_NUM, T...);
}

#ifdef HOME
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

namespace std {

template <typename T>
std::istream &operator>>(std::istream &in, std::vector<T> &vec) {
  for (auto &it : vec) {
    in >> it;
  }
  return in;
}

template <typename T, typename U>
std::istream &operator>>(std::istream &in, std::pair<T, U> &rhs) {
  in >> rhs.first >> rhs.second;
  return in;
}

} // namespace std

void assign_files_input_txt() {
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
}

#include <cstddef>

template <typename T>
class IntegerIterator
    : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T *, T> {
public:
  using value_type = T;

  constexpr explicit IntegerIterator(const value_type value) : value_(value) {}

  IntegerIterator &operator++() {
    ++value_;
    return *this;
  }

  IntegerIterator operator++(int) {
    IntegerIterator copy = *this;
    ++value_;
    return copy;
  }

  IntegerIterator &operator--() {
    --value_;
    return *this;
  }

  IntegerIterator operator--(int) {
    IntegerIterator copy = *this;
    --value_;
    return copy;
  }

  constexpr value_type operator*() const { return value_; }

  constexpr bool operator==(const IntegerIterator rhs) const {
    return value_ == rhs.value_;
  }

  constexpr bool operator!=(const IntegerIterator rhs) const {
    return !(*this == rhs);
  }

  constexpr value_type operator+(const IntegerIterator rhs) const {
    return value_ + rhs.value_;
  }

  IntegerIterator &operator+=(const IntegerIterator rhs) const {
    value_ += rhs.value_;
    return *this;
  }

  constexpr value_type operator-(const IntegerIterator rhs) const {
    return value_ - rhs.value_;
  }

  IntegerIterator &operator-=(const IntegerIterator rhs) const {
    value_ -= rhs.value_;
    return *this;
  }

private:
  value_type value_;
};

template <typename T> class IntegerRange {
public:
  using const_iterator = IntegerIterator<T>;

  constexpr IntegerRange(const T begin, const T end)
      : begin_(begin), end_(end) {}

  constexpr const_iterator begin() const { return const_iterator(begin_); }

  constexpr const_iterator end() const { return const_iterator(end_); }

  constexpr T size() const { return end_ - begin_; }

private:
  T begin_;
  T end_;
};

template <typename T> class ReversedRange {
public:
  using const_iterator = typename std::decay<T>::type::const_iterator;
  using reverse_iterator = std::reverse_iterator<const_iterator>;

  explicit constexpr ReversedRange(const T &iterable)
      : begin_(iterable.begin()), end_(iterable.end()) {}

  constexpr reverse_iterator begin() const { return reverse_iterator(end_); }

  constexpr reverse_iterator end() const { return reverse_iterator(begin_); }

private:
  const_iterator begin_;
  const_iterator end_;
};

template <typename T> ReversedRange<T> reversed(T &&iterable) {
  return ReversedRange<T>{iterable};
}

template <typename T> constexpr IntegerRange<T> range(const T to) {
  return IntegerRange<T>(0, to);
}

template <typename T>
constexpr IntegerRange<T> range(const T from, const T to) {
  return IntegerRange<T>(from, to);
}

template <typename T> constexpr IntegerRange<T> inclusiveRange(const T to) {
  return IntegerRange<T>(0, to + 1);
}

template <typename T>
constexpr IntegerRange<T> inclusiveRange(const T from, const T to) {
  return IntegerRange<T>(from, to + 1);
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> downrange(const T from) {
  return reversed(range(from));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> downrange(const T from, const T to) {
  return reversed(range(to, from));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> inclusiveDownrange(const T from) {
  return reversed(range(from + 1));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> inclusiveDownrange(const T from,
                                                            const T to) {
  return reversed(range(to, from + 1));
}

template <typename R> void sort(R &range) {
  std::sort(range.begin(), range.end());
}

template <typename R, typename Comp> void sort(R &range, Comp comp) {
  std::sort(range.begin(), range.end(), comp);
}

template <typename R> void reverse(R &range) {
  std::reverse(range.begin(), range.end());
}

template <typename R, typename T>
auto lower_bound(const R &range, const T &value) -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value);
}

template <typename R, typename T, typename Comp>
auto lower_bound(const R &range, const T &value, Comp comp)
    -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value, comp);
}

template <typename R, typename T>
auto upper_bound(const R &range, const T &value) -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value);
}

template <typename R, typename T, typename Comp>
auto upper_bound(const R &range, const T &value, Comp comp)
    -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value, comp);
}

template <typename R>
auto min_element(const R &range) -> decltype(range.begin()) {
  return std::min_element(range.begin(), range.end());
}

template <typename R>
auto max_element(const R &range) -> decltype(range.begin()) {
  return std::max_element(range.begin(), range.end());
}

template <typename R> bool next_permutation(R &range) {
  return std::next_permutation(range.begin(), range.end());
}

template <typename T> void unique(std::vector<T> &range) {
  range.erase(std::unique(range.begin(), range.end()), range.end());
}

template <typename T> void dedup(std::vector<T> &range) {
  sort(range);
  unique(range);
}

template <typename R> R sorted(R range) {
  sort(range);
  return range;
}

template <typename R, typename Comp> R sorted(R range, Comp comp) {
  sort(range, comp);
  return range;
}

static constexpr long double PI = 3.14159265358979323846;
static constexpr long double EPS = 1e-9;
static constexpr int32_t INF = 0x3f3f3f3f;
static constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;

static constexpr int32_t DX[8] = {-1, 0, 1, 0, -1, -1, 1, 1};
static constexpr int32_t DY[8] = {0, 1, 0, -1, -1, 1, 1, -1};

static constexpr uint32_t kDayMonth[12] = {31, 28, 31, 30, 31, 30,
                                           31, 31, 30, 31, 30, 31};

enum Direction : uint8_t {
  Up,
  Right,
  Down,
  Left,
  UpLeft,
  UpRight,
  DownRight,
  DownLeft,
  North = Up,
  East = Right,
  South = Down,
  West = Left,
  NorthWest = UpLeft,
  NorthEast = UpRight,
  SouthEast = DownRight,
  SouthWest = DownLeft,
  Unknown = 255
};

#include <cstdint>

namespace Random {

inline std::chrono::system_clock::rep current_timestamp() {
  return std::chrono::system_clock::now().time_since_epoch().count();
}

inline uint64_t get_new_rand_seed() {
  return static_cast<uint64_t>(current_timestamp());
}

inline uint64_t get_rand_seed() {
  static const uint64_t kRandSeed = get_new_rand_seed();
  return kRandSeed;
}

using Engine = std::mt19937_64;

template <typename T> using Distribution = std::uniform_int_distribution<T>;

inline Engine &random_engine() {
  static Engine engine(get_rand_seed());
  return engine;
}

template <typename T> inline T get(const T to) {
  Distribution<T> distribution(0, to);
  return distribution(random_engine());
}

template <typename T> inline T get(const T from, const T to) {
  return get(to - from) + from;
}

template <typename T = int32_t> inline T get() {
  return get(static_cast<T>(0), std::numeric_limits<T>::max());
}

} // namespace Random

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
class SafeIntegralHash {
public:
  const T kRandomValue = static_cast<T>(Random::current_timestamp());

  T operator()(const T &value) const { return value ^ kRandomValue; }
};

template <typename Key, typename Value,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMap = std::unordered_map<Key, Value, SafeIntegralHash<Key>>;

template <typename Key, typename Value,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMultiMap =
    std::unordered_multimap<Key, Value, SafeIntegralHash<Key>>;

template <typename Key,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedSet = std::unordered_set<Key, SafeIntegralHash<Key>>;

template <typename Key,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMultiSet =
    std::unordered_multiset<Key, SafeIntegralHash<Key>>;

namespace std {

#ifndef STD_HASH_PAIR
template <typename T, typename U> struct hash<std::pair<T, U>> {
  std::size_t operator()(const std::pair<T, U> &pair) const {
    return pair.first * 877117 + pair.second;
  }
};
#endif

} // namespace std

template <typename T, typename std::enable_if<
                          std::is_floating_point<T>::value>::type * = nullptr>
inline bool is_equal_to_zero(const T &a) {
  return abs(a) < EPS;
}

template <typename T, typename std::enable_if<
                          !std::is_floating_point<T>::value>::type * = nullptr>
inline bool is_equal_to_zero(const T &a) {
  return a == 0;
}

template <typename T> inline bool umin(T &a, const T &b) {
  return (b < a ? a = b, true : false);
}

template <typename T> inline bool umax(T &a, const T &b) {
  return (a < b ? a = b, true : false);
}

template <typename T, size_t N> struct MakeVector {
  template <typename... Args,
            typename R = std::vector<decltype(MakeVector<T, N - 1>::make_vector(
                std::declval<Args>()...))>>
  static R make_vector(size_t first, Args... sizes) {
    auto inner = MakeVector<T, N - 1>::make_vector(sizes...);
    return R(first, inner);
  }
};

template <typename T> struct MakeVector<T, 1> {
  /// caide keep
  template <typename R = std::vector<T>>
  static R make_vector(std::size_t size, const T &value) {
    return R(size, value);
  }
};

template <typename T, typename... Args>
auto make_vector(Args... args)
    -> decltype(MakeVector<T, sizeof...(Args) - 1>::make_vector(args...)) {
  return MakeVector<T, sizeof...(Args) - 1>::make_vector(args...);
}

template <typename T> inline bool is_leap_year(const T year) {
  return year % 400 == 0 || (year % 100 != 0 && (year & 3) == 0);
}

inline size_t get_days_in_month(const size_t month, const size_t year) {
  return kDayMonth[month] + (month == 1 && is_leap_year(year) ? 1 : 0);
}

#define X first
#define Y second
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef _MSC_VER
#define LLD "%I64d"
#define LLU "%I64u"
#else
#define LLD "%lld"
#define LLU "%llu"
#endif

using ll = int64_t;
using ull = uint64_t;
using uint = uint32_t;
using ld = long double;

using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;
using pli = std::pair<ll, int>;

using vi = std::vector<int>;
using vvi = std::vector<vi>;
using vp = std::vector<pii>;

template <typename T> inline T gcd(T a, T b) {
  while (b != 0) {
    a %= b;
    std::swap(a, b);
  }
  return a;
}

template <typename T> inline T lcm(const T &a, const T &b) {
  return a / gcd(a, b) * b;
}

template <typename T> constexpr inline T sqr(const T &x) { return x * x; }

template <typename T> T factorial(T n) {
  T ret = 1;
  for (int i = 2; i <= n; ++i) {
    ret *= i;
  }
  return ret;
}

template <typename T, typename U> inline T binpow(T a, U b) {
  static_assert(std::is_integral<U>::value,
                "Degree must be integral. For real degree use pow.");
  T ret = 1;
  while (b != 0) {
    if ((b & 1) != 0) {
      ret *= a;
    }
    a *= a;
    b >>= 1;
  }
  return ret;
}

template <typename T, typename U, typename Q> inline T binpow(T a, U b, Q mod) {
  static_assert(std::is_integral<U>::value,
                "Degree must be integral. For real degree use pow.");
  long long ret = 1;
  a %= mod;
  while (b != 0) {
    if ((b & 1) != 0) {
      ret = ret * a % mod;
    }
    a = a * a % mod;
    b >>= 1;
  }
  return ret % mod;
}

template <typename T> T digit_sum(const T n) {
  T res = 0;
  T tmp = abs(n);
  while (tmp > 0) {
    res += tmp % 10;
    tmp /= 10;
  }
  return res;
}

template <typename T> std::vector<size_t> digits(const T n) {
  if (n == 0) {
    return {0};
  }
  std::vector<size_t> res;
  T tmp = abs(n);
  while (tmp > 0) {
    res.emplace_back(tmp % 10);
    tmp /= 10;
  }
  return res;
}

template <typename T> size_t digit_count(const T n) { return digits(n).size(); }

template <typename T> std::vector<T> divisors_vector(const T n) {
  const auto approximate_divisors_count = static_cast<size_t>(cbrt(n));
  std::vector<T> ans;
  ans.reserve(approximate_divisors_count);
  const auto floored_square_root = static_cast<T>(sqrt(n));
  for (T i = 1; i <= floored_square_root; ++i) {
    if (n % i == 0) {
      ans.emplace_back(i);
      if (n / i != i) {
        ans.emplace_back(n / i);
      }
    }
  }
  return ans;
}

template <typename T> T euler_function(T n) {
  T res = n;
  for (T i = 2; i * i <= n; ++i) {
    if (n % i == 0) {
      while (n % i == 0) {
        n /= i;
      }
      res -= res / i;
    }
  }
  if (n > 1) {
    res -= res / n;
  }
  return res;
}

template <typename T, typename U>
T inverse_element(const T n, const U mod)
// inverse element for prime mod
{
  return binpow(static_cast<long long>(n), mod - 2, mod);
}

inline void inverseElementForSegment(int r[], const int n, const int mod)
// inverse element for prime mod for numbers [1; mod - 1]
{
  r[1] = 1;
  for (int i = 2; i < n; ++i) {
    r[i] = (mod - static_cast<long long>(mod) / i * r[mod % i] % mod) % mod;
  }
}

template <typename T>
T inverse_element_comp_mod(const T n, const T mod)
// inverse element for composite mod using formula inv(n) = n^(phi(mod) - 1)
{
  return binpow(n, euler_function(mod) - 1, mod);
}

template <typename T>
void binomial_coefficients(const size_t n, std::vector<std::vector<T>> *c) {
  std::vector<std::vector<T>> result(n, std::vector<T>(n));
  for (size_t i = 0; i < n; ++i) {
    result[i][0] = 1;
    result[i][i] = 1;
    for (size_t j = 1; j < i; ++j) {
      result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
    }
  }
  c->swap(result);
}

template <class T> std::string toRoman(T n) {
  const int ValsCount = 13;
  const int Vals[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
  const char *Digits[] = {"I",  "IV", "V",  "IX", "X",  "XL", "L",
                          "XC", "C",  "CD", "D",  "CM", "M"};
  std::string res = "";
  int x = ValsCount - 1;
  while (n) {
    while (Vals[x] > n) {
      --x;
    }
    n -= Vals[x];
    res += Digits[x];
  }
  return res;
}

template <typename T> std::vector<T> calc_powers(const T base, const size_t n) {
  std::vector<T> powers(n + 1);
  powers[0] = 1;
  for (size_t i = 1; i < powers.size(); ++i) {
    powers[i] = powers[i - 1] * base;
  }
  return powers;
}

template <typename T> std::vector<T> calc_factorial(const size_t n) {
  std::vector<T> factorial(n + 1);
  factorial[0] = 1;
  for (size_t i = 1; i < factorial.size(); ++i) {
    factorial[i] = factorial[i - 1] * i;
  }
  return factorial;
}

inline uint32_t abs(const uint32_t x) { return x; }

inline uint64_t abs(const uint64_t x) { return x; }

constexpr const int kBaseModulo = 1000000007; /// caide keep

template <typename T>
inline T &add_mod(T &a, const T b, const T mod = kBaseModulo) {
  if ((a += b) >= mod) {
    a -= mod;
  }
  return a;
}

template <typename T>
inline T &sub_mod(T &a, const T b, const T mod = kBaseModulo) {
  if ((a -= b) < 0) {
    a += mod;
  }
  return a;
}

template <typename T>
inline T &mul_mod(T &a, const T b, const T mod = kBaseModulo) {
  a = static_cast<long long>(a) * b % mod;
  return a;
}

template <typename T, T MOD = kBaseModulo> class ModInt {
public:
  using value_type = T;

  /// caide keep
  constexpr ModInt() : ModInt(0) {}

  constexpr ModInt(const value_type value) : value_(value) {
    static_assert(MOD > 0, "Modulo must be strictly positive.");
    // static_assert((std::equal<value_type, int32_t> && MOD <= 0x3f3f3f3f) ||
    // (std::equal<value_type, int64_t> && MOD <= 0x3f3f3f3f3f3f3f3fLL), "Modulo
    // must be less than half of the max value for typename.");
  }

  template <typename U> constexpr static ModInt from_integer(const U value) {
    return {ModInt::normalize(value)};
  }

  constexpr value_type value() const { return value_; }

  constexpr value_type mod() const { return MOD; }

  constexpr bool operator==(const ModInt rhs) const {
    return value_ == rhs.value_;
  }

  constexpr bool operator!=(const ModInt rhs) const { return !operator==(rhs); }

  constexpr bool operator<(const ModInt &rhs) const {
    return value_ < rhs.value_;
  }

  constexpr bool operator>(const ModInt &rhs) const {
    return value_ > rhs.value_;
  }

  ModInt operator+(const ModInt rhs) const {
    value_type x = value_;
    return {add_mod(x, rhs.value_, MOD)};
  }

  ModInt operator-(const ModInt rhs) const {
    value_type x = value_;
    return {sub_mod(x, rhs.value_, MOD)};
  }

  ModInt operator*(const ModInt rhs) const {
    value_type x = value_;
    return {mul_mod(x, rhs.value_, MOD)};
  }

  ModInt &operator+=(const ModInt rhs) {
    add_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt &operator-=(const ModInt rhs) {
    sub_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt &operator*=(const ModInt rhs) {
    mul_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt operator++(int) {
    const ModInt ret(value_);
    add_mod(value_, static_cast<value_type>(1), MOD);
    return ret;
  }

  ModInt operator--(int) {
    const ModInt ret(value_);
    sub_mod(value_, static_cast<value_type>(1), MOD);
    return ret;
  }

  ModInt &operator++() {
    add_mod(value_, static_cast<value_type>(1), MOD);
    return *this;
  }

  ModInt &operator--() {
    sub_mod(value_, static_cast<value_type>(1), MOD);
    return *this;
  }

  constexpr ModInt operator+() const { return {value_}; }

  constexpr ModInt operator-() const { return negate(); }

  constexpr ModInt negate() const { return {ModInt::normalize(-value_)}; }

  constexpr ModInt inverse() const { return {inverse_element(value_, MOD)}; }

  std::string str() const { return std::to_string(value_); }

  template <typename C> C as() const { return static_cast<C>(value_); }

  friend std::istream &operator>>(std::istream &in, ModInt &rhs) {
    value_type x;
    in >> x;
    rhs.value_ = ModInt::normalize(x);
    return in;
  }

  friend std::ostream &operator<<(std::ostream &out, const ModInt &rhs) {
    out << rhs.value_;
    return out;
  }

private:
  value_type value_;

  template <typename U> static value_type normalize(const U value) {
    if (value >= 0 && value < MOD) {
      return value;
    }
    const value_type ret = value % MOD;
    if (ret < 0) {
      return ret + MOD;
    }
    return ret;
  }
};

namespace std {

template <typename T, T MOD>
struct is_integral<ModInt<T, MOD>> : std::true_type {};

template <typename T, T MOD>
struct is_arithmetic<ModInt<T, MOD>> : std::true_type {};

} // namespace std

template <typename T, T MOD> std::string to_string(const ModInt<T, MOD> &val) {
  return val.str();
}

#ifdef _MSC_VER
#include <intrin.h>
#include <nmmintrin.h>

#define __builtin_popcount __popcnt
#define __builtin_popcountll _mm_popcnt_u64

// bit operations (_builtin_ctz (ctzl, ctzll) and __builtin_clz (clzl, clzll))
// for Visual Studio
// https://gist.github.com/pps83/3210a2f980fd02bb2ba2e5a1fc4a2ef0

static inline int __builtin_ctz(unsigned x) {
  unsigned long ret;
  _BitScanForward(&ret, x);
  return (int)ret;
}

static inline int __builtin_ctzll(unsigned long long x) {
  unsigned long ret;
  _BitScanForward64(&ret, x);
  return (int)ret;
}

static inline int __builtin_ctzl(unsigned long x) {
  return sizeof(x) == 8 ? __builtin_ctzll(x) : __builtin_ctz((uint32_t)x);
}

static inline int __builtin_clz(unsigned x) {
  // unsigned long ret;
  //_BitScanReverse(&ret, x);
  // return (int)(31 ^ ret);
  return (int)__lzcnt(x);
}

static inline int __builtin_clzll(unsigned long long x) {
  // unsigned long ret;
  //_BitScanReverse64(&ret, x);
  // return (int)(63 ^ ret);
  return (int)__lzcnt64(x);
}

static inline int __builtin_clzl(unsigned long x) {
  return sizeof(x) == 8 ? __builtin_clzll(x) : __builtin_clz((uint32_t)x);
}

#ifdef __cplusplus
static inline int __builtin_ctzl(unsigned long long x) {
  return __builtin_ctzll(x);
}

static inline int __builtin_clzl(unsigned long long x) {
  return __builtin_clzll(x);
}
#endif
#endif

// ToDo[c++17]: use constexpr if
template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t popcount(const T value) noexcept {
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_popcount(value);
  } else {
    return __builtin_popcountll(value);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t popcount(const T value) noexcept {
  return popcount(static_cast<typename std::make_unsigned<T>::type>(value));
}

// ToDo[c++17]: use constexpr if
template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t countl_zero(const T value) noexcept {
  constexpr size_t digits = std::numeric_limits<T>::digits;
  if (value == 0) {
    return digits;
  }
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_clz(value) -
           (std::numeric_limits<uint32_t>::digits - digits);
  } else {
    return __builtin_clzll(value) -
           (std::numeric_limits<uint64_t>::digits - digits);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t countl_zero(const T value) noexcept {
  return countl_zero(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr size_t countl_one(const T value) noexcept {
  return countl_zero(static_cast<T>(~value));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t countr_zero(const T value) noexcept {
  if (value == 0) {
    return std::numeric_limits<T>::digits;
  }
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_ctz(value);
  } else {
    return __builtin_ctzll(value);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t countr_zero(const T value) noexcept {
  return countr_zero(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr size_t countr_one(const T value) noexcept {
  return countr_zero(static_cast<T>(~value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr bool has_single_bit(const T value) noexcept {
  return value != 0 && (value & (value - 1)) == 0;
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr T bit_ceil(const T value) noexcept {
  if (value == 0) {
    return 1;
  }
  return static_cast<T>(T{1} << (std::numeric_limits<T>::digits -
                                 countl_zero(static_cast<T>(value - 1))));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr T bit_ceil(const T value) noexcept {
  return static_cast<T>(
      bit_ceil(static_cast<typename std::make_unsigned<T>::type>(value)));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr T bit_floor(const T value) noexcept {
  if (value == 0) {
    return 0;
  }
  return static_cast<T>(
      T{1} << (std::numeric_limits<T>::digits - 1 - countl_zero(value)));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr T bit_floor(const T value) noexcept {
  return static_cast<T>(
      bit_floor(static_cast<typename std::make_unsigned<T>::type>(value)));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t bit_width(const T value) noexcept {
  return static_cast<T>(std::numeric_limits<T>::digits - countl_zero(value));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t bit_width(const T value) noexcept {
  return bit_width(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr bool test_bit(const T mask, const std::size_t bit_id) noexcept {
  return mask & (T{1} << bit_id);
}

class EMultiplication4 {
public:
  static constexpr bool kWriteCaseNumber = false;
  static constexpr bool kMultiTest = false;

  using Int = ModInt<int>;

  void solve(std::istream &in, std::ostream &out) {
    int n, k;
    in >> n >> k;
    std::vector<ll> negative;
    std::vector<ll> positive;
    int zeroes = 0;
    for (int i : range(n)) {
      ll x;
      in >> x;
      if (x == 0) {
        ++zeroes;
        continue;
      }
      if (x < 0) {
        negative.emplace_back(std::abs(x));
        continue;
      }
      if (x > 0) {
        positive.emplace_back(x);
        continue;
      }
      assert(false);
    }

    const int negative_count = negative.size();
    const int positive_count = positive.size();

    if (negative_count + positive_count < k) {
      out << 0 << std::endl;
      return;
    }

    if (negative_count + positive_count == k) {
      if (negative_count % 2 == 1) {
        if (zeroes > 0) {
          out << 0 << std::endl;
          return;
        }
        Int ans = 1;
        for (ll x : positive) {
          ans *= x;
        }
        for (ll x : negative) {
          ans *= x;
        }
        ans = -ans;
        out << ans << std::endl;
        return;
      }
    }

    sort(negative, std::greater<>());
    sort(positive, std::greater<>());

    if (positive_count == 0) {
      Int ans = 1;
      if (k % 2 == 1) {
        if (zeroes > 0) {
          out << 0 << std::endl;
          return;
        }
        reverse(negative);
        ans = -ans;
      }
      for (int i : range(k)) {
        ans *= negative[i];
      }
      out << ans << std::endl;
      return;
    }

    ld cur_log = 0;
    int pos_index = 0;
    if (k > positive_count) {
      if ((k - positive_count) % 2 == 1) {
        pos_index = positive_count - 1;
      } else {
        pos_index = positive_count;
      }
    } else {
      pos_index = k;
    }
    int neg_index = k - pos_index;

    Int ans = 1;
    for (int i : range(pos_index)) {
      ans *= positive[i];
    }
    for (int j : range(neg_index)) {
      ans *= negative[j];
    }

    constexpr ld kEps = 1e-16;

    for (int neg_cnt = neg_index + 2; neg_cnt <= negative_count && neg_cnt <= k;
         neg_cnt += 2) {
      const ll last_pos = positive[pos_index - 1] * positive[pos_index - 2];
      const ll next_neg = negative[neg_index] * negative[neg_index + 1];

      if (next_neg > last_pos) {
        ans *= Int::from_integer(last_pos).inverse();
        ans *= Int::from_integer(next_neg);
        pos_index -= 2;
        neg_index += 2;
      } else {
        break;
      }
    }

    out << ans << std::endl;
  }

  EMultiplication4() {}

  static constexpr bool kUseCustomChecker = false;
  bool check(std::istringstream in, std::istringstream jury,
             std::istringstream out) {
    int n, k;
    in >> n >> k;
    std::vector<ll> a(n);
    in >> a;

    ll best = -LINF;
    for (int mask : range(1 << n)) {
      if (popcount(mask) != k) {
        continue;
      }
      ll ans = 1;
      for (int i : range(n)) {
        if (test_bit(mask, i)) {
          ans *= a[i];
        }
      }
      umax(best, ans);
    }

    Int pans;
    out >> pans;

    const Int jans = Int::from_integer(best);

    if (pans != jans) {
      debug(pans, jans, best);
      return false;
    }

    return true;
  }

  static constexpr size_t kGeneratedTestsCount = 0;
  static constexpr bool kStopAfterFirstFail = true;
  static void generate_test(std::ostream &test) {
    const int kMaxn = 20;
    const int kMaxm = 10;
    const int kMinm = -10;

    const int n = Random::get(1, kMaxn);
    const int k = Random::get(1, n);
    test << n << " " << k << std::endl;
    for (int i : range(n)) {
      test << Random::get(kMinm, kMaxm) << " ";
    }
    test << std::endl;
  }
};

int main() {
  EMultiplication4 solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);

  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  srand(time(nullptr));
  out << std::fixed << std::setprecision(16);
  if (EMultiplication4::kMultiTest) {
    size_t tests_count;
    in >> tests_count;
    for (size_t test_id : inclusiveRange<size_t>(1, tests_count)) {
      if (EMultiplication4::kWriteCaseNumber) {
        out << "Case #" << test_id << ": ";
      }
      solver.solve(in, out);
    }
  } else {
    solver.solve(in, out);
  }
  return 0;
}


Error: 0

Fixed submission:

/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author Alexander Agulenko
 */

#include <cstdlib>
#include <ctime>
#include <fstream>
#include <iostream>

/**
 *  This solution uses cpplib (prewritten code library)
 *  More info: https://github.com/agul/algolib/tree/master/cpplib
 */

#pragma comment(linker, "/STACK:66777216")
#pragma warning(disable : 4996)
#define _USE_MATH_DEFINES
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <chrono>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
#pragma hdrstop

// todo[c++17]: replace with std::disjunction_v
template <bool... Bools> struct Disjunction : std::false_type {};

template <bool First, bool... Others>
// todo[c++14] use bool_constant
struct Disjunction<First, Others...>
    : std::integral_constant<bool, First || Disjunction<Others...>::value> {};

#if __cplusplus >= 201703L
template <bool... Bools>
constexpr bool DisjunctionV = Disjunction<Bools...>::value;

static_assert(!DisjunctionV<>, "");
static_assert(!DisjunctionV<false, false>, "");
static_assert(DisjunctionV<true>, "");
static_assert(DisjunctionV<false, true>, "");
static_assert(DisjunctionV<true, false>, "");
static_assert(DisjunctionV<false, false, true, true>, "");
#endif

#include <iterator>

template <typename T>
constexpr auto has_begin(int) -> decltype(std::begin(std::declval<T>()), true) {
  return true;
}

template <typename T> constexpr bool has_begin(...) { return false; }

template <typename T>
using is_container = std::integral_constant<bool, has_begin<T>(0)>;

template <typename T, typename... Types>
// todo[c++17] use is_same_v
// todo[c++17] use variable template
using is_one_of = Disjunction<std::is_same<T, Types>::value...>;

// todo[c++14] use remove_cv_t
// todo[c++17] use is_integral_v
// todo[c++17] use  variable template
template <typename T>
using is_sane_integer = std::integral_constant<
    bool,
    std::is_integral<T>::value &&
        !is_one_of<typename std::remove_cv<T>::type, char, signed char,
                   unsigned char, bool, char16_t, char32_t, wchar_t>::value>;

std::string to_string(const std::string &s) { return '"' + s + '"'; }

std::string to_string(const char *s) { return to_string(std::string(s)); }

std::string to_string(const char ch) { return {'\\'', ch, '\\''}; }

std::string to_string(const bool b) { return (b ? "true" : "false"); }

template <typename T,
          typename std::enable_if<Disjunction<
              is_sane_integer<T>::value,
              std::is_floating_point<T>::value>::value>::type * = nullptr>
std::string to_string(const T value) {
  return std::to_string(value);
}

template <typename A, typename B>
std::string to_string(const std::pair<A, B> &);

template <typename T,
          typename std::enable_if<is_container<T>::value>::type * = nullptr>
std::string to_string(const T &container) {
  bool is_first = true;
  std::string res = "{";
  for (const auto &x : container) {
    if (!is_first) {
      res += ", ";
    }
    is_first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

template <typename A, typename B>
std::string to_string(const std::pair<A, B> &p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

std::vector<std::string> vec_splitter(std::string s) {
  s += ',';
  std::vector<std::string> res;
  while (!s.empty()) {
    const size_t pos = s.find(',');
    res.emplace_back(s.substr(0, pos));
    s = s.substr(pos + 1);
  }
  return res;
}

void debug_out(std::vector<std::string> __attribute__((unused)) args,
               __attribute__((unused)) int idx,
               __attribute__((unused)) int LINE_NUM) {
  std::cerr << std::endl;
}

template <typename Head, typename... Tail>
void debug_out(std::vector<std::string> args, int idx, int LINE_NUM, Head H,
               Tail... T) {
  std::stringstream ss;
  ss << to_string(H);
  if (idx > 0) {
    std::cerr << ", ";
  } else {
    std::cerr << "Line(" << LINE_NUM << ") ";
  }
  const std::string &arg = args[idx];
  const std::string value = ss.str();
  if (arg == value) {
    std::cerr << arg;
  } else {
    std::cerr << arg << " = " << value;
  }
  debug_out(args, idx + 1, LINE_NUM, T...);
}

#ifdef HOME
#define debug(...)                                                             \\
  debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

namespace std {

template <typename T>
std::istream &operator>>(std::istream &in, std::vector<T> &vec) {
  for (auto &it : vec) {
    in >> it;
  }
  return in;
}

template <typename T, typename U>
std::istream &operator>>(std::istream &in, std::pair<T, U> &rhs) {
  in >> rhs.first >> rhs.second;
  return in;
}

} // namespace std

void assign_files_input_txt() {
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
}

#include <cstddef>

template <typename T>
class IntegerIterator
    : public std::iterator<std::input_iterator_tag, T, std::ptrdiff_t, T *, T> {
public:
  using value_type = T;

  constexpr explicit IntegerIterator(const value_type value) : value_(value) {}

  IntegerIterator &operator++() {
    ++value_;
    return *this;
  }

  IntegerIterator operator++(int) {
    IntegerIterator copy = *this;
    ++value_;
    return copy;
  }

  IntegerIterator &operator--() {
    --value_;
    return *this;
  }

  IntegerIterator operator--(int) {
    IntegerIterator copy = *this;
    --value_;
    return copy;
  }

  constexpr value_type operator*() const { return value_; }

  constexpr bool operator==(const IntegerIterator rhs) const {
    return value_ == rhs.value_;
  }

  constexpr bool operator!=(const IntegerIterator rhs) const {
    return !(*this == rhs);
  }

  constexpr value_type operator+(const IntegerIterator rhs) const {
    return value_ + rhs.value_;
  }

  IntegerIterator &operator+=(const IntegerIterator rhs) const {
    value_ += rhs.value_;
    return *this;
  }

  constexpr value_type operator-(const IntegerIterator rhs) const {
    return value_ - rhs.value_;
  }

  IntegerIterator &operator-=(const IntegerIterator rhs) const {
    value_ -= rhs.value_;
    return *this;
  }

private:
  value_type value_;
};

template <typename T> class IntegerRange {
public:
  using const_iterator = IntegerIterator<T>;

  constexpr IntegerRange(const T begin, const T end)
      : begin_(begin), end_(end) {}

  constexpr const_iterator begin() const { return const_iterator(begin_); }

  constexpr const_iterator end() const { return const_iterator(end_); }

  constexpr T size() const { return end_ - begin_; }

private:
  T begin_;
  T end_;
};

template <typename T> class ReversedRange {
public:
  using const_iterator = typename std::decay<T>::type::const_iterator;
  using reverse_iterator = std::reverse_iterator<const_iterator>;

  explicit constexpr ReversedRange(const T &iterable)
      : begin_(iterable.begin()), end_(iterable.end()) {}

  constexpr reverse_iterator begin() const { return reverse_iterator(end_); }

  constexpr reverse_iterator end() const { return reverse_iterator(begin_); }

private:
  const_iterator begin_;
  const_iterator end_;
};

template <typename T> ReversedRange<T> reversed(T &&iterable) {
  return ReversedRange<T>{iterable};
}

template <typename T> constexpr IntegerRange<T> range(const T to) {
  return IntegerRange<T>(0, to);
}

template <typename T>
constexpr IntegerRange<T> range(const T from, const T to) {
  return IntegerRange<T>(from, to);
}

template <typename T> constexpr IntegerRange<T> inclusiveRange(const T to) {
  return IntegerRange<T>(0, to + 1);
}

template <typename T>
constexpr IntegerRange<T> inclusiveRange(const T from, const T to) {
  return IntegerRange<T>(from, to + 1);
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> downrange(const T from) {
  return reversed(range(from));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> downrange(const T from, const T to) {
  return reversed(range(to, from));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> inclusiveDownrange(const T from) {
  return reversed(range(from + 1));
}

template <typename T>
constexpr ReversedRange<IntegerRange<T>> inclusiveDownrange(const T from,
                                                            const T to) {
  return reversed(range(to, from + 1));
}

template <typename R> void sort(R &range) {
  std::sort(range.begin(), range.end());
}

template <typename R, typename Comp> void sort(R &range, Comp comp) {
  std::sort(range.begin(), range.end(), comp);
}

template <typename R> void reverse(R &range) {
  std::reverse(range.begin(), range.end());
}

template <typename R, typename T>
auto lower_bound(const R &range, const T &value) -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value);
}

template <typename R, typename T, typename Comp>
auto lower_bound(const R &range, const T &value, Comp comp)
    -> decltype(range.begin()) {
  return std::lower_bound(range.begin(), range.end(), value, comp);
}

template <typename R, typename T>
auto upper_bound(const R &range, const T &value) -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value);
}

template <typename R, typename T, typename Comp>
auto upper_bound(const R &range, const T &value, Comp comp)
    -> decltype(range.begin()) {
  return std::upper_bound(range.begin(), range.end(), value, comp);
}

template <typename R>
auto min_element(const R &range) -> decltype(range.begin()) {
  return std::min_element(range.begin(), range.end());
}

template <typename R>
auto max_element(const R &range) -> decltype(range.begin()) {
  return std::max_element(range.begin(), range.end());
}

template <typename R> bool next_permutation(R &range) {
  return std::next_permutation(range.begin(), range.end());
}

template <typename T> void unique(std::vector<T> &range) {
  range.erase(std::unique(range.begin(), range.end()), range.end());
}

template <typename T> void dedup(std::vector<T> &range) {
  sort(range);
  unique(range);
}

template <typename R> R sorted(R range) {
  sort(range);
  return range;
}

template <typename R, typename Comp> R sorted(R range, Comp comp) {
  sort(range, comp);
  return range;
}

static constexpr long double PI = 3.14159265358979323846;
static constexpr long double EPS = 1e-9;
static constexpr int32_t INF = 0x3f3f3f3f;
static constexpr int64_t LINF = 0x3f3f3f3f3f3f3f3fLL;

static constexpr int32_t DX[8] = {-1, 0, 1, 0, -1, -1, 1, 1};
static constexpr int32_t DY[8] = {0, 1, 0, -1, -1, 1, 1, -1};

static constexpr uint32_t kDayMonth[12] = {31, 28, 31, 30, 31, 30,
                                           31, 31, 30, 31, 30, 31};

enum Direction : uint8_t {
  Up,
  Right,
  Down,
  Left,
  UpLeft,
  UpRight,
  DownRight,
  DownLeft,
  North = Up,
  East = Right,
  South = Down,
  West = Left,
  NorthWest = UpLeft,
  NorthEast = UpRight,
  SouthEast = DownRight,
  SouthWest = DownLeft,
  Unknown = 255
};

#include <cstdint>

namespace Random {

inline std::chrono::system_clock::rep current_timestamp() {
  return std::chrono::system_clock::now().time_since_epoch().count();
}

inline uint64_t get_new_rand_seed() {
  return static_cast<uint64_t>(current_timestamp());
}

inline uint64_t get_rand_seed() {
  static const uint64_t kRandSeed = get_new_rand_seed();
  return kRandSeed;
}

using Engine = std::mt19937_64;

template <typename T> using Distribution = std::uniform_int_distribution<T>;

inline Engine &random_engine() {
  static Engine engine(get_rand_seed());
  return engine;
}

template <typename T> inline T get(const T to) {
  Distribution<T> distribution(0, to);
  return distribution(random_engine());
}

template <typename T> inline T get(const T from, const T to) {
  return get(to - from) + from;
}

template <typename T = int32_t> inline T get() {
  return get(static_cast<T>(0), std::numeric_limits<T>::max());
}

} // namespace Random

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
class SafeIntegralHash {
public:
  const T kRandomValue = static_cast<T>(Random::current_timestamp());

  T operator()(const T &value) const { return value ^ kRandomValue; }
};

template <typename Key, typename Value,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMap = std::unordered_map<Key, Value, SafeIntegralHash<Key>>;

template <typename Key, typename Value,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMultiMap =
    std::unordered_multimap<Key, Value, SafeIntegralHash<Key>>;

template <typename Key,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedSet = std::unordered_set<Key, SafeIntegralHash<Key>>;

template <typename Key,
          typename std::enable_if<std::is_integral<Key>::value>::type * =
              nullptr>
using SafeUnorderedMultiSet =
    std::unordered_multiset<Key, SafeIntegralHash<Key>>;

namespace std {

#ifndef STD_HASH_PAIR
template <typename T, typename U> struct hash<std::pair<T, U>> {
  std::size_t operator()(const std::pair<T, U> &pair) const {
    return pair.first * 877117 + pair.second;
  }
};
#endif

} // namespace std

template <typename T, typename std::enable_if<
                          std::is_floating_point<T>::value>::type * = nullptr>
inline bool is_equal_to_zero(const T &a) {
  return abs(a) < EPS;
}

template <typename T, typename std::enable_if<
                          !std::is_floating_point<T>::value>::type * = nullptr>
inline bool is_equal_to_zero(const T &a) {
  return a == 0;
}

template <typename T> inline bool umin(T &a, const T &b) {
  return (b < a ? a = b, true : false);
}

template <typename T> inline bool umax(T &a, const T &b) {
  return (a < b ? a = b, true : false);
}

template <typename T, size_t N> struct MakeVector {
  template <typename... Args,
            typename R = std::vector<decltype(MakeVector<T, N - 1>::make_vector(
                std::declval<Args>()...))>>
  static R make_vector(size_t first, Args... sizes) {
    auto inner = MakeVector<T, N - 1>::make_vector(sizes...);
    return R(first, inner);
  }
};

template <typename T> struct MakeVector<T, 1> {
  /// caide keep
  template <typename R = std::vector<T>>
  static R make_vector(std::size_t size, const T &value) {
    return R(size, value);
  }
};

template <typename T, typename... Args>
auto make_vector(Args... args)
    -> decltype(MakeVector<T, sizeof...(Args) - 1>::make_vector(args...)) {
  return MakeVector<T, sizeof...(Args) - 1>::make_vector(args...);
}

template <typename T> inline bool is_leap_year(const T year) {
  return year % 400 == 0 || (year % 100 != 0 && (year & 3) == 0);
}

inline size_t get_days_in_month(const size_t month, const size_t year) {
  return kDayMonth[month] + (month == 1 && is_leap_year(year) ? 1 : 0);
}

#define X first
#define Y second
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()

#ifdef _MSC_VER
#define LLD "%I64d"
#define LLU "%I64u"
#else
#define LLD "%lld"
#define LLU "%llu"
#endif

using ll = int64_t;
using ull = uint64_t;
using uint = uint32_t;
using ld = long double;

using pii = std::pair<int, int>;
using pll = std::pair<ll, ll>;
using pli = std::pair<ll, int>;

using vi = std::vector<int>;
using vvi = std::vector<vi>;
using vp = std::vector<pii>;

template <typename T> inline T gcd(T a, T b) {
  while (b != 0) {
    a %= b;
    std::swap(a, b);
  }
  return a;
}

template <typename T> inline T lcm(const T &a, const T &b) {
  return a / gcd(a, b) * b;
}

template <typename T> constexpr inline T sqr(const T &x) { return x * x; }

template <typename T> T factorial(T n) {
  T ret = 1;
  for (int i = 2; i <= n; ++i) {
    ret *= i;
  }
  return ret;
}

template <typename T, typename U> inline T binpow(T a, U b) {
  static_assert(std::is_integral<U>::value,
                "Degree must be integral. For real degree use pow.");
  T ret = 1;
  while (b != 0) {
    if ((b & 1) != 0) {
      ret *= a;
    }
    a *= a;
    b >>= 1;
  }
  return ret;
}

template <typename T, typename U, typename Q> inline T binpow(T a, U b, Q mod) {
  static_assert(std::is_integral<U>::value,
                "Degree must be integral. For real degree use pow.");
  long long ret = 1;
  a %= mod;
  while (b != 0) {
    if ((b & 1) != 0) {
      ret = ret * a % mod;
    }
    a = a * a % mod;
    b >>= 1;
  }
  return ret % mod;
}

template <typename T> T digit_sum(const T n) {
  T res = 0;
  T tmp = abs(n);
  while (tmp > 0) {
    res += tmp % 10;
    tmp /= 10;
  }
  return res;
}

template <typename T> std::vector<size_t> digits(const T n) {
  if (n == 0) {
    return {0};
  }
  std::vector<size_t> res;
  T tmp = abs(n);
  while (tmp > 0) {
    res.emplace_back(tmp % 10);
    tmp /= 10;
  }
  return res;
}

template <typename T> size_t digit_count(const T n) { return digits(n).size(); }

template <typename T> std::vector<T> divisors_vector(const T n) {
  const auto approximate_divisors_count = static_cast<size_t>(cbrt(n));
  std::vector<T> ans;
  ans.reserve(approximate_divisors_count);
  const auto floored_square_root = static_cast<T>(sqrt(n));
  for (T i = 1; i <= floored_square_root; ++i) {
    if (n % i == 0) {
      ans.emplace_back(i);
      if (n / i != i) {
        ans.emplace_back(n / i);
      }
    }
  }
  return ans;
}

template <typename T> T euler_function(T n) {
  T res = n;
  for (T i = 2; i * i <= n; ++i) {
    if (n % i == 0) {
      while (n % i == 0) {
        n /= i;
      }
      res -= res / i;
    }
  }
  if (n > 1) {
    res -= res / n;
  }
  return res;
}

template <typename T, typename U>
T inverse_element(const T n, const U mod)
// inverse element for prime mod
{
  return binpow(static_cast<long long>(n), mod - 2, mod);
}

inline void inverseElementForSegment(int r[], const int n, const int mod)
// inverse element for prime mod for numbers [1; mod - 1]
{
  r[1] = 1;
  for (int i = 2; i < n; ++i) {
    r[i] = (mod - static_cast<long long>(mod) / i * r[mod % i] % mod) % mod;
  }
}

template <typename T>
T inverse_element_comp_mod(const T n, const T mod)
// inverse element for composite mod using formula inv(n) = n^(phi(mod) - 1)
{
  return binpow(n, euler_function(mod) - 1, mod);
}

template <typename T>
void binomial_coefficients(const size_t n, std::vector<std::vector<T>> *c) {
  std::vector<std::vector<T>> result(n, std::vector<T>(n));
  for (size_t i = 0; i < n; ++i) {
    result[i][0] = 1;
    result[i][i] = 1;
    for (size_t j = 1; j < i; ++j) {
      result[i][j] = result[i - 1][j - 1] + result[i - 1][j];
    }
  }
  c->swap(result);
}

template <class T> std::string toRoman(T n) {
  const int ValsCount = 13;
  const int Vals[] = {1, 4, 5, 9, 10, 40, 50, 90, 100, 400, 500, 900, 1000};
  const char *Digits[] = {"I",  "IV", "V",  "IX", "X",  "XL", "L",
                          "XC", "C",  "CD", "D",  "CM", "M"};
  std::string res = "";
  int x = ValsCount - 1;
  while (n) {
    while (Vals[x] > n) {
      --x;
    }
    n -= Vals[x];
    res += Digits[x];
  }
  return res;
}

template <typename T> std::vector<T> calc_powers(const T base, const size_t n) {
  std::vector<T> powers(n + 1);
  powers[0] = 1;
  for (size_t i = 1; i < powers.size(); ++i) {
    powers[i] = powers[i - 1] * base;
  }
  return powers;
}

template <typename T> std::vector<T> calc_factorial(const size_t n) {
  std::vector<T> factorial(n + 1);
  factorial[0] = 1;
  for (size_t i = 1; i < factorial.size(); ++i) {
    factorial[i] = factorial[i - 1] * i;
  }
  return factorial;
}

inline uint32_t abs(const uint32_t x) { return x; }

inline uint64_t abs(const uint64_t x) { return x; }

constexpr const int kBaseModulo = 1000000007; /// caide keep

template <typename T>
inline T &add_mod(T &a, const T b, const T mod = kBaseModulo) {
  if ((a += b) >= mod) {
    a -= mod;
  }
  return a;
}

template <typename T>
inline T &sub_mod(T &a, const T b, const T mod = kBaseModulo) {
  if ((a -= b) < 0) {
    a += mod;
  }
  return a;
}

template <typename T>
inline T &mul_mod(T &a, const T b, const T mod = kBaseModulo) {
  a = static_cast<long long>(a) * b % mod;
  return a;
}

template <typename T, T MOD = kBaseModulo> class ModInt {
public:
  using value_type = T;

  /// caide keep
  constexpr ModInt() : ModInt(0) {}

  constexpr ModInt(const value_type value) : value_(value) {
    static_assert(MOD > 0, "Modulo must be strictly positive.");
    // static_assert((std::equal<value_type, int32_t> && MOD <= 0x3f3f3f3f) ||
    // (std::equal<value_type, int64_t> && MOD <= 0x3f3f3f3f3f3f3f3fLL), "Modulo
    // must be less than half of the max value for typename.");
  }

  template <typename U> constexpr static ModInt from_integer(const U value) {
    return {ModInt::normalize(value)};
  }

  constexpr value_type value() const { return value_; }

  constexpr value_type mod() const { return MOD; }

  constexpr bool operator==(const ModInt rhs) const {
    return value_ == rhs.value_;
  }

  constexpr bool operator!=(const ModInt rhs) const { return !operator==(rhs); }

  constexpr bool operator<(const ModInt &rhs) const {
    return value_ < rhs.value_;
  }

  constexpr bool operator>(const ModInt &rhs) const {
    return value_ > rhs.value_;
  }

  ModInt operator+(const ModInt rhs) const {
    value_type x = value_;
    return {add_mod(x, rhs.value_, MOD)};
  }

  ModInt operator-(const ModInt rhs) const {
    value_type x = value_;
    return {sub_mod(x, rhs.value_, MOD)};
  }

  ModInt operator*(const ModInt rhs) const {
    value_type x = value_;
    return {mul_mod(x, rhs.value_, MOD)};
  }

  ModInt &operator+=(const ModInt rhs) {
    add_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt &operator-=(const ModInt rhs) {
    sub_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt &operator*=(const ModInt rhs) {
    mul_mod(value_, rhs.value_, MOD);
    return *this;
  }

  ModInt operator++(int) {
    const ModInt ret(value_);
    add_mod(value_, static_cast<value_type>(1), MOD);
    return ret;
  }

  ModInt operator--(int) {
    const ModInt ret(value_);
    sub_mod(value_, static_cast<value_type>(1), MOD);
    return ret;
  }

  ModInt &operator++() {
    add_mod(value_, static_cast<value_type>(1), MOD);
    return *this;
  }

  ModInt &operator--() {
    sub_mod(value_, static_cast<value_type>(1), MOD);
    return *this;
  }

  constexpr ModInt operator+() const { return {value_}; }

  constexpr ModInt operator-() const { return negate(); }

  constexpr ModInt negate() const { return {ModInt::normalize(-value_)}; }

  constexpr ModInt inverse() const { return {inverse_element(value_, MOD)}; }

  std::string str() const { return std::to_string(value_); }

  template <typename C> C as() const { return static_cast<C>(value_); }

  friend std::istream &operator>>(std::istream &in, ModInt &rhs) {
    value_type x;
    in >> x;
    rhs.value_ = ModInt::normalize(x);
    return in;
  }

  friend std::ostream &operator<<(std::ostream &out, const ModInt &rhs) {
    out << rhs.value_;
    return out;
  }

private:
  value_type value_;

  template <typename U> static value_type normalize(const U value) {
    if (value >= 0 && value < MOD) {
      return value;
    }
    const value_type ret = value % MOD;
    if (ret < 0) {
      return ret + MOD;
    }
    return ret;
  }
};

namespace std {

template <typename T, T MOD>
struct is_integral<ModInt<T, MOD>> : std::true_type {};

template <typename T, T MOD>
struct is_arithmetic<ModInt<T, MOD>> : std::true_type {};

} // namespace std

template <typename T, T MOD> std::string to_string(const ModInt<T, MOD> &val) {
  return val.str();
}

#ifdef _MSC_VER
#include <intrin.h>
#include <nmmintrin.h>

#define __builtin_popcount __popcnt
#define __builtin_popcountll _mm_popcnt_u64

// bit operations (_builtin_ctz (ctzl, ctzll) and __builtin_clz (clzl, clzll))
// for Visual Studio
// https://gist.github.com/pps83/3210a2f980fd02bb2ba2e5a1fc4a2ef0

static inline int __builtin_ctz(unsigned x) {
  unsigned long ret;
  _BitScanForward(&ret, x);
  return (int)ret;
}

static inline int __builtin_ctzll(unsigned long long x) {
  unsigned long ret;
  _BitScanForward64(&ret, x);
  return (int)ret;
}

static inline int __builtin_ctzl(unsigned long x) {
  return sizeof(x) == 8 ? __builtin_ctzll(x) : __builtin_ctz((uint32_t)x);
}

static inline int __builtin_clz(unsigned x) {
  // unsigned long ret;
  //_BitScanReverse(&ret, x);
  // return (int)(31 ^ ret);
  return (int)__lzcnt(x);
}

static inline int __builtin_clzll(unsigned long long x) {
  // unsigned long ret;
  //_BitScanReverse64(&ret, x);
  // return (int)(63 ^ ret);
  return (int)__lzcnt64(x);
}

static inline int __builtin_clzl(unsigned long x) {
  return sizeof(x) == 8 ? __builtin_clzll(x) : __builtin_clz((uint32_t)x);
}

#ifdef __cplusplus
static inline int __builtin_ctzl(unsigned long long x) {
  return __builtin_ctzll(x);
}

static inline int __builtin_clzl(unsigned long long x) {
  return __builtin_clzll(x);
}
#endif
#endif

// ToDo[c++17]: use constexpr if
template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t popcount(const T value) noexcept {
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_popcount(value);
  } else {
    return __builtin_popcountll(value);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t popcount(const T value) noexcept {
  return popcount(static_cast<typename std::make_unsigned<T>::type>(value));
}

// ToDo[c++17]: use constexpr if
template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t countl_zero(const T value) noexcept {
  constexpr size_t digits = std::numeric_limits<T>::digits;
  if (value == 0) {
    return digits;
  }
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_clz(value) -
           (std::numeric_limits<uint32_t>::digits - digits);
  } else {
    return __builtin_clzll(value) -
           (std::numeric_limits<uint64_t>::digits - digits);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t countl_zero(const T value) noexcept {
  return countl_zero(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr size_t countl_one(const T value) noexcept {
  return countl_zero(static_cast<T>(~value));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t countr_zero(const T value) noexcept {
  if (value == 0) {
    return std::numeric_limits<T>::digits;
  }
  if (sizeof(T) <= sizeof(uint32_t)) {
    return __builtin_ctz(value);
  } else {
    return __builtin_ctzll(value);
  }
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t countr_zero(const T value) noexcept {
  return countr_zero(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr size_t countr_one(const T value) noexcept {
  return countr_zero(static_cast<T>(~value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr bool has_single_bit(const T value) noexcept {
  return value != 0 && (value & (value - 1)) == 0;
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr T bit_ceil(const T value) noexcept {
  if (value == 0) {
    return 1;
  }
  return static_cast<T>(T{1} << (std::numeric_limits<T>::digits -
                                 countl_zero(static_cast<T>(value - 1))));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr T bit_ceil(const T value) noexcept {
  return static_cast<T>(
      bit_ceil(static_cast<typename std::make_unsigned<T>::type>(value)));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr T bit_floor(const T value) noexcept {
  if (value == 0) {
    return 0;
  }
  return static_cast<T>(
      T{1} << (std::numeric_limits<T>::digits - 1 - countl_zero(value)));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr T bit_floor(const T value) noexcept {
  return static_cast<T>(
      bit_floor(static_cast<typename std::make_unsigned<T>::type>(value)));
}

template <typename T,
          typename std::enable_if<std::is_unsigned<T>::value>::type * = nullptr>
constexpr size_t bit_width(const T value) noexcept {
  return static_cast<T>(std::numeric_limits<T>::digits - countl_zero(value));
}

template <typename T, typename std::enable_if<!std::is_unsigned<T>::value>::type
                          * = nullptr>
constexpr size_t bit_width(const T value) noexcept {
  return bit_width(static_cast<typename std::make_unsigned<T>::type>(value));
}

template <typename T,
          typename std::enable_if<std::is_integral<T>::value>::type * = nullptr>
constexpr bool test_bit(const T mask, const std::size_t bit_id) noexcept {
  return mask & (T{1} << bit_id);
}

class EMultiplication4 {
public:
  static constexpr bool kWriteCaseNumber = false;
  static constexpr bool kMultiTest = false;

  using Int = ModInt<int>;

  void solve(std::istream &in, std::ostream &out) {
    int n, k;
    in >> n >> k;
    std::vector<ll> negative;
    std::vector<ll> positive;
    int zeroes = 0;
    for (int i : range(n)) {
      ll x;
      in >> x;
      if (x == 0) {
        ++zeroes;
        continue;
      }
      if (x < 0) {
        negative.emplace_back(std::abs(x));
        continue;
      }
      if (x > 0) {
        positive.emplace_back(x);
        continue;
      }
      assert(false);
    }

    const int negative_count = negative.size();
    const int positive_count = positive.size();

    if (negative_count + positive_count < k) {
      out << 0 << std::endl;
      return;
    }

    if (negative_count + positive_count == k) {
      if (negative_count % 2 == 1) {
        if (zeroes > 0) {
          out << 0 << std::endl;
          return;
        }
        Int ans = 1;
        for (ll x : positive) {
          ans *= x;
        }
        for (ll x : negative) {
          ans *= x;
        }
        ans = -ans;
        out << ans << std::endl;
        return;
      }
    }

    sort(negative, std::greater<>());
    sort(positive, std::greater<>());

    assert(positive_count > 0);

    if (positive_count == 0) {
      Int ans = 1;
      if (k % 2 == 1) {
        if (zeroes > 0) {
          out << 0 << std::endl;
          return;
        }
        reverse(negative);
        ans = -ans;
      }
      for (int i : range(k)) {
        ans *= negative[i];
      }
      out << ans << std::endl;
      return;
    }

    ld cur_log = 0;
    int pos_index = 0;
    if (k > positive_count) {
      if ((k - positive_count) % 2 == 1) {
        pos_index = positive_count - 1;
      } else {
        pos_index = positive_count;
      }
    } else {
      pos_index = k;
    }
    for (int i : range(pos_index)) {
      cur_log += std::log(positive[i]);
    }
    int neg_index = k - pos_index;
    for (int i : range(neg_index)) {
      cur_log += std::log(negative[i]);
    }

    ld best_log = cur_log;
    int best_pos = pos_index;
    int best_neg = neg_index;

    constexpr ld kEps = 1e-16;

    for (int neg_cnt = neg_index + 2; neg_cnt <= negative_count && neg_cnt <= k;
         neg_cnt += 2) {
      cur_log += std::log(negative[neg_index++]);
      cur_log += std::log(negative[neg_index++]);

      cur_log -= std::log(positive[--pos_index]);
      cur_log -= std::log(positive[--pos_index]);

      if (best_log + kEps < cur_log) {
        best_log = cur_log;
        best_pos = pos_index;
        best_neg = neg_index;
      }
    }

    debug(best_pos, best_neg);

    Int ans = 1;
    for (int i : range(best_pos)) {
      ans *= positive[i];
    }
    for (int i : range(best_neg)) {
      ans *= negative[i];
    }

    out << ans << std::endl;
  }

  EMultiplication4() {}

  static constexpr bool kUseCustomChecker = false;
  bool check(std::istringstream in, std::istringstream jury,
             std::istringstream out) {
    int n, k;
    in >> n >> k;
    std::vector<ll> a(n);
    in >> a;

    ll best = -LINF;
    for (int mask : range(1 << n)) {
      if (popcount(mask) != k) {
        continue;
      }
      ll ans = 1;
      for (int i : range(n)) {
        if (test_bit(mask, i)) {
          ans *= a[i];
        }
      }
      umax(best, ans);
    }

    Int pans;
    out >> pans;

    const Int jans = Int::from_integer(best);

    if (pans != jans) {
      debug(pans, jans, best);
      return false;
    }

    return true;
  }

  static constexpr size_t kGeneratedTestsCount = 0;
  static constexpr bool kStopAfterFirstFail = true;
  static void generate_test(std::ostream &test) {
    const int kMaxn = 20;
    const int kMaxm = 10;
    const int kMinm = -10;

    const int n = Random::get(1, kMaxn);
    const int k = Random::get(1, n);
    test << n << " " << k << std::endl;
    for (int i : range(n)) {
      test << Random::get(kMinm, kMaxm) << " ";
    }
    test << std::endl;
  }
};

int main() {
  EMultiplication4 solver;
  std::istream &in(std::cin);
  std::ostream &out(std::cout);

  std::ios_base::sync_with_stdio(false);
  std::cin.tie(nullptr);
  srand(time(nullptr));
  out << std::fixed << std::setprecision(16);
  if (EMultiplication4::kMultiTest) {
    size_t tests_count;
    in >> tests_count;
    for (size_t test_id : inclusiveRange<size_t>(1, tests_count)) {
      if (EMultiplication4::kWriteCaseNumber) {
        out << "Case #" << test_id << ": ";
      }
      solver.solve(in, out);
    }
  } else {
    solver.solve(in, out);
  }
  return 0;
}