#include using namespace std; template ostream &operator<<(ostream &os, const pair &p); template ostream &operator<<(ostream &os, const vector &vec); template ostream &operator<<(ostream &os, const map &m); template ostream &operator<<(ostream &os, const unordered_map &m); template ostream &operator<<(ostream &os, const set &s); template ostream &operator<<(ostream &os, const unordered_set &s); template ostream &operator<<(ostream &os, const pair &p) { os << "(" << p.first << ", " << p.second << ")"; return os; } template ostream &operator<<(ostream &os, const vector &vec) { os << "["; for (size_t i = 0; i < vec.size(); ++i) { if (i > 0) os << ", "; os << vec[i]; } os << "]"; return os; } template ostream &operator<<(ostream &os, const vector> &vec) { os << "[\n"; for (size_t i = 0; i < vec.size(); ++i) { os << " " << vec[i]; if (i > 0) os << ", "; os << '\n'; } os << "]"; return os; } template ostream &operator<<(ostream &os, const map &m) { os << "{"; for (const auto &p : m) { os << p.first << ": " << p.second << ", "; } os << "}"; return os; } template ostream &operator<<(ostream &os, const unordered_map &m) { os << "{"; for (const auto &p : m) { os << p.first << ": " << p.second << ", "; } os << "}"; return os; } template ostream &operator<<(ostream &os, const set &s) { int i = 0; os << "{"; for (const auto &e : s) { if (i > 0) os << ", "; os << e; i++; } os << "}"; return os; } template ostream &operator<<(ostream &os, const unordered_set &s) { int i = 0; os << "{"; for (const auto &e : s) { if (i > 0) os << ", "; os << e; i++; } os << "}"; return os; } template void debug_out(const std::string_view names, const Ts &...ts) { size_t start = 0; const auto print_single = [&names](size_t start, const auto &value) { const auto end = names.find(',', start + 1); std::cerr << names.substr(start, end - start) << " = " << value << '\n'; return end + 2; }; ((start = print_single(start, ts)), ...); } #define dbg(...) debug_out(#__VA_ARGS__, __VA_ARGS__)