#include <bits/stdc++.h>
#define SPED \
ios_base::sync_with_stdio(false); \
cin.tie(0); \
cout.tie(0);
#define endl "\n"
#define fi first
#define se second
#define lint long long
#define fami signed
#define lore main
#define freefire freopen
#define rect tuple<lint, lint, lint, lint>
#define Data tuple<lint, bool, int>
const lint INF = 0x1f1f1f1f1f1f1f1f;
const lint NEG = 0xE1E1E1E1E1E1E1E1;
using namespace std;
struct Button
{
lint X, Y, CX, CY, ID; // tọa độ và tạo độ đc nén,
int idH, idC; // idhàng là id của cột Y trên hàng CX
// idcột là id của hàng X trên cột CY
};
int t, p, q, dp[2005][2005], hpref[2005][2005], cpref[2005][2005];
lint m, n, dist[2][100005];
Button a[100005];
rect b[100005];
vector<pair<lint, int>> adjh[200005],
adjc[200005]; // adjhang, adjcot, nghia la cac tk chung hang thi chung 1 vector, chug cot thi chung 1 vector
void reset()
{
for (int i = 1; i <= p + 2; i++)
{
adjh[i].clear();
adjc[i].clear();
}
}
void reset1()
{
for (int i = 1; i <= p + 2; i++)
{
adjh[i].clear();
adjc[i].clear();
}
for (int i = 0; i <= m + 2; i++)
for (int j = 0; j <= n + 2; j++)
dp[i][j] = 0;
}
/*
quy ước : 0 là UD
1 là LR
*/
inline bool bR(lint X, lint yA, lint yB)
{
lint L = min(yA, yB), R = max(yA, yB);
for (int j = 1; j <= q; ++j)
{
auto [x1, y1, x2, y2] = b[j];
if (x1 <= X and X <= x2)
{
if (!(R < y1 or y2 < L))
return true;
}
}
return false;
}
inline bool bC(lint Y, lint xA, lint xB)
{
lint L = min(xA, xB), R = max(xA, xB);
for (int j = 1; j <= q; ++j)
{
auto [x1, y1, x2, y2] = b[j];
if (y1 <= Y and Y <= y2)
{
if (!(R < x1 or x2 < L))
return true;
}
}
return false;
}
void dijkstra()
{
fill(dist[0], dist[0] + p + 2, INF);
fill(dist[1], dist[1] + p + 2, INF);
dist[0][0] = 0;
priority_queue<Data, vector<Data>, greater<Data>> pq;
pq.emplace(0, 0, 0);
while (!pq.empty())
{
auto [du, mode, u] = pq.top();
pq.pop();
if (du > dist[mode][u])
continue;
auto [idx, idy, cidx, cidy, id, idh, idc] = a[u];
if (1 <= u and u <= p)
{
if (dist[!mode][u] > dist[mode][u] + 1)
{
dist[!mode][u] = dist[mode][u] + 1;
pq.emplace(dist[!mode][u], !mode, u);
}
}
if (mode == 1)
{
if (idh > 0)
{
auto [w_adj, id_adj] = adjh[cidx][idh - 1];
if (!bR(idx, idy, w_adj) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idy))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idy);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
if (idh < adjh[cidx].size() - 1)
{
auto [w_adj, id_adj] = adjh[cidx][idh + 1];
if (!bR(idx, idy, w_adj) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idy))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idy);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
}
else
{
if (idc > 0)
{
auto [w_adj, id_adj] = adjc[cidy][idc - 1];
if (!bC(idy, idx, w_adj) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idx))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idx);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
if (idc < adjc[cidy].size() - 1)
{
auto [w_adj, id_adj] = adjc[cidy][idc + 1];
if (!bC(idy, idx, w_adj) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idx))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idx);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
}
}
}
void dijkstra1()
{
fill(dist[0], dist[0] + p + 2, INF);
fill(dist[1], dist[1] + p + 2, INF);
dist[0][0] = 0;
priority_queue<Data, vector<Data>, greater<Data>> pq;
pq.emplace(0, 0, 0);
while (!pq.empty())
{
auto [du, mode, u] = pq.top();
pq.pop();
if (du > dist[mode][u])
continue;
auto [idx, idy, cidx, cidy, id, idh, idc] = a[u];
if (1 <= u and u <= p)
{
if (dist[!mode][u] > dist[mode][u] + 1)
{
dist[!mode][u] = dist[mode][u] + 1;
pq.emplace(dist[!mode][u], !mode, u);
}
}
if (mode == 1)
{
if (idh > 0)
{
auto [w_adj, id_adj] = adjh[cidx][idh - 1];
lint XX = a[id_adj].X;
lint YY = a[id_adj].Y;
if (!(hpref[XX][idy] - hpref[XX][YY - 1]) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idy))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idy);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
if (idh < adjh[cidx].size() - 1)
{
auto [w_adj, id_adj] = adjh[cidx][idh + 1];
lint XX = a[id_adj].X;
lint YY = a[id_adj].Y;
if (!(hpref[XX][YY] - hpref[XX][idy - 1]) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idy))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idy);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
}
else
{
if (idc > 0)
{
auto [w_adj, id_adj] = adjc[cidy][idc - 1];
lint XX = a[id_adj].X;
lint YY = a[id_adj].Y;
if (!(cpref[idx][YY] - cpref[XX - 1][YY]) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idx))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idx);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
if (idc < adjc[cidy].size() - 1)
{
auto [w_adj, id_adj] = adjc[cidy][idc + 1];
lint XX = a[id_adj].X;
lint YY = a[id_adj].Y;
if (!(cpref[XX][YY] - cpref[idx - 1][YY]) and dist[mode][id_adj] > dist[mode][u] + abs(w_adj - idx))
{
dist[mode][id_adj] = dist[mode][u] + abs(w_adj - idx);
pq.emplace(dist[mode][id_adj], mode, id_adj);
}
}
}
}
}
void compress()
{
vector<pair<lint, int>> vx, vy;
for (int i = 0; i <= p + 1; i++)
vx.emplace_back(a[i].X, i);
for (int i = 0; i <= p + 1; i++)
vy.emplace_back(a[i].Y, i);
sort(vx.begin(), vx.end());
sort(vy.begin(), vy.end());
int cx = 0, cy = 0;
for (int i = 0; i < vx.size(); i++)
{
if (i == 0 or vx[i].fi != vx[i - 1].fi)
++cx;
a[vx[i].se].CX = cx;
}
for (int i = 0; i < vy.size(); i++)
{
if (i == 0 or vy[i].fi != vy[i - 1].fi)
++cy;
a[vy[i].se].CY = cy;
}
}
fami lore()
{
if (fopen("starofhope.inp", "r"))
{
freefire("starofhope.inp", "r", stdin);
freefire("starofhope.out", "w", stdout);
}
SPED;
cin >> t;
while (t--)
{
cin >> m >> n >> p >> q;
a[0] = {1, 1, 0, 0, 0, 0, 0};
for (int i = 1; i <= p; i++)
{
int N, E;
cin >> N >> E;
a[i] = {N, E, 0, 0, i, 0, 0};
}
a[p + 1] = {m, n, 0, 0, p + 1, 0, 0};
for (int i = 1; i <= q; i++)
{
lint N, I, G, A;
cin >> N >> I >> G >> A;
b[i] = {N, I, G, A};
}
compress();
for (int i = 0; i <= p + 1; i++)
{
auto [idx, idy, cidx, cidy, id, idh, idc] = a[i];
adjh[cidx].emplace_back(idy, id);
adjc[cidy].emplace_back(idx, id);
}
for (int i = 1; i <= p + 2; i++)
{
sort(adjh[i].begin(), adjh[i].end());
sort(adjc[i].begin(), adjc[i].end());
}
for (int id = 1; id <= p + 2; id++)
{
for (int i = 0; i < adjh[id].size(); i++)
{
auto [wc, idx] = adjh[id][i];
a[idx].idH = i;
}
for (int i = 0; i < adjc[id].size(); i++)
{
auto [wh, idx] = adjc[id][i];
a[idx].idC = i;
}
}
if (m <= 2000 and n <= 2000 and q > 10)
{
for (int i = 1; i <= q; ++i)
{
auto [x1, y1, x2, y2] = b[i];
++dp[x1][y1];
--dp[x2 + 1][y1];
--dp[x1][y2 + 1];
++dp[x2 + 1][y2 + 1];
}
for (int i = 1; i <= m + 1; ++i)
for (int j = 1; j <= n + 1; ++j)
dp[i][j] += dp[i - 1][j] + dp[i][j - 1] - dp[i - 1][j - 1];
for (int i = 1; i <= m; ++i)
for (int j = 1; j <= n; ++j)
dp[i][j] = (dp[i][j] > 0);
for (int i = 1; i <= m; ++i)
{
hpref[i][0] = 0;
for (int j = 1; j <= n; ++j)
hpref[i][j] = hpref[i][j - 1] + dp[i][j];
}
for (int j = 1; j <= n; ++j)
{
cpref[0][j] = 0;
for (int i = 1; i <= m; ++i)
cpref[i][j] = cpref[i - 1][j] + dp[i][j];
}
dijkstra1();
lint res = min(dist[0][p + 1], dist[1][p + 1]);
cout << (res == INF ? -1 : res) << endl;
reset1();
}
else
{
dijkstra();
lint res = min(dist[0][p + 1], dist[1][p + 1]);
cout << (res == INF ? -1 : res) << endl;
reset();
}
}
}
// Let your soul wander where dreams are born.
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CgojZGVmaW5lIFNQRUQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKICAgIGlvc19iYXNlOjpzeW5jX3dpdGhfc3RkaW8oZmFsc2UpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCiAgICBjaW4udGllKDApOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAogICAgY291dC50aWUoMCk7CgojZGVmaW5lIGVuZGwgIlxuIgojZGVmaW5lIGZpIGZpcnN0CiNkZWZpbmUgc2Ugc2Vjb25kCiNkZWZpbmUgbGludCBsb25nIGxvbmcKI2RlZmluZSBmYW1pIHNpZ25lZAojZGVmaW5lIGxvcmUgbWFpbgojZGVmaW5lIGZyZWVmaXJlIGZyZW9wZW4KI2RlZmluZSByZWN0IHR1cGxlPGxpbnQsIGxpbnQsIGxpbnQsIGxpbnQ+CiNkZWZpbmUgRGF0YSB0dXBsZTxsaW50LCBib29sLCBpbnQ+Cgpjb25zdCBsaW50IElORiA9IDB4MWYxZjFmMWYxZjFmMWYxZjsKY29uc3QgbGludCBORUcgPSAweEUxRTFFMUUxRTFFMUUxRTE7Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IEJ1dHRvbgp7CiAgICBsaW50IFgsIFksIENYLCBDWSwgSUQ7IC8vIHThu41hIMSR4buZIHbDoCB04bqhbyDEkeG7mSDEkWMgbsOpbiwKICAgIGludCBpZEgsIGlkQzsgICAgICAgICAgLy8gaWRow6BuZyBsw6AgaWQgY+G7p2EgY+G7mXQgWSB0csOqbiBow6BuZyBDWAogICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpZGPhu5l0IGzDoCBpZCBj4bunYSBow6BuZyBYIHRyw6puIGPhu5l0IENZCn07CgppbnQgdCwgcCwgcSwgZHBbMjAwNV1bMjAwNV0sIGhwcmVmWzIwMDVdWzIwMDVdLCBjcHJlZlsyMDA1XVsyMDA1XTsKbGludCBtLCBuLCBkaXN0WzJdWzEwMDAwNV07CkJ1dHRvbiBhWzEwMDAwNV07CnJlY3QgYlsxMDAwMDVdOwp2ZWN0b3I8cGFpcjxsaW50LCBpbnQ+PiBhZGpoWzIwMDAwNV0sCiAgICBhZGpjWzIwMDAwNV07IC8vIGFkamhhbmcsIGFkamNvdCwgbmdoaWEgbGEgY2FjIHRrIGNodW5nIGhhbmcgdGhpIGNodW5nIDEgdmVjdG9yLCBjaHVnIGNvdCB0aGkgY2h1bmcgMSB2ZWN0b3IKCnZvaWQgcmVzZXQoKQp7CiAgICBmb3IgKGludCBpID0gMTsgaSA8PSBwICsgMjsgaSsrKQogICAgewogICAgICAgIGFkamhbaV0uY2xlYXIoKTsKICAgICAgICBhZGpjW2ldLmNsZWFyKCk7CiAgICB9Cn0KCnZvaWQgcmVzZXQxKCkKewogICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gcCArIDI7IGkrKykKICAgIHsKICAgICAgICBhZGpoW2ldLmNsZWFyKCk7CiAgICAgICAgYWRqY1tpXS5jbGVhcigpOwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gbSArIDI7IGkrKykKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8PSBuICsgMjsgaisrKQogICAgICAgICAgICBkcFtpXVtqXSA9IDA7Cn0KCi8qCiAgICBxdXkgxrDhu5tjIDogMCBsw6AgVUQKICAgICAgICAgMSBsw6AgTFIKKi8KCmlubGluZSBib29sIGJSKGxpbnQgWCwgbGludCB5QSwgbGludCB5QikKewogICAgbGludCBMID0gbWluKHlBLCB5QiksIFIgPSBtYXgoeUEsIHlCKTsKICAgIGZvciAoaW50IGogPSAxOyBqIDw9IHE7ICsraikKICAgIHsKICAgICAgICBhdXRvIFt4MSwgeTEsIHgyLCB5Ml0gPSBiW2pdOwogICAgICAgIGlmICh4MSA8PSBYIGFuZCBYIDw9IHgyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEoUiA8IHkxIG9yIHkyIDwgTCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCmlubGluZSBib29sIGJDKGxpbnQgWSwgbGludCB4QSwgbGludCB4QikKewogICAgbGludCBMID0gbWluKHhBLCB4QiksIFIgPSBtYXgoeEEsIHhCKTsKICAgIGZvciAoaW50IGogPSAxOyBqIDw9IHE7ICsraikKICAgIHsKICAgICAgICBhdXRvIFt4MSwgeTEsIHgyLCB5Ml0gPSBiW2pdOwogICAgICAgIGlmICh5MSA8PSBZIGFuZCBZIDw9IHkyKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKCEoUiA8IHgxIG9yIHgyIDwgTCkpCiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICByZXR1cm4gZmFsc2U7Cn0KCnZvaWQgZGlqa3N0cmEoKQp7CiAgICBmaWxsKGRpc3RbMF0sIGRpc3RbMF0gKyBwICsgMiwgSU5GKTsKICAgIGZpbGwoZGlzdFsxXSwgZGlzdFsxXSArIHAgKyAyLCBJTkYpOwoKICAgIGRpc3RbMF1bMF0gPSAwOwoKICAgIHByaW9yaXR5X3F1ZXVlPERhdGEsIHZlY3RvcjxEYXRhPiwgZ3JlYXRlcjxEYXRhPj4gcHE7CgogICAgcHEuZW1wbGFjZSgwLCAwLCAwKTsKCiAgICB3aGlsZSAoIXBxLmVtcHR5KCkpCiAgICB7CiAgICAgICAgYXV0byBbZHUsIG1vZGUsIHVdID0gcHEudG9wKCk7CiAgICAgICAgcHEucG9wKCk7CiAgICAgICAgaWYgKGR1ID4gZGlzdFttb2RlXVt1XSkKICAgICAgICAgICAgY29udGludWU7CgogICAgICAgIGF1dG8gW2lkeCwgaWR5LCBjaWR4LCBjaWR5LCBpZCwgaWRoLCBpZGNdID0gYVt1XTsKCiAgICAgICAgaWYgKDEgPD0gdSBhbmQgdSA8PSBwKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGRpc3RbIW1vZGVdW3VdID4gZGlzdFttb2RlXVt1XSArIDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGRpc3RbIW1vZGVdW3VdID0gZGlzdFttb2RlXVt1XSArIDE7CiAgICAgICAgICAgICAgICBwcS5lbXBsYWNlKGRpc3RbIW1vZGVdW3VdLCAhbW9kZSwgdSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGlmIChtb2RlID09IDEpCiAgICAgICAgewogICAgICAgICAgICBpZiAoaWRoID4gMCkKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0byBbd19hZGosIGlkX2Fkal0gPSBhZGpoW2NpZHhdW2lkaCAtIDFdOwogICAgICAgICAgICAgICAgaWYgKCFiUihpZHgsIGlkeSwgd19hZGopIGFuZCBkaXN0W21vZGVdW2lkX2Fkal0gPiBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR5KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkaXN0W21vZGVdW2lkX2Fkal0gPSBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR5KTsKICAgICAgICAgICAgICAgICAgICBwcS5lbXBsYWNlKGRpc3RbbW9kZV1baWRfYWRqXSwgbW9kZSwgaWRfYWRqKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaWRoIDwgYWRqaFtjaWR4XS5zaXplKCkgLSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhdXRvIFt3X2FkaiwgaWRfYWRqXSA9IGFkamhbY2lkeF1baWRoICsgMV07CiAgICAgICAgICAgICAgICBpZiAoIWJSKGlkeCwgaWR5LCB3X2FkaikgYW5kIGRpc3RbbW9kZV1baWRfYWRqXSA+IGRpc3RbbW9kZV1bdV0gKyBhYnMod19hZGogLSBpZHkpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRpc3RbbW9kZV1baWRfYWRqXSA9IGRpc3RbbW9kZV1bdV0gKyBhYnMod19hZGogLSBpZHkpOwogICAgICAgICAgICAgICAgICAgIHBxLmVtcGxhY2UoZGlzdFttb2RlXVtpZF9hZGpdLCBtb2RlLCBpZF9hZGopOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGlmIChpZGMgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhdXRvIFt3X2FkaiwgaWRfYWRqXSA9IGFkamNbY2lkeV1baWRjIC0gMV07CiAgICAgICAgICAgICAgICBpZiAoIWJDKGlkeSwgaWR4LCB3X2FkaikgYW5kIGRpc3RbbW9kZV1baWRfYWRqXSA+IGRpc3RbbW9kZV1bdV0gKyBhYnMod19hZGogLSBpZHgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGRpc3RbbW9kZV1baWRfYWRqXSA9IGRpc3RbbW9kZV1bdV0gKyBhYnMod19hZGogLSBpZHgpOwogICAgICAgICAgICAgICAgICAgIHBxLmVtcGxhY2UoZGlzdFttb2RlXVtpZF9hZGpdLCBtb2RlLCBpZF9hZGopOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpZGMgPCBhZGpjW2NpZHldLnNpemUoKSAtIDEpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dG8gW3dfYWRqLCBpZF9hZGpdID0gYWRqY1tjaWR5XVtpZGMgKyAxXTsKICAgICAgICAgICAgICAgIGlmICghYkMoaWR5LCBpZHgsIHdfYWRqKSBhbmQgZGlzdFttb2RlXVtpZF9hZGpdID4gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGlzdFttb2RlXVtpZF9hZGpdID0gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeCk7CiAgICAgICAgICAgICAgICAgICAgcHEuZW1wbGFjZShkaXN0W21vZGVdW2lkX2Fkal0sIG1vZGUsIGlkX2Fkaik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnZvaWQgZGlqa3N0cmExKCkKewogICAgZmlsbChkaXN0WzBdLCBkaXN0WzBdICsgcCArIDIsIElORik7CiAgICBmaWxsKGRpc3RbMV0sIGRpc3RbMV0gKyBwICsgMiwgSU5GKTsKCiAgICBkaXN0WzBdWzBdID0gMDsKCiAgICBwcmlvcml0eV9xdWV1ZTxEYXRhLCB2ZWN0b3I8RGF0YT4sIGdyZWF0ZXI8RGF0YT4+IHBxOwoKICAgIHBxLmVtcGxhY2UoMCwgMCwgMCk7CgogICAgd2hpbGUgKCFwcS5lbXB0eSgpKQogICAgewogICAgICAgIGF1dG8gW2R1LCBtb2RlLCB1XSA9IHBxLnRvcCgpOwogICAgICAgIHBxLnBvcCgpOwogICAgICAgIGlmIChkdSA+IGRpc3RbbW9kZV1bdV0pCiAgICAgICAgICAgIGNvbnRpbnVlOwoKICAgICAgICBhdXRvIFtpZHgsIGlkeSwgY2lkeCwgY2lkeSwgaWQsIGlkaCwgaWRjXSA9IGFbdV07CgogICAgICAgIGlmICgxIDw9IHUgYW5kIHUgPD0gcCkKICAgICAgICB7CiAgICAgICAgICAgIGlmIChkaXN0WyFtb2RlXVt1XSA+IGRpc3RbbW9kZV1bdV0gKyAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkaXN0WyFtb2RlXVt1XSA9IGRpc3RbbW9kZV1bdV0gKyAxOwogICAgICAgICAgICAgICAgcHEuZW1wbGFjZShkaXN0WyFtb2RlXVt1XSwgIW1vZGUsIHUpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBpZiAobW9kZSA9PSAxKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlkaCA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dG8gW3dfYWRqLCBpZF9hZGpdID0gYWRqaFtjaWR4XVtpZGggLSAxXTsKICAgICAgICAgICAgICAgIGxpbnQgWFggPSBhW2lkX2Fkal0uWDsKICAgICAgICAgICAgICAgIGxpbnQgWVkgPSBhW2lkX2Fkal0uWTsKICAgICAgICAgICAgICAgIGlmICghKGhwcmVmW1hYXVtpZHldIC0gaHByZWZbWFhdW1lZIC0gMV0pIGFuZCBkaXN0W21vZGVdW2lkX2Fkal0gPiBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR5KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkaXN0W21vZGVdW2lkX2Fkal0gPSBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR5KTsKICAgICAgICAgICAgICAgICAgICBwcS5lbXBsYWNlKGRpc3RbbW9kZV1baWRfYWRqXSwgbW9kZSwgaWRfYWRqKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaWRoIDwgYWRqaFtjaWR4XS5zaXplKCkgLSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhdXRvIFt3X2FkaiwgaWRfYWRqXSA9IGFkamhbY2lkeF1baWRoICsgMV07CiAgICAgICAgICAgICAgICBsaW50IFhYID0gYVtpZF9hZGpdLlg7CiAgICAgICAgICAgICAgICBsaW50IFlZID0gYVtpZF9hZGpdLlk7CiAgICAgICAgICAgICAgICBpZiAoIShocHJlZltYWF1bWVldIC0gaHByZWZbWFhdW2lkeSAtIDFdKSBhbmQgZGlzdFttb2RlXVtpZF9hZGpdID4gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeSkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGlzdFttb2RlXVtpZF9hZGpdID0gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeSk7CiAgICAgICAgICAgICAgICAgICAgcHEuZW1wbGFjZShkaXN0W21vZGVdW2lkX2Fkal0sIG1vZGUsIGlkX2Fkaik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgaWYgKGlkYyA+IDApCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dG8gW3dfYWRqLCBpZF9hZGpdID0gYWRqY1tjaWR5XVtpZGMgLSAxXTsKICAgICAgICAgICAgICAgIGxpbnQgWFggPSBhW2lkX2Fkal0uWDsKICAgICAgICAgICAgICAgIGxpbnQgWVkgPSBhW2lkX2Fkal0uWTsKICAgICAgICAgICAgICAgIGlmICghKGNwcmVmW2lkeF1bWVldIC0gY3ByZWZbWFggLSAxXVtZWV0pIGFuZCBkaXN0W21vZGVdW2lkX2Fkal0gPiBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR4KSkKICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICBkaXN0W21vZGVdW2lkX2Fkal0gPSBkaXN0W21vZGVdW3VdICsgYWJzKHdfYWRqIC0gaWR4KTsKICAgICAgICAgICAgICAgICAgICBwcS5lbXBsYWNlKGRpc3RbbW9kZV1baWRfYWRqXSwgbW9kZSwgaWRfYWRqKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaWRjIDwgYWRqY1tjaWR5XS5zaXplKCkgLSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBhdXRvIFt3X2FkaiwgaWRfYWRqXSA9IGFkamNbY2lkeV1baWRjICsgMV07CiAgICAgICAgICAgICAgICBsaW50IFhYID0gYVtpZF9hZGpdLlg7CiAgICAgICAgICAgICAgICBsaW50IFlZID0gYVtpZF9hZGpdLlk7CiAgICAgICAgICAgICAgICBpZiAoIShjcHJlZltYWF1bWVldIC0gY3ByZWZbaWR4IC0gMV1bWVldKSBhbmQgZGlzdFttb2RlXVtpZF9hZGpdID4gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeCkpCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgZGlzdFttb2RlXVtpZF9hZGpdID0gZGlzdFttb2RlXVt1XSArIGFicyh3X2FkaiAtIGlkeCk7CiAgICAgICAgICAgICAgICAgICAgcHEuZW1wbGFjZShkaXN0W21vZGVdW2lkX2Fkal0sIG1vZGUsIGlkX2Fkaik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0KCnZvaWQgY29tcHJlc3MoKQoKewogICAgdmVjdG9yPHBhaXI8bGludCwgaW50Pj4gdngsIHZ5OwogICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gcCArIDE7IGkrKykKICAgICAgICB2eC5lbXBsYWNlX2JhY2soYVtpXS5YLCBpKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDw9IHAgKyAxOyBpKyspCiAgICAgICAgdnkuZW1wbGFjZV9iYWNrKGFbaV0uWSwgaSk7CiAgICBzb3J0KHZ4LmJlZ2luKCksIHZ4LmVuZCgpKTsKICAgIHNvcnQodnkuYmVnaW4oKSwgdnkuZW5kKCkpOwogICAgaW50IGN4ID0gMCwgY3kgPSAwOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2eC5zaXplKCk7IGkrKykKICAgIHsKICAgICAgICBpZiAoaSA9PSAwIG9yIHZ4W2ldLmZpICE9IHZ4W2kgLSAxXS5maSkKICAgICAgICAgICAgKytjeDsKICAgICAgICBhW3Z4W2ldLnNlXS5DWCA9IGN4OwogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCB2eS5zaXplKCk7IGkrKykKICAgIHsKICAgICAgICBpZiAoaSA9PSAwIG9yIHZ5W2ldLmZpICE9IHZ5W2kgLSAxXS5maSkKICAgICAgICAgICAgKytjeTsKICAgICAgICBhW3Z5W2ldLnNlXS5DWSA9IGN5OwogICAgfQp9CgpmYW1pIGxvcmUoKQp7CiAgICBpZiAoZm9wZW4oInN0YXJvZmhvcGUuaW5wIiwgInIiKSkKICAgIHsKICAgICAgICBmcmVlZmlyZSgic3Rhcm9maG9wZS5pbnAiLCAiciIsIHN0ZGluKTsKICAgICAgICBmcmVlZmlyZSgic3Rhcm9maG9wZS5vdXQiLCAidyIsIHN0ZG91dCk7CiAgICB9CiAgICBTUEVEOwogICAgY2luID4+IHQ7CiAgICB3aGlsZSAodC0tKQogICAgewogICAgICAgIGNpbiA+PiBtID4+IG4gPj4gcCA+PiBxOwoKICAgICAgICBhWzBdID0gezEsIDEsIDAsIDAsIDAsIDAsIDB9OwogICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IHA7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGludCBOLCBFOwogICAgICAgICAgICBjaW4gPj4gTiA+PiBFOwogICAgICAgICAgICBhW2ldID0ge04sIEUsIDAsIDAsIGksIDAsIDB9OwogICAgICAgIH0KICAgICAgICBhW3AgKyAxXSA9IHttLCBuLCAwLCAwLCBwICsgMSwgMCwgMH07CgogICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IHE7IGkrKykKICAgICAgICB7CiAgICAgICAgICAgIGxpbnQgTiwgSSwgRywgQTsKICAgICAgICAgICAgY2luID4+IE4gPj4gSSA+PiBHID4+IEE7CiAgICAgICAgICAgIGJbaV0gPSB7TiwgSSwgRywgQX07CiAgICAgICAgfQoKICAgICAgICBjb21wcmVzcygpOwoKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8PSBwICsgMTsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgYXV0byBbaWR4LCBpZHksIGNpZHgsIGNpZHksIGlkLCBpZGgsIGlkY10gPSBhW2ldOwogICAgICAgICAgICBhZGpoW2NpZHhdLmVtcGxhY2VfYmFjayhpZHksIGlkKTsKICAgICAgICAgICAgYWRqY1tjaWR5XS5lbXBsYWNlX2JhY2soaWR4LCBpZCk7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBwICsgMjsgaSsrKQogICAgICAgIHsKICAgICAgICAgICAgc29ydChhZGpoW2ldLmJlZ2luKCksIGFkamhbaV0uZW5kKCkpOwogICAgICAgICAgICBzb3J0KGFkamNbaV0uYmVnaW4oKSwgYWRqY1tpXS5lbmQoKSk7CiAgICAgICAgfQoKICAgICAgICBmb3IgKGludCBpZCA9IDE7IGlkIDw9IHAgKyAyOyBpZCsrKQogICAgICAgIHsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBhZGpoW2lkXS5zaXplKCk7IGkrKykKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYXV0byBbd2MsIGlkeF0gPSBhZGpoW2lkXVtpXTsKICAgICAgICAgICAgICAgIGFbaWR4XS5pZEggPSBpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgYWRqY1tpZF0uc2l6ZSgpOyBpKyspCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dG8gW3doLCBpZHhdID0gYWRqY1tpZF1baV07CiAgICAgICAgICAgICAgICBhW2lkeF0uaWRDID0gaTsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgaWYgKG0gPD0gMjAwMCBhbmQgbiA8PSAyMDAwIGFuZCBxID4gMTApCiAgICAgICAgewogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBxOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGF1dG8gW3gxLCB5MSwgeDIsIHkyXSA9IGJbaV07CiAgICAgICAgICAgICAgICArK2RwW3gxXVt5MV07CiAgICAgICAgICAgICAgICAtLWRwW3gyICsgMV1beTFdOwogICAgICAgICAgICAgICAgLS1kcFt4MV1beTIgKyAxXTsKICAgICAgICAgICAgICAgICsrZHBbeDIgKyAxXVt5MiArIDFdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBtICsgMTsgKytpKQogICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPD0gbiArIDE7ICsraikKICAgICAgICAgICAgICAgICAgICBkcFtpXVtqXSArPSBkcFtpIC0gMV1bal0gKyBkcFtpXVtqIC0gMV0gLSBkcFtpIC0gMV1baiAtIDFdOwoKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDE7IGkgPD0gbTsgKytpKQogICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDE7IGogPD0gbjsgKytqKQogICAgICAgICAgICAgICAgICAgIGRwW2ldW2pdID0gKGRwW2ldW2pdID4gMCk7CgogICAgICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8PSBtOyArK2kpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGhwcmVmW2ldWzBdID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaW50IGogPSAxOyBqIDw9IG47ICsraikKICAgICAgICAgICAgICAgICAgICBocHJlZltpXVtqXSA9IGhwcmVmW2ldW2ogLSAxXSArIGRwW2ldW2pdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IgKGludCBqID0gMTsgaiA8PSBuOyArK2opCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGNwcmVmWzBdW2pdID0gMDsKICAgICAgICAgICAgICAgIGZvciAoaW50IGkgPSAxOyBpIDw9IG07ICsraSkKICAgICAgICAgICAgICAgICAgICBjcHJlZltpXVtqXSA9IGNwcmVmW2kgLSAxXVtqXSArIGRwW2ldW2pdOwogICAgICAgICAgICB9CgogICAgICAgICAgICBkaWprc3RyYTEoKTsKCiAgICAgICAgICAgIGxpbnQgcmVzID0gbWluKGRpc3RbMF1bcCArIDFdLCBkaXN0WzFdW3AgKyAxXSk7CgogICAgICAgICAgICBjb3V0IDw8IChyZXMgPT0gSU5GID8gLTEgOiByZXMpIDw8IGVuZGw7CgogICAgICAgICAgICByZXNldDEoKTsKICAgICAgICB9CgogICAgICAgIGVsc2UKICAgICAgICB7CiAgICAgICAgICAgIGRpamtzdHJhKCk7CgogICAgICAgICAgICBsaW50IHJlcyA9IG1pbihkaXN0WzBdW3AgKyAxXSwgZGlzdFsxXVtwICsgMV0pOwoKICAgICAgICAgICAgY291dCA8PCAocmVzID09IElORiA/IC0xIDogcmVzKSA8PCBlbmRsOwoKICAgICAgICAgICAgcmVzZXQoKTsKICAgICAgICB9CiAgICB9Cn0KLy8gTGV0IHlvdXIgc291bCB3YW5kZXIgd2hlcmUgZHJlYW1zIGFyZSBib3JuLgo=