#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct edge
{
int v, to, cap, scap;
edge(int a, int b, int c)
{
v = a, to = b, cap = c, scap = c;
}
edge() {}
};
struct rect
{
int x1, y1, x2, y2;
};
struct tri
{
int y1, y2, x;
};
bool operator < (const tri &a, const tri &b)
{
return a.y1 < b.y1;
};
const int N = 1e6 + 7;
const int INF = 1e9 + 7;
vector <edge> e;
vector <int> g[N];
int us[N];
int usbs = 1;
int d[N];
int q[N];
int ded[N];
int ptr[N];
vector <rect> fget[N];
int after_bfs = 1;
int visb = 1;
ll ans = 0;
int qh, qt;
int s, t;
int l;
bool bfs()
{
qh = qt = 0;
us[s] = usbs;
q[qt++] = s;
d[s] = 0;
while (qh < qt)
{
int v = q[qh++];
for (auto c : g[v])
{
if (us[e[c].to] != usbs && e[c].cap > 0)
{
d[e[c].to] = d[v] + 1;
us[e[c].to] = usbs;
q[qt++] = e[c].to;
}
}
}
return (us[t] == usbs++);
}
int dfs(int v = s, int c = 1e9)
{
if (!c)
{
return 0;
}
if (v == t)
{
ans += c;
return c;
}
if (ded[v] != after_bfs)
{
ded[v] = after_bfs;
ptr[v] = 0;
}
for (; ptr[v] < (int) g[v].size(); ptr[v]++)
{
int ind = g[v][ptr[v]];
if (e[ind].cap > 0 && d[e[ind].to] == d[v] + 1)
{
int x = dfs(e[ind].to, min(c, e[ind].cap));
if (x)
{
e[ind].cap -= x;
e[ind ^ 1].cap += x;
return x;
}
}
}
return 0;
}
void add_edge(int u, int v, int cap)
{
g[u].push_back(e.size());
e.push_back({u, v, cap});
g[v].push_back(e.size());
e.push_back({v, u, 0});
}
ll dinic(int a, int b)
{
s = a, t = b;
while (bfs())
{
after_bfs++;
while (dfs())
{
continue;
}
}
return ans;
}
vector <int> inds;
int lel(int v, int l, int r, int i)
{
if (r - l == 1)
{
return v;
}
else
{
int m = (l + r) / 2;
if (i < m)
{
return lel(v * 2 + 1, l, m, i);
}
else
{
return lel(v * 2 + 2, m, r, i);
}
}
}
void get(int v, int l, int r, int tl, int tr)
{
if (tl >= r || tr <= l)
{
return;
}
if (tl >= l && tr <= r)
{
inds.push_back(v);
}
else
{
int tm = (tl + tr) / 2;
get(v * 2 + 1, l, r, tl, tm);
get(v * 2 + 2, l, r, tm, tr);
}
}
void build(int v, int l, int r, int ax, int bx, int n)
{
if (r - l == 1)
{
add_edge(l, ax + v, 1);
add_edge(bx + v, n + l, 1);
}
else
{
int m = (l + r) / 2;
build(v * 2 + 1, l, m, ax, bx, n);
build(v * 2 + 2, m, r, ax, bx, n);
add_edge(ax + v * 2 + 1, ax + v, INF);
add_edge(ax + v * 2 + 2, ax + v, INF);
add_edge(bx + v, bx + v * 2 + 1, INF);
add_edge(bx + v, bx + v * 2 + 2, INF);
}
}
int main()
{
#ifdef ONPC
freopen("a.in", "r", stdin);
//freopen("a.out", "w", stdout);
#else
//freopen("a.in", "r", stdin);
//freopen("a.out", "w", stdout);
#endif
vector <rect> fre;
int n, q;
scanf("%d", &n);
scanf("%d", &q);
for (int i = 0; i < q; i++)
{
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1--, y1--, x2--, y2--;
fget[x2].push_back({x1, y1, x2, y2});
}
set <tri> s;
s.insert({0, n - 1, 0});
for (int i = 0; i < n; i++)
{
for (auto c : fget[i])
{
auto it = s.lower_bound({c.y1, -1, -1});
vector <tri> gt;
if (it != s.begin())
{
it--;
gt.push_back(*it);
it++;
}
bool b = false;
while (it != s.end() && (it->y2 <= c.y2 || !b))
{
gt.push_back(*it);
it++;
if (it != s.end())
{
if (it->y2 > c.y2)
{
gt.push_back(*it);
b = true;
}
}
}
for (auto d : gt)
{
if (max(d.y1, c.y1) > min(d.y2, c.y2))
{
continue;
}
s.erase(d);
if (c.y1 <= d.y1 && d.y2 <= c.y2)
{
int a = d.x, b = c.x1 - 1;
if (a <= b)
{
fre.push_back({a, d.y1, b, d.y2});
}
}
else
{
if (d.y1 <= c.y1 && c.y2 <= d.y2)
{
auto was = d;
was.y2 = c.y1 - 1;
if (was.y1 <= was.y2)
{
s.insert(was);
}
was = d;
was.y1 = c.y2 + 1;
if (was.y1 <= was.y2)
{
s.insert(was);
}
int a = d.x, b = c.x1 - 1;
if (a <= b)
{
fre.push_back({a, c.y1, b, c.y2});
}
}
else if (d.y2 > c.y2)
{
auto was = d;
was.y1 = c.y2 + 1;
s.insert(was);
int a = d.x, b = c.x1 - 1;
if (a <= b)
{
fre.push_back({a, d.y1, b, c.y2});
}
}
else if (d.y1 < c.y1)
{
auto was = d;
was.y2 = c.y1 - 1;
s.insert(was);
int a = d.x, b = c.x1 - 1;
if (a <= b)
{
fre.push_back({a, c.y1, b, d.y2});
}
}
}
}
if (c.x2 != n - 1)
{
s.insert({c.y1, c.y2, c.x2 + 1});
}
}
}
for (auto c : s)
{
fre.push_back({c.x, c.y1, n - 1, c.y2});
}
inds.clear();
get(0, n - 1, n, 0, n);
int cnt = inds[0] + 1;
for (auto c : fre)
{
int x1 = c.x1, y1 = c.y1, x2 = c.x2, y2 = c.y2;
inds.clear();
get(0, x1, x2 + 1, 0, n);
vector <int> a = inds;
inds.clear();
get(0, y1, y2 + 1, 0, n);
vector <int> b = inds;
for (auto c : a)
{
for (auto d : b)
{
add_edge(n + n + c, n + n + cnt + d, INF);
}
}
}
build(0, 0, n, n + n, n + n + cnt, n);
int st = n + n + cnt + cnt, en = n + n + cnt + cnt + 1;
for (int i = 0; i < n; i++)
{
add_edge(st, i, 1);
add_edge(i + n, en, 1);
}
printf("%lld\n", dinic(st, en));
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBsb25nIGxvbmcgbGw7CiAgICAgICAgCgpzdHJ1Y3QgZWRnZQp7CiAgICBpbnQgdiwgdG8sIGNhcCwgc2NhcDsKICAgIGVkZ2UoaW50IGEsIGludCBiLCBpbnQgYykKICAgIHsKICAgICAgICB2ID0gYSwgdG8gPSBiLCBjYXAgPSBjLCBzY2FwID0gYzsKICAgIH0KICAgIGVkZ2UoKSB7fQp9OwoKc3RydWN0IHJlY3QKewogICAgaW50IHgxLCB5MSwgeDIsIHkyOwp9OwoKc3RydWN0IHRyaQp7CiAgICBpbnQgeTEsIHkyLCB4Owp9OwoKYm9vbCBvcGVyYXRvciA8IChjb25zdCB0cmkgJmEsIGNvbnN0IHRyaSAmYikKewogICAgcmV0dXJuIGEueTEgPCBiLnkxOwp9OwoKY29uc3QgaW50IE4gPSAxZTYgKyA3Owpjb25zdCBpbnQgSU5GID0gMWU5ICsgNzsKCnZlY3RvciA8ZWRnZT4gZTsKdmVjdG9yIDxpbnQ+IGdbTl07CmludCB1c1tOXTsKaW50IHVzYnMgPSAxOwppbnQgZFtOXTsKaW50IHFbTl07CmludCBkZWRbTl07CmludCBwdHJbTl07CnZlY3RvciA8cmVjdD4gZmdldFtOXTsKaW50IGFmdGVyX2JmcyA9IDE7CmludCB2aXNiID0gMTsKbGwgYW5zID0gMDsKaW50IHFoLCBxdDsKaW50IHMsIHQ7CmludCBsOwoKYm9vbCBiZnMoKQp7CiAgICBxaCA9IHF0ID0gMDsKICAgIHVzW3NdID0gdXNiczsKICAgIHFbcXQrK10gPSBzOwogICAgZFtzXSA9IDA7CiAgICB3aGlsZSAocWggPCBxdCkKICAgIHsKICAgICAgICBpbnQgdiA9IHFbcWgrK107CiAgICAgICAgZm9yIChhdXRvIGMgOiBnW3ZdKQogICAgICAgIHsKICAgICAgICAgICAgaWYgKHVzW2VbY10udG9dICE9IHVzYnMgJiYgZVtjXS5jYXAgPiAwKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBkW2VbY10udG9dID0gZFt2XSArIDE7CiAgICAgICAgICAgICAgICB1c1tlW2NdLnRvXSA9IHVzYnM7CiAgICAgICAgICAgICAgICBxW3F0KytdID0gZVtjXS50bzsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAodXNbdF0gPT0gdXNicysrKTsKfQoKaW50IGRmcyhpbnQgdiA9IHMsIGludCBjID0gMWU5KQp7CiAgICBpZiAoIWMpCiAgICB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CiAgICBpZiAodiA9PSB0KQogICAgewogICAgICAgIGFucyArPSBjOwogICAgICAgIHJldHVybiBjOwogICAgfQogICAgaWYgKGRlZFt2XSAhPSBhZnRlcl9iZnMpCiAgICB7CiAgICAgICAgZGVkW3ZdID0gYWZ0ZXJfYmZzOwogICAgICAgIHB0clt2XSA9IDA7CiAgICB9CiAgICBmb3IgKDsgcHRyW3ZdIDwgKGludCkgZ1t2XS5zaXplKCk7IHB0clt2XSsrKQogICAgewogICAgICAgIGludCBpbmQgPSBnW3ZdW3B0clt2XV07CiAgICAgICAgaWYgKGVbaW5kXS5jYXAgPiAwICYmIGRbZVtpbmRdLnRvXSA9PSBkW3ZdICsgMSkKICAgICAgICB7CiAgICAgICAgICAgIGludCB4ID0gZGZzKGVbaW5kXS50bywgbWluKGMsIGVbaW5kXS5jYXApKTsKICAgICAgICAgICAgaWYgKHgpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGVbaW5kXS5jYXAgLT0geDsKICAgICAgICAgICAgICAgIGVbaW5kIF4gMV0uY2FwICs9IHg7CiAgICAgICAgICAgICAgICByZXR1cm4geDsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cgp2b2lkIGFkZF9lZGdlKGludCB1LCBpbnQgdiwgaW50IGNhcCkKewogICAgZ1t1XS5wdXNoX2JhY2soZS5zaXplKCkpOwogICAgZS5wdXNoX2JhY2soe3UsIHYsIGNhcH0pOwogICAgZ1t2XS5wdXNoX2JhY2soZS5zaXplKCkpOwogICAgZS5wdXNoX2JhY2soe3YsIHUsIDB9KTsKfQoKbGwgZGluaWMoaW50IGEsIGludCBiKQp7CiAgICBzID0gYSwgdCA9IGI7CiAgICB3aGlsZSAoYmZzKCkpCiAgICB7CiAgICAgICAgYWZ0ZXJfYmZzKys7CiAgICAgICAgd2hpbGUgKGRmcygpKQogICAgICAgIHsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIGFuczsKfQoKdmVjdG9yIDxpbnQ+IGluZHM7CgppbnQgbGVsKGludCB2LCBpbnQgbCwgaW50IHIsIGludCBpKQp7CiAgICBpZiAociAtIGwgPT0gMSkKICAgIHsKICAgICAgICByZXR1cm4gdjsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgbSA9IChsICsgcikgLyAyOwogICAgICAgIGlmIChpIDwgbSkKICAgICAgICB7CiAgICAgICAgICAgIHJldHVybiBsZWwodiAqIDIgKyAxLCBsLCBtLCBpKTsKICAgICAgICB9CiAgICAgICAgZWxzZQogICAgICAgIHsKICAgICAgICAgICAgcmV0dXJuIGxlbCh2ICogMiArIDIsIG0sIHIsIGkpOwogICAgICAgIH0KICAgIH0KfQoKdm9pZCBnZXQoaW50IHYsIGludCBsLCBpbnQgciwgaW50IHRsLCBpbnQgdHIpCnsKICAgIGlmICh0bCA+PSByIHx8IHRyIDw9IGwpCiAgICB7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKHRsID49IGwgJiYgdHIgPD0gcikKICAgIHsKICAgICAgICBpbmRzLnB1c2hfYmFjayh2KTsKICAgIH0KICAgIGVsc2UKICAgIHsKICAgICAgICBpbnQgdG0gPSAodGwgKyB0cikgLyAyOwogICAgICAgIGdldCh2ICogMiArIDEsIGwsIHIsIHRsLCB0bSk7CiAgICAgICAgZ2V0KHYgKiAyICsgMiwgbCwgciwgdG0sIHRyKTsKICAgIH0KfQoKdm9pZCBidWlsZChpbnQgdiwgaW50IGwsIGludCByLCBpbnQgYXgsIGludCBieCwgaW50IG4pCnsKICAgIGlmIChyIC0gbCA9PSAxKQogICAgewogICAgICAgIGFkZF9lZGdlKGwsIGF4ICsgdiwgMSk7CiAgICAgICAgYWRkX2VkZ2UoYnggKyB2LCBuICsgbCwgMSk7CiAgICB9CiAgICBlbHNlCiAgICB7CiAgICAgICAgaW50IG0gPSAobCArIHIpIC8gMjsKICAgICAgICBidWlsZCh2ICogMiArIDEsIGwsIG0sIGF4LCBieCwgbik7CiAgICAgICAgYnVpbGQodiAqIDIgKyAyLCBtLCByLCBheCwgYngsIG4pOwogICAgICAgIGFkZF9lZGdlKGF4ICsgdiAqIDIgKyAxLCBheCArIHYsIElORik7CiAgICAgICAgYWRkX2VkZ2UoYXggKyB2ICogMiArIDIsIGF4ICsgdiwgSU5GKTsKICAgICAgICBhZGRfZWRnZShieCArIHYsIGJ4ICsgdiAqIDIgKyAxLCBJTkYpOwogICAgICAgIGFkZF9lZGdlKGJ4ICsgdiwgYnggKyB2ICogMiArIDIsIElORik7CiAgICB9Cn0KCmludCBtYWluKCkKewojaWZkZWYgT05QQwogICAgZnJlb3BlbigiYS5pbiIsICJyIiwgc3RkaW4pOwogICAgLy9mcmVvcGVuKCJhLm91dCIsICJ3Iiwgc3Rkb3V0KTsKI2Vsc2UKICAgIC8vZnJlb3BlbigiYS5pbiIsICJyIiwgc3RkaW4pOwogICAgLy9mcmVvcGVuKCJhLm91dCIsICJ3Iiwgc3Rkb3V0KTsKI2VuZGlmCiAgICB2ZWN0b3IgPHJlY3Q+IGZyZTsKICAgIGludCBuLCBxOwogICAgc2NhbmYoIiVkIiwgJm4pOwogICAgc2NhbmYoIiVkIiwgJnEpOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBxOyBpKyspCiAgICB7CiAgICAgICAgaW50IHgxLCB5MSwgeDIsIHkyOwogICAgICAgIHNjYW5mKCIlZCVkJWQlZCIsICZ4MSwgJnkxLCAmeDIsICZ5Mik7CiAgICAgICAgeDEtLSwgeTEtLSwgeDItLSwgeTItLTsKICAgICAgICBmZ2V0W3gyXS5wdXNoX2JhY2soe3gxLCB5MSwgeDIsIHkyfSk7CiAgICB9CiAgICBzZXQgPHRyaT4gczsKICAgIHMuaW5zZXJ0KHswLCBuIC0gMSwgMH0pOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgZm9yIChhdXRvIGMgOiBmZ2V0W2ldKQogICAgICAgIHsKICAgICAgICAgICAgYXV0byBpdCA9IHMubG93ZXJfYm91bmQoe2MueTEsIC0xLCAtMX0pOwogICAgICAgICAgICB2ZWN0b3IgPHRyaT4gZ3Q7CiAgICAgICAgICAgIGlmIChpdCAhPSBzLmJlZ2luKCkpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGl0LS07CiAgICAgICAgICAgICAgICBndC5wdXNoX2JhY2soKml0KTsKICAgICAgICAgICAgICAgIGl0Kys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYm9vbCBiID0gZmFsc2U7CiAgICAgICAgICAgIHdoaWxlIChpdCAhPSBzLmVuZCgpICYmIChpdC0+eTIgPD0gYy55MiB8fCAhYikpCiAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgIGd0LnB1c2hfYmFjaygqaXQpOwogICAgICAgICAgICAgICAgaXQrKzsKICAgICAgICAgICAgICAgIGlmIChpdCAhPSBzLmVuZCgpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGlmIChpdC0+eTIgPiBjLnkyKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgZ3QucHVzaF9iYWNrKCppdCk7CiAgICAgICAgICAgICAgICAgICAgICAgIGIgPSB0cnVlOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IgKGF1dG8gZCA6IGd0KQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBpZiAobWF4KGQueTEsIGMueTEpID4gbWluKGQueTIsIGMueTIpKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcy5lcmFzZShkKTsKICAgICAgICAgICAgICAgIGlmIChjLnkxIDw9IGQueTEgJiYgZC55MiA8PSBjLnkyKQogICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgIGludCBhID0gZC54LCBiID0gYy54MSAtIDE7CiAgICAgICAgICAgICAgICAgICAgaWYgKGEgPD0gYikKICAgICAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgICAgIGZyZS5wdXNoX2JhY2soe2EsIGQueTEsIGIsIGQueTJ9KTsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAgICAgaWYgKGQueTEgPD0gYy55MSAmJiBjLnkyIDw9IGQueTIpCiAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICBhdXRvIHdhcyA9IGQ7CiAgICAgICAgICAgICAgICAgICAgICAgIHdhcy55MiA9IGMueTEgLSAxOwogICAgICAgICAgICAgICAgICAgICAgICBpZiAod2FzLnkxIDw9IHdhcy55MikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgcy5pbnNlcnQod2FzKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgICAgICB3YXMgPSBkOwogICAgICAgICAgICAgICAgICAgICAgICB3YXMueTEgPSBjLnkyICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHdhcy55MSA8PSB3YXMueTIpCiAgICAgICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMuaW5zZXJ0KHdhcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgaW50IGEgPSBkLngsIGIgPSBjLngxIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgPD0gYikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlLnB1c2hfYmFjayh7YSwgYy55MSwgYiwgYy55Mn0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGQueTIgPiBjLnkyKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0byB3YXMgPSBkOwogICAgICAgICAgICAgICAgICAgICAgICB3YXMueTEgPSBjLnkyICsgMTsKICAgICAgICAgICAgICAgICAgICAgICAgcy5pbnNlcnQod2FzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGEgPSBkLngsIGIgPSBjLngxIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgPD0gYikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlLnB1c2hfYmFjayh7YSwgZC55MSwgYiwgYy55Mn0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKGQueTEgPCBjLnkxKQogICAgICAgICAgICAgICAgICAgIHsKICAgICAgICAgICAgICAgICAgICAgICAgYXV0byB3YXMgPSBkOwogICAgICAgICAgICAgICAgICAgICAgICB3YXMueTIgPSBjLnkxIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgcy5pbnNlcnQod2FzKTsKICAgICAgICAgICAgICAgICAgICAgICAgaW50IGEgPSBkLngsIGIgPSBjLngxIC0gMTsKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGEgPD0gYikKICAgICAgICAgICAgICAgICAgICAgICAgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJlLnB1c2hfYmFjayh7YSwgYy55MSwgYiwgZC55Mn0pOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChjLngyICE9IG4gLSAxKQogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICBzLmluc2VydCh7Yy55MSwgYy55MiwgYy54MiArIDF9KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGZvciAoYXV0byBjIDogcykKICAgIHsKICAgICAgICBmcmUucHVzaF9iYWNrKHtjLngsIGMueTEsIG4gLSAxLCBjLnkyfSk7CiAgICB9CiAgICBpbmRzLmNsZWFyKCk7CiAgICBnZXQoMCwgbiAtIDEsIG4sIDAsIG4pOwogICAgaW50IGNudCA9IGluZHNbMF0gKyAxOwogICAgZm9yIChhdXRvIGMgOiBmcmUpCiAgICB7CiAgICAgICAgaW50IHgxID0gYy54MSwgeTEgPSBjLnkxLCB4MiA9IGMueDIsIHkyID0gYy55MjsgICAgICAgIAogICAgICAgIGluZHMuY2xlYXIoKTsKICAgICAgICBnZXQoMCwgeDEsIHgyICsgMSwgMCwgbik7CiAgICAgICAgdmVjdG9yIDxpbnQ+IGEgPSBpbmRzOwogICAgICAgIGluZHMuY2xlYXIoKTsKICAgICAgICBnZXQoMCwgeTEsIHkyICsgMSwgMCwgbik7CiAgICAgICAgdmVjdG9yIDxpbnQ+IGIgPSBpbmRzOwogICAgICAgIGZvciAoYXV0byBjIDogYSkKICAgICAgICB7CiAgICAgICAgICAgIGZvciAoYXV0byBkIDogYikKICAgICAgICAgICAgewogICAgICAgICAgICAgICAgYWRkX2VkZ2UobiArIG4gKyBjLCBuICsgbiArIGNudCArIGQsIElORik7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CiAgICBidWlsZCgwLCAwLCBuLCBuICsgbiwgbiArIG4gKyBjbnQsIG4pOwogICAgaW50IHN0ID0gbiArIG4gKyBjbnQgKyBjbnQsIGVuID0gbiArIG4gKyBjbnQgKyBjbnQgKyAxOwogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuOyBpKyspCiAgICB7CiAgICAgICAgYWRkX2VkZ2Uoc3QsIGksIDEpOwogICAgICAgIGFkZF9lZGdlKGkgKyBuLCBlbiwgMSk7CiAgICB9CiAgICBwcmludGYoIiVsbGRcbiIsIGRpbmljKHN0LCBlbikpOwp9Cg==