#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <iostream>
#include <string.h>
//-------------------------------------macros-----------------------------------------------
#define ll long long int
#define ull unsigned long long int
#define ld long double
#define color(array, value) memset(array, value, sizeof(array))
#define colorDD(array, value) fill_n(*array, sizeof(array) / sizeof(**array), value);
#define sz(x) ((ll)x.size())
#define cerr(x) cout << #x << " = " << x << endl
#define YES cout << "YES\n"
#define NO cout << "NO\n"
#define Yes cout << "Yes\n"
#define No cout << "No\n"
#define endl "\n"
#define FOR(index, lower, upper) for (ll index = lower; index < upper; index++)
#define FORD(index, upper, lower) for (ll index = upper; index > lower; index--)
#define all(x) x.begin(), x.end()
#define rall(x) x.rbegin(), x.rend()
#define containsKey(map, key) (map.find(key) != map.end())
#define umap unordered_map
#define uset unordered_set
#define CASE(x) cout << "Case " << x << ":" << endl;
#define popcount(x) __builtin_popcount(x)
#define pll pair<ll, ll>
const ll MOD = 1e9 + 7;
const ll A_MOD = 998244353;
const ld EPS = 1e-7;
const ld PI = acos(-1.0);
const ll INF = 1e18;
/*------------------------------------Policy based data structures-------------------------------------------*/
using namespace std;
using namespace __gnu_pbds;
template <class T>
using oset = tree<T, null_type, less_equal<T>, rb_tree_tag, tree_order_statistics_node_update>;
/*-----------custom-hash------------*/
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
template <class T1, class T2>
using pmap = gp_hash_table<T1, T2, custom_hash>;
template <class T>
using pset = unordered_set<T, custom_hash>;
/*----------------------Graph Moves----------------*/
const ll dx[] = {+0, +0, +1, -1, -1, +1, -1, +1}; // Kings Move L R D U
const ll dy[] = {-1, +1, +0, +0, +1, +1, -1, -1}; // Kings Move
// const ll dx[] = {-2, -2, -1, -1, 1, 1, 2, 2}; // Knights Move
// const ll dy[] = {-1, 1, -2, 2, -2, 2, -1, 1}; // Knights Move
/*------------------------------------------------*/
bool isBitSet(ll number, ll bit) {
return (number & (1ll << bit)) != 0;
}
ll inverseBit(ll number, ll bit) {
return (number ^ (1ll << bit));
}
ll ceil_div(ll a, ll b) {
return a / b + ((a ^ b) > 0 && a % b != 0);
}
template <typename T>
T square(T v) {
return v * v;
}
bool comp_second(pair<ll, ll> &a, pair<ll, ll> &b) {
if (a.second != b.second)
return a.second < b.second;
return a.first < b.first;
}
bool comp_first_reverse(pair<ll, ll> &a, pair<ll, ll> &b) {
if (a.first != b.first)
return a.first < b.first;
return a.second > b.second;
}
bool comp_second_reverse(pair<ll, ll> &a, pair<ll, ll> &b) {
if (a.second != b.second)
return a.second > b.second;
return a.first < b.first;
}
ll __lcm(ll a, ll b) {
return (a / __gcd(a, b)) * b;
}
struct Point {
ld x, y;
Point() : x(0.0), y(0.0) {}
Point(ld _x, ld _y) : x(_x), y(_y){};
};
//-------------------------------------------- fast-io----------------------------------------
void HUTH() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
#ifndef ONLINE_JUDGE
freopen("input", "r", stdin);
freopen("output", "w", stdout);
#endif
}
//-----------------------------------------Operator overloads----------------------------------
template <typename T1, typename T2> // cin >> pair<T1, T2>
istream &operator>>(istream &istream, pair<T1, T2> &p) { return (istream >> p.first >> p.second); }
template <typename T> // cin >> vector<T>
istream &operator>>(istream &istream, vector<T> &v) {
for (auto &it : v)
cin >> it;
return istream;
}
template <typename T1, typename T2> // cout << pair<T1, T2>
ostream &operator<<(ostream &ostream, const pair<T1, T2> &p) { return (ostream << p.first << " " << p.second); }
template <typename T> // cout << vector<T>
ostream &operator<<(ostream &ostream, const vector<T> &c) {
ll n = sz(c);
FOR(i, 0, n) {
cout << c[i] << ((i == n - 1) ? "" : " ");
}
return ostream;
}
template <typename T> // cout << unordered_set<T>
ostream &operator<<(ostream &ostream, const unordered_set<T> &c) {
for (auto &it : c)
cout << it << " ";
return ostream;
}
template <typename T> // cout << ordered_set<T>
ostream &operator<<(ostream &ostream, const set<T> &c) {
for (auto &it : c)
cout << it << " ";
return ostream;
}
istream &operator>>(istream &istream, Point &v) {
cin >> v.x >> v.y;
return istream;
}
//-----------------------------------------Operator overloads----------------------------------
void solve(ll);
int main() {
HUTH();
ll T = 1ll;
// cin >> T;
FOR(i, 1, T + 1) {
solve(i);
}
}
const ll N = (1e5 + 5);
pair<int, int> seg_tree[4 * N];
pair<int, int> merge(pair<int, int> a, pair<int, int> b) {
if (a.first > b.first)
return a;
else if (a.first < b.first)
return b;
return make_pair(a.first, ((ll)a.second + b.second) % MOD);
}
pair<int, int> query(ll node, ll left, ll right, ll start, ll end) {
if (left > end || right < start)
return make_pair(-1, 0);
if (left <= start && right >= end) {
return seg_tree[node];
}
ll mid = start + (end - start) / 2;
return merge(query(2 * node, left, right, start, mid), query(2 * node + 1, left, right, mid + 1, end));
}
void update(ll node, ll index, ll start, ll end, pair<int, int> val) {
if (start == end) {
if (val.first == seg_tree[node].first) {
ll ans = seg_tree[node].second;
ans += val.second;
ans %= MOD;
seg_tree[node].second = ans;
return;
} else {
seg_tree[node] = val;
}
return;
}
ll mid = start + (end - start) / 2;
if (index <= mid) {
update(2 * node, index, start, mid, val);
} else {
update(2 * node + 1, index, mid + 1, end, val);
}
seg_tree[node] = merge(seg_tree[2 * node], seg_tree[2 * node + 1]);
}
void compress_coordinate(vector<int> &a, pmap<int, int> &mp) {
vector<int> sorted(a);
sort(all(sorted));
int idx = 1;
for (auto &e : sorted) {
if (!containsKey(mp, e)) {
mp[e] = idx++;
}
}
for (int i = 0; i < sz(a); i++) {
a[i] = mp[a[i]];
}
}
void solve(ll TC) {
int n;
cin >> n;
vector<int> vc(n);
cin >> vc;
FOR(i, 0, N) {
seg_tree[i] = make_pair(0, 0);
}
pmap<int, int> mp;
compress_coordinate(vc, mp);
int ansl = 0, ansn = 0;
for (int i = 0; i < n; i++) {
auto res = query(1, 0, vc[i] - 1, 0, N);
if (res.first + 1 > ansl) {
ansl = res.first + 1;
ansn = max(1, res.second);
} else if (res.first + 1 == ansl) {
ll nans = ansn;
nans += res.second;
nans %= MOD;
ansn = nans;
}
update(1, vc[i], 0, N, make_pair(res.first + 1, max(1, res.second)));
}
cout << ansl << " " << ansn << endl;
}
/*
itne me hi thakk gaya vro?
never compare your failure with other’s success.(which you are doing ri8 now)
read question
rethink your approach
dont put --> n <-- in every for loop
consider case = 0
Expert before 2023
*/
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlIDxleHQvcGJfZHMvYXNzb2NfY29udGFpbmVyLmhwcD4KI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+CiNpbmNsdWRlIDxpb3N0cmVhbT4KI2luY2x1ZGUgPHN0cmluZy5oPgovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1tYWNyb3MtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQojZGVmaW5lIGxsIGxvbmcgbG9uZyBpbnQKI2RlZmluZSB1bGwgdW5zaWduZWQgbG9uZyBsb25nIGludAojZGVmaW5lIGxkIGxvbmcgZG91YmxlCiNkZWZpbmUgY29sb3IoYXJyYXksIHZhbHVlKSBtZW1zZXQoYXJyYXksIHZhbHVlLCBzaXplb2YoYXJyYXkpKQojZGVmaW5lIGNvbG9yREQoYXJyYXksIHZhbHVlKSBmaWxsX24oKmFycmF5LCBzaXplb2YoYXJyYXkpIC8gc2l6ZW9mKCoqYXJyYXkpLCB2YWx1ZSk7CiNkZWZpbmUgc3ooeCkgKChsbCl4LnNpemUoKSkKI2RlZmluZSBjZXJyKHgpIGNvdXQgPDwgI3ggPDwgIiA9ICIgPDwgeCA8PCBlbmRsCiNkZWZpbmUgWUVTIGNvdXQgPDwgIllFU1xuIgojZGVmaW5lIE5PIGNvdXQgPDwgIk5PXG4iCiNkZWZpbmUgWWVzIGNvdXQgPDwgIlllc1xuIgojZGVmaW5lIE5vIGNvdXQgPDwgIk5vXG4iCiNkZWZpbmUgZW5kbCAiXG4iCiNkZWZpbmUgRk9SKGluZGV4LCBsb3dlciwgdXBwZXIpIGZvciAobGwgaW5kZXggPSBsb3dlcjsgaW5kZXggPCB1cHBlcjsgaW5kZXgrKykKI2RlZmluZSBGT1JEKGluZGV4LCB1cHBlciwgbG93ZXIpIGZvciAobGwgaW5kZXggPSB1cHBlcjsgaW5kZXggPiBsb3dlcjsgaW5kZXgtLSkKI2RlZmluZSBhbGwoeCkgeC5iZWdpbigpLCB4LmVuZCgpCiNkZWZpbmUgcmFsbCh4KSB4LnJiZWdpbigpLCB4LnJlbmQoKQojZGVmaW5lIGNvbnRhaW5zS2V5KG1hcCwga2V5KSAobWFwLmZpbmQoa2V5KSAhPSBtYXAuZW5kKCkpCiNkZWZpbmUgdW1hcCB1bm9yZGVyZWRfbWFwCiNkZWZpbmUgdXNldCB1bm9yZGVyZWRfc2V0CiNkZWZpbmUgQ0FTRSh4KSBjb3V0IDw8ICJDYXNlICIgPDwgeCA8PCAiOiIgPDwgZW5kbDsKI2RlZmluZSBwb3Bjb3VudCh4KSBfX2J1aWx0aW5fcG9wY291bnQoeCkKI2RlZmluZSBwbGwgcGFpcjxsbCwgbGw+CmNvbnN0IGxsIE1PRCA9IDFlOSArIDc7CmNvbnN0IGxsIEFfTU9EID0gOTk4MjQ0MzUzOwpjb25zdCBsZCBFUFMgPSAxZS03Owpjb25zdCBsZCBQSSA9IGFjb3MoLTEuMCk7CmNvbnN0IGxsIElORiA9IDFlMTg7CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVBvbGljeSBiYXNlZCBkYXRhIHN0cnVjdHVyZXMtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7CnRlbXBsYXRlIDxjbGFzcyBUPgp1c2luZyBvc2V0ID0gdHJlZTxULCBudWxsX3R5cGUsIGxlc3NfZXF1YWw8VD4sIHJiX3RyZWVfdGFnLCB0cmVlX29yZGVyX3N0YXRpc3RpY3Nfbm9kZV91cGRhdGU+OwovKi0tLS0tLS0tLS0tY3VzdG9tLWhhc2gtLS0tLS0tLS0tLS0qLwpzdHJ1Y3QgY3VzdG9tX2hhc2ggewogICAgc3RhdGljIHVpbnQ2NF90IHNwbGl0bWl4NjQodWludDY0X3QgeCkgewogICAgICAgIHggKz0gMHg5ZTM3NzliOTdmNGE3YzE1OwogICAgICAgIHggPSAoeCBeICh4ID4+IDMwKSkgKiAweGJmNTg0NzZkMWNlNGU1Yjk7CiAgICAgICAgeCA9ICh4IF4gKHggPj4gMjcpKSAqIDB4OTRkMDQ5YmIxMzMxMTFlYjsKICAgICAgICByZXR1cm4geCBeICh4ID4+IDMxKTsKICAgIH0KCiAgICBzaXplX3Qgb3BlcmF0b3IoKSh1aW50NjRfdCB4KSBjb25zdCB7CiAgICAgICAgc3RhdGljIGNvbnN0IHVpbnQ2NF90IEZJWEVEX1JBTkRPTSA9IGNocm9ubzo6c3RlYWR5X2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKTsKICAgICAgICByZXR1cm4gc3BsaXRtaXg2NCh4ICsgRklYRURfUkFORE9NKTsKICAgIH0KfTsKdGVtcGxhdGUgPGNsYXNzIFQxLCBjbGFzcyBUMj4KdXNpbmcgcG1hcCA9IGdwX2hhc2hfdGFibGU8VDEsIFQyLCBjdXN0b21faGFzaD47CnRlbXBsYXRlIDxjbGFzcyBUPgp1c2luZyBwc2V0ID0gdW5vcmRlcmVkX3NldDxULCBjdXN0b21faGFzaD47Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLUdyYXBoIE1vdmVzLS0tLS0tLS0tLS0tLS0tLSovCmNvbnN0IGxsIGR4W10gPSB7KzAsICswLCArMSwgLTEsIC0xLCArMSwgLTEsICsxfTsgLy8gS2luZ3MgTW92ZSBMIFIgRCBVCmNvbnN0IGxsIGR5W10gPSB7LTEsICsxLCArMCwgKzAsICsxLCArMSwgLTEsIC0xfTsgLy8gS2luZ3MgTW92ZQovLyBjb25zdCBsbCBkeFtdID0gey0yLCAtMiwgLTEsIC0xLCAxLCAxLCAyLCAyfTsgLy8gS25pZ2h0cyBNb3ZlCi8vIGNvbnN0IGxsIGR5W10gPSB7LTEsIDEsIC0yLCAyLCAtMiwgMiwgLTEsIDF9OyAvLyBLbmlnaHRzIE1vdmUKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwoKYm9vbCBpc0JpdFNldChsbCBudW1iZXIsIGxsIGJpdCkgewogICAgcmV0dXJuIChudW1iZXIgJiAoMWxsIDw8IGJpdCkpICE9IDA7Cn0KCmxsIGludmVyc2VCaXQobGwgbnVtYmVyLCBsbCBiaXQpIHsKICAgIHJldHVybiAobnVtYmVyIF4gKDFsbCA8PCBiaXQpKTsKfQoKbGwgY2VpbF9kaXYobGwgYSwgbGwgYikgewogICAgcmV0dXJuIGEgLyBiICsgKChhIF4gYikgPiAwICYmIGEgJSBiICE9IDApOwp9Cgp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4KVCBzcXVhcmUoVCB2KSB7CiAgICByZXR1cm4gdiAqIHY7Cn0KYm9vbCBjb21wX3NlY29uZChwYWlyPGxsLCBsbD4gJmEsIHBhaXI8bGwsIGxsPiAmYikgewogICAgaWYgKGEuc2Vjb25kICE9IGIuc2Vjb25kKQogICAgICAgIHJldHVybiBhLnNlY29uZCA8IGIuc2Vjb25kOwogICAgcmV0dXJuIGEuZmlyc3QgPCBiLmZpcnN0Owp9CmJvb2wgY29tcF9maXJzdF9yZXZlcnNlKHBhaXI8bGwsIGxsPiAmYSwgcGFpcjxsbCwgbGw+ICZiKSB7CiAgICBpZiAoYS5maXJzdCAhPSBiLmZpcnN0KQogICAgICAgIHJldHVybiBhLmZpcnN0IDwgYi5maXJzdDsKICAgIHJldHVybiBhLnNlY29uZCA+IGIuc2Vjb25kOwp9CmJvb2wgY29tcF9zZWNvbmRfcmV2ZXJzZShwYWlyPGxsLCBsbD4gJmEsIHBhaXI8bGwsIGxsPiAmYikgewogICAgaWYgKGEuc2Vjb25kICE9IGIuc2Vjb25kKQogICAgICAgIHJldHVybiBhLnNlY29uZCA+IGIuc2Vjb25kOwogICAgcmV0dXJuIGEuZmlyc3QgPCBiLmZpcnN0Owp9CgpsbCBfX2xjbShsbCBhLCBsbCBiKSB7CiAgICByZXR1cm4gKGEgLyBfX2djZChhLCBiKSkgKiBiOwp9CgpzdHJ1Y3QgUG9pbnQgewogICAgbGQgeCwgeTsKICAgIFBvaW50KCkgOiB4KDAuMCksIHkoMC4wKSB7fQogICAgUG9pbnQobGQgX3gsIGxkIF95KSA6IHgoX3gpLCB5KF95KXt9Owp9OwoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSBmYXN0LWlvLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdm9pZCBIVVRIKCkgewogICAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKE5VTEwpOwogICAgY291dC50aWUoTlVMTCk7CiNpZm5kZWYgT05MSU5FX0pVREdFCiAgICBmcmVvcGVuKCJpbnB1dCIsICJyIiwgc3RkaW4pOwogICAgZnJlb3Blbigib3V0cHV0IiwgInciLCBzdGRvdXQpOwojZW5kaWYKfQoKLy8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLU9wZXJhdG9yIG92ZXJsb2Fkcy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KdGVtcGxhdGUgPHR5cGVuYW1lIFQxLCB0eXBlbmFtZSBUMj4gLy8gY2luID4+IHBhaXI8VDEsIFQyPgppc3RyZWFtICZvcGVyYXRvcj4+KGlzdHJlYW0gJmlzdHJlYW0sIHBhaXI8VDEsIFQyPiAmcCkgeyByZXR1cm4gKGlzdHJlYW0gPj4gcC5maXJzdCA+PiBwLnNlY29uZCk7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IC8vIGNpbiA+PiB2ZWN0b3I8VD4KaXN0cmVhbSAmb3BlcmF0b3I+Pihpc3RyZWFtICZpc3RyZWFtLCB2ZWN0b3I8VD4gJnYpIHsKICAgIGZvciAoYXV0byAmaXQgOiB2KQogICAgICAgIGNpbiA+PiBpdDsKICAgIHJldHVybiBpc3RyZWFtOwp9CnRlbXBsYXRlIDx0eXBlbmFtZSBUMSwgdHlwZW5hbWUgVDI+IC8vIGNvdXQgPDwgcGFpcjxUMSwgVDI+Cm9zdHJlYW0gJm9wZXJhdG9yPDwob3N0cmVhbSAmb3N0cmVhbSwgY29uc3QgcGFpcjxUMSwgVDI+ICZwKSB7IHJldHVybiAob3N0cmVhbSA8PCBwLmZpcnN0IDw8ICIgIiA8PCBwLnNlY29uZCk7IH0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IC8vIGNvdXQgPDwgdmVjdG9yPFQ+Cm9zdHJlYW0gJm9wZXJhdG9yPDwob3N0cmVhbSAmb3N0cmVhbSwgY29uc3QgdmVjdG9yPFQ+ICZjKSB7CiAgICBsbCBuID0gc3ooYyk7CiAgICBGT1IoaSwgMCwgbikgewogICAgICAgIGNvdXQgPDwgY1tpXSA8PCAoKGkgPT0gbiAtIDEpID8gIiIgOiAiICIpOwogICAgfQogICAgcmV0dXJuIG9zdHJlYW07Cn0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IC8vIGNvdXQgPDwgdW5vcmRlcmVkX3NldDxUPgpvc3RyZWFtICZvcGVyYXRvcjw8KG9zdHJlYW0gJm9zdHJlYW0sIGNvbnN0IHVub3JkZXJlZF9zZXQ8VD4gJmMpIHsKICAgIGZvciAoYXV0byAmaXQgOiBjKQogICAgICAgIGNvdXQgPDwgaXQgPDwgIiAiOwogICAgcmV0dXJuIG9zdHJlYW07Cn0KdGVtcGxhdGUgPHR5cGVuYW1lIFQ+IC8vIGNvdXQgPDwgb3JkZXJlZF9zZXQ8VD4Kb3N0cmVhbSAmb3BlcmF0b3I8PChvc3RyZWFtICZvc3RyZWFtLCBjb25zdCBzZXQ8VD4gJmMpIHsKICAgIGZvciAoYXV0byAmaXQgOiBjKQogICAgICAgIGNvdXQgPDwgaXQgPDwgIiAiOwogICAgcmV0dXJuIG9zdHJlYW07Cn0KaXN0cmVhbSAmb3BlcmF0b3I+Pihpc3RyZWFtICZpc3RyZWFtLCBQb2ludCAmdikgewogICAgY2luID4+IHYueCA+PiB2Lnk7CiAgICByZXR1cm4gaXN0cmVhbTsKfQovLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tT3BlcmF0b3Igb3ZlcmxvYWRzLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQp2b2lkIHNvbHZlKGxsKTsKCmludCBtYWluKCkgewoKICAgIEhVVEgoKTsKCiAgICBsbCBUID0gMWxsOwogICAgLy8gY2luID4+IFQ7CiAgICBGT1IoaSwgMSwgVCArIDEpIHsKICAgICAgICBzb2x2ZShpKTsKICAgIH0KfQpjb25zdCBsbCBOID0gKDFlNSArIDUpOwpwYWlyPGludCwgaW50PiBzZWdfdHJlZVs0ICogTl07CnBhaXI8aW50LCBpbnQ+IG1lcmdlKHBhaXI8aW50LCBpbnQ+IGEsIHBhaXI8aW50LCBpbnQ+IGIpIHsKICAgIGlmIChhLmZpcnN0ID4gYi5maXJzdCkKICAgICAgICByZXR1cm4gYTsKICAgIGVsc2UgaWYgKGEuZmlyc3QgPCBiLmZpcnN0KQogICAgICAgIHJldHVybiBiOwogICAgcmV0dXJuIG1ha2VfcGFpcihhLmZpcnN0LCAoKGxsKWEuc2Vjb25kICsgYi5zZWNvbmQpICUgTU9EKTsKfQpwYWlyPGludCwgaW50PiBxdWVyeShsbCBub2RlLCBsbCBsZWZ0LCBsbCByaWdodCwgbGwgc3RhcnQsIGxsIGVuZCkgewogICAgaWYgKGxlZnQgPiBlbmQgfHwgcmlnaHQgPCBzdGFydCkKICAgICAgICByZXR1cm4gbWFrZV9wYWlyKC0xLCAwKTsKICAgIGlmIChsZWZ0IDw9IHN0YXJ0ICYmIHJpZ2h0ID49IGVuZCkgewogICAgICAgIHJldHVybiBzZWdfdHJlZVtub2RlXTsKICAgIH0KICAgIGxsIG1pZCA9IHN0YXJ0ICsgKGVuZCAtIHN0YXJ0KSAvIDI7CiAgICByZXR1cm4gbWVyZ2UocXVlcnkoMiAqIG5vZGUsIGxlZnQsIHJpZ2h0LCBzdGFydCwgbWlkKSwgcXVlcnkoMiAqIG5vZGUgKyAxLCBsZWZ0LCByaWdodCwgbWlkICsgMSwgZW5kKSk7Cn0Kdm9pZCB1cGRhdGUobGwgbm9kZSwgbGwgaW5kZXgsIGxsIHN0YXJ0LCBsbCBlbmQsIHBhaXI8aW50LCBpbnQ+IHZhbCkgewogICAgaWYgKHN0YXJ0ID09IGVuZCkgewogICAgICAgIGlmICh2YWwuZmlyc3QgPT0gc2VnX3RyZWVbbm9kZV0uZmlyc3QpIHsKICAgICAgICAgICAgbGwgYW5zID0gc2VnX3RyZWVbbm9kZV0uc2Vjb25kOwogICAgICAgICAgICBhbnMgKz0gdmFsLnNlY29uZDsKICAgICAgICAgICAgYW5zICU9IE1PRDsKICAgICAgICAgICAgc2VnX3RyZWVbbm9kZV0uc2Vjb25kID0gYW5zOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgc2VnX3RyZWVbbm9kZV0gPSB2YWw7CiAgICAgICAgfQogICAgICAgIHJldHVybjsKICAgIH0KICAgIGxsIG1pZCA9IHN0YXJ0ICsgKGVuZCAtIHN0YXJ0KSAvIDI7CiAgICBpZiAoaW5kZXggPD0gbWlkKSB7CiAgICAgICAgdXBkYXRlKDIgKiBub2RlLCBpbmRleCwgc3RhcnQsIG1pZCwgdmFsKTsKICAgIH0gZWxzZSB7CiAgICAgICAgdXBkYXRlKDIgKiBub2RlICsgMSwgaW5kZXgsIG1pZCArIDEsIGVuZCwgdmFsKTsKICAgIH0KICAgIHNlZ190cmVlW25vZGVdID0gbWVyZ2Uoc2VnX3RyZWVbMiAqIG5vZGVdLCBzZWdfdHJlZVsyICogbm9kZSArIDFdKTsKfQp2b2lkIGNvbXByZXNzX2Nvb3JkaW5hdGUodmVjdG9yPGludD4gJmEsIHBtYXA8aW50LCBpbnQ+ICZtcCkgewogICAgdmVjdG9yPGludD4gc29ydGVkKGEpOwogICAgc29ydChhbGwoc29ydGVkKSk7CiAgICBpbnQgaWR4ID0gMTsKICAgIGZvciAoYXV0byAmZSA6IHNvcnRlZCkgewogICAgICAgIGlmICghY29udGFpbnNLZXkobXAsIGUpKSB7CiAgICAgICAgICAgIG1wW2VdID0gaWR4Kys7CiAgICAgICAgfQogICAgfQogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBzeihhKTsgaSsrKSB7CiAgICAgICAgYVtpXSA9IG1wW2FbaV1dOwogICAgfQp9CnZvaWQgc29sdmUobGwgVEMpIHsKICAgIGludCBuOwogICAgY2luID4+IG47CiAgICB2ZWN0b3I8aW50PiB2YyhuKTsKICAgIGNpbiA+PiB2YzsKICAgIEZPUihpLCAwLCBOKSB7CiAgICAgICAgc2VnX3RyZWVbaV0gPSBtYWtlX3BhaXIoMCwgMCk7CiAgICB9CiAgICBwbWFwPGludCwgaW50PiBtcDsKICAgIGNvbXByZXNzX2Nvb3JkaW5hdGUodmMsIG1wKTsKICAgIGludCBhbnNsID0gMCwgYW5zbiA9IDA7CiAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgewogICAgICAgIGF1dG8gcmVzID0gcXVlcnkoMSwgMCwgdmNbaV0gLSAxLCAwLCBOKTsKICAgICAgICBpZiAocmVzLmZpcnN0ICsgMSA+IGFuc2wpIHsKICAgICAgICAgICAgYW5zbCA9IHJlcy5maXJzdCArIDE7CiAgICAgICAgICAgIGFuc24gPSBtYXgoMSwgcmVzLnNlY29uZCk7CiAgICAgICAgfSBlbHNlIGlmIChyZXMuZmlyc3QgKyAxID09IGFuc2wpIHsKICAgICAgICAgICAgbGwgbmFucyA9IGFuc247CiAgICAgICAgICAgIG5hbnMgKz0gcmVzLnNlY29uZDsKICAgICAgICAgICAgbmFucyAlPSBNT0Q7CiAgICAgICAgICAgIGFuc24gPSBuYW5zOwogICAgICAgIH0KICAgICAgICB1cGRhdGUoMSwgdmNbaV0sIDAsIE4sIG1ha2VfcGFpcihyZXMuZmlyc3QgKyAxLCBtYXgoMSwgcmVzLnNlY29uZCkpKTsKICAgIH0KICAgIGNvdXQgPDwgYW5zbCA8PCAiICIgPDwgYW5zbiA8PCBlbmRsOwp9CgovKgogaXRuZSBtZSBoaSB0aGFrayBnYXlhIHZybz8KIG5ldmVyIGNvbXBhcmUgeW91ciBmYWlsdXJlIHdpdGggb3RoZXLigJlzIHN1Y2Nlc3MuKHdoaWNoIHlvdSBhcmUgZG9pbmcgcmk4IG5vdykKCiByZWFkIHF1ZXN0aW9uCiByZXRoaW5rIHlvdXIgYXBwcm9hY2gKIGRvbnQgcHV0IC0tPiBuIDwtLSBpbiBldmVyeSBmb3IgbG9vcAogY29uc2lkZXIgY2FzZSA9IDAKCiBFeHBlcnQgYmVmb3JlIDIwMjMKKi8=