#include <algorithm>
#include <bits/stdc++.h>
#include <iostream>
#include <numeric>
#include <sched.h>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <map>
#include <stack>
#include <queue>
#include <ext/pb_ds/priority_queue.hpp>
#include <memory>
using namespace std;
using namespace __gnu_pbds;
#define CONFIG_STDERR_ON_SERVER 0
namespace Config
{
bool USACO = false;
const string USACO_IO = "shell";
bool TEST_CASES = false;
inline constexpr bool STDERR_ON_SERVER = CONFIG_STDERR_ON_SERVER;
}
#ifdef LOCAL
const int INF = INT32_MAX - 10;
#endif // LOCAL
#ifndef LOCAL
const long long INF = LLONG_MAX - 10;
#define int long long
#endif // LOCAL
long long max(signed x, long long y) { return std::max((long long) x, y); }
long long max(long long y, signed x) { return std::max((long long) x, y); }
long long min(signed x, long long y) { return std::min((long long) x, y); }
long long min(long long y, signed x) { return std::min((long long) x, y); }
struct Coordinate
{
int x, y;
static void sortByX(vector<Coordinate*>& vec)
{
sort(vec.begin(), vec.end(), [](Coordinate* a, Coordinate* b) {
return a->x < b->x;
});
}
static void sortByY(vector<Coordinate*>& vec)
{
sort(vec.begin(), vec.end(), [](Coordinate* a, Coordinate* b) {
return a->y < b->y;
});
}
};
struct Rect
{
int x1, y1, x2, y2;
friend ostream& operator<<(ostream& os, const Rect& rect)
{
return os << rect.x1 << ' ' << rect.y1 << ' ' << rect.x2 << ' ' << rect.y2;
}
friend istream& operator>>(istream& is, Rect& rect)
{
return is >> rect.x1 >> rect.y1 >> rect.x2 >> rect.y2;
}
};
template<typename Grid>
void cartesianPrint(const Grid& grid, int rows, int cols)
{
if (rows < 0 || cols < 0)
{
throw invalid_argument("rows and cols must be non-negative");
}
vector<int> colWidths(cols);
for (int c = 0; c < cols; ++c)
{
colWidths[c] = static_cast<int>(to_string(c).size());
for (int r = 0; r < rows; ++r)
{
int value = grid[r][c];
int width = static_cast<int>(to_string(value).size());
colWidths[c] = max(colWidths[c], width);
}
}
int rowLabelWidth = max(3, static_cast<int>(to_string(rows - 1).size()));
// ---- Column labels (TOP) ----
cerr << string(rowLabelWidth, ' ') << " ";
for (int c = 0; c < cols; ++c)
{
cerr << setw(colWidths[c]) << c;
if (c < cols - 1)
{
cerr << ' ';
}
}
cerr << '\n';
cerr << string(rowLabelWidth, ' ') << " +";
for (int c = 0; c < cols; ++c)
{
cerr << string(colWidths[c] + 1, '-');
}
cerr << '\n';
// ---- Rows ----
for (int r = 0; r < rows; ++r)
{
cerr << setw(rowLabelWidth) << r << " | ";
for (int c = 0; c < cols; ++c)
{
cerr << setw(colWidths[c]) << grid[r][c];
if (c < cols - 1)
{
cerr << ' ';
}
}
cerr << '\n';
}
}
const vector<pair<signed, signed>> dirs = {
{1, 0}, {0, 1}, {-1, 0}, {0, -1},
{1, 1}, {-1, 1}, {-1, -1}, {1, -1}
};
const vector<pair<signed, signed>> dirs4 = {
{1, 0}, {0, 1}, {-1, 0}, {0, -1}
};
const int MOD = 1000000007;
constexpr double epsilon = 0.00001;
struct MCMF {
struct edge {
signed from, to, rev;
long long cap, cost, flow;
};
signed N;
vector<vector<edge>> ed;
vector<signed> seen;
vector<long long> dist, pi;
vector<edge*> par;
MCMF(signed N_in) : N(N_in), ed(N_in), seen(N_in), dist(N_in), pi(N_in), par(N_in) {}
void addEdge(signed from, signed to, long long cap, long long cost) {
if (from == to) return;
ed[from].push_back(edge{ from,to,(signed)ed[to].size(),cap,cost,0 });
ed[to].push_back(edge{ to,from,(signed)ed[from].size()-1,0,-cost,0 });
}
void path(signed s) {
fill(seen.begin(), seen.end(), 0);
fill(dist.begin(), dist.end(), INF);
dist[s] = 0; long long di;
__gnu_pbds::priority_queue<pair<long long, signed>> q;
vector<decltype(q)::point_iterator> its(N);
q.push({ 0, s });
while (!q.empty()) {
s = q.top().second; q.pop();
seen[s] = 1; di = dist[s] + pi[s];
for (edge& e : ed[s]) if (!seen[e.to]) {
long long val = di - pi[e.to] + e.cost;
if (e.cap - e.flow > 0 && val < dist[e.to]) {
dist[e.to] = val;
par[e.to] = &e;
if (its[e.to] == q.end())
its[e.to] = q.push({ -dist[e.to], e.to });
else
q.modify(its[e.to], { -dist[e.to], e.to });
}
}
}
for (signed i = 0; i < N; i++) pi[i] = min(pi[i] + dist[i], INF);
}
pair<long long, long long> maxflow(signed s, signed t) {
long long totflow = 0, totcost = 0;
while (path(s), seen[t]) {
long long fl = INF;
for (edge* x = par[t]; x; x = par[x->from])
fl = min(fl, x->cap - x->flow);
totflow += fl;
for (edge* x = par[t]; x; x = par[x->from]) {
x->flow += fl;
ed[x->to][x->rev].flow -= fl;
}
}
for (signed i = 0; i < N; i++) for(edge& e : ed[i]) totcost += e.cost * e.flow;
return {totflow, totcost/2};
}
// If some costs can be negative, call this before maxflow:
void setpi(signed s) { // (otherwise, leave this out)
fill(pi.begin(), pi.end(), INF); pi[s] = 0;
signed it = N, ch = 1; long long v;
while (ch-- && it--)
for (signed i = 0; i < N; i++) if (pi[i] != INF)
for (edge& e : ed[i]) if (e.cap)
if ((v = pi[i] + e.cost) < pi[e.to])
pi[e.to] = v, ch = 1;
assert(it >= 0); // negative cost cycle
}
};
class UnionFind
{
private:
std::vector<int> root;
public:
UnionFind(size_t size)
{
root.resize(size);
for (size_t i = 0; i < size; i++)
{
root[i] = i;
}
}
int find(int x)
{
return root[x];
}
void unionSets(int x, int y)
{
int rootX = find(x);
int rootY = find(y);
if (rootX != rootY)
{
for (size_t i = 0; i < root.size(); i++)
{
if (root[i] == rootY)
{
root[i] = rootX;
}
}
}
}
bool connected(int x, int y)
{
return find(x) == find(y);
}
};
class Graph
{
public:
struct Edge
{
signed from;
signed end;
signed weight;
Edge(signed e, signed w)
: from(-1), end(e), weight(w)
{ }
Edge(signed f, signed e, signed w)
: from(f), end(e), weight(w)
{ }
};
private:
vector<size_t> head;
vector<signed> to;
vector<signed> weight;
vector<size_t> next;
size_t n;
size_t idx = 1;
bool directed;
void check(signed v) const
{
if (v < 0 || static_cast<size_t>(v) >= n)
{
throw out_of_range("vertex out of range");
}
}
void addOne(signed s, signed e, signed w)
{
if (idx >= to.size())
{
throw overflow_error("edge capacity exceeded");
}
to[idx] = e;
weight[idx] = w;
next[idx] = head[s];
head[s] = idx++;
}
public:
Graph(size_t size, bool isDirected = true)
: Graph(size, size * (size - 1), isDirected)
{ }
Graph(size_t size, size_t edgeCapacity, bool isDirected = true)
: head(size, 0),
to(edgeCapacity + 1),
weight(edgeCapacity + 1),
next(edgeCapacity + 1),
n(size),
directed(isDirected)
{
}
void add(signed start, signed end, signed w)
{
check(start);
check(end);
addOne(start, end, w);
if (!directed)
{
addOne(end, start, w);
}
}
bool isConnected(signed start, signed end) const
{
check(start);
check(end);
for (size_t i = head[start]; i; i = next[i])
{
if (to[i] == end)
{
return true;
}
}
return false;
}
vector<Edge> outEdges(signed start) const
{
check(start);
vector<Edge> res;
for (size_t i = head[start]; i; i = next[i])
{
res.emplace_back(to[i], weight[i]);
}
return res;
}
size_t size() const
{
return n;
}
bool isDirected() const
{
return directed;
}
};
signed main(signed argc, char** args)
{
void solve();
#ifdef LOCAL
cerr << "Code running w/ test cases locally" << endl;
cerr << "Is USACO mode on? " << (Config::USACO ? "True" : "False");
if (Config::USACO) cout << "\twill read from " << Config::USACO_IO << ".in";
cerr << endl;
cerr << "Multi-test-cases on? " << (Config::TEST_CASES ? "True" : "False") << "\n\n";
// freopen("shell.txt", "r", stdin)
// note: freopen deleted for using designated competitive programming editor
#endif // LOCAL
#ifndef LOCAL
if (Config::USACO)
{
freopen((Config::USACO_IO + ".in").c_str(), "r", stdin);
freopen((Config::USACO_IO + ".out").c_str(), "w", stdout);
}
if (Config::STDERR_ON_SERVER == false)
cerr << "stderr on server is off" << endl;
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
#endif // LOCAL
if (Config::TEST_CASES)
{
int test_cases_numbers_main; cin >> test_cases_numbers_main;
for (int test_case_main = 0; test_case_main < test_cases_numbers_main; test_case_main++)
solve();
}
else
solve();
return 0;
}
constexpr int N1E5 = 100005;
constexpr int N1E6 = 1000006;
constexpr int N1E9 = 1000000009;
/*------------------------------------------------------------------------*/
void solve()
{
}