#include<climits>
#include<cstdio>
#include<memory>
#include<random>
#include<set>
#include<tuple>
using namespace std;
using ll = long long;
constexpr ll P = 1000000007;
// R = Z_P[x] / (x^3-x^2-x-1)
struct R{
// ax^2 + bx + c
ll a, b, c;
R() noexcept = default;
constexpr R(ll a, ll b, ll c) noexcept: a((a%P+P)%P), b((b%P+P)%P), c((c%P+P)%P){}
constexpr R operator *(R const &g) noexcept{
ll a4 = a*g.a, a3 = a*g.b+b*g.a, a2 = a*g.c+b*g.b+c*g.a, a1 = b*g.c+c*g.b, a0 = c*g.c;
return {2*a4+a3+a2, 2*a4+a3+a1, a4+a3+a0};
}
constexpr R &operator *=(R const &g) noexcept{
return *this = *this * g;
}
};
tuple<ll, ll, ll> f(long n) noexcept{
R xp(0, 1, 0), xn(0, 0, 1);
for(; n; n>>=1){
if(n&1) xn *= xp;
xp *= xp;
}
return {xn.a, (xn.a+xn.b)%P, (2*xn.a+xn.b+xn.c)%P};
}
tuple<ll, ll, ll, ll> loli(ll ll1, ll lr1, ll rl1, ll rr1, ll ll2, ll lr2, ll rl2, ll rr2) noexcept{
return {
(ll1*ll2+lr1*ll2+lr1*rl2)%P,
(ll1*lr2+lr1*lr2+lr1*rr2)%P,
(rl1*ll2+rr1*ll2+rr1*rl2)%P,
(rl1*lr2+rr1*lr2+rr1*rr2)%P
};
}
struct Node{
static mt19937_64 rand;
long key;
decltype(rand()) fix = rand();
ll nll, nlr, nrl, nrr;
ll subtll, subtlr, subtrl, subtrr;
shared_ptr<Node> lch, rch;
Node() noexcept = default;
Node(long key, ll nll, ll nlr, ll nrl, ll nrr) noexcept: key(key), nll(nll), nlr(nlr), nrl(nrl), nrr(nrr), subtll(nll), subtlr(nlr), subtrl(nrl), subtrr(nrr){}
void maintain() noexcept{
subtll = nll, subtlr = nlr, subtrl = nrl, subtrr = nrr;
if(lch){
tie(subtll, subtlr, subtrl, subtrr) = loli(lch->subtll, lch->subtlr, lch->subtrl, lch->subtrr, subtll, subtlr, subtrl, subtrr);
}
if(rch){
tie(subtll, subtlr, subtrl, subtrr) = loli(subtll, subtlr, subtrl, subtrr, rch->subtll, rch->subtlr, rch->subtrl, rch->subtrr);
}
}
};
mt19937_64 Node::rand(random_device{}());
using Subt = shared_ptr<Node>;
Subt merge(Subt p, Subt q) noexcept{
if(!p) return q;
if(!q) return p;
if(p->fix < q->fix) swap(p, q);
if(q->key < p->key) p->lch = merge(p->lch, q);
else p->rch = merge(p->rch, q);
p->maintain();
return p;
}
pair<Subt, Subt> split(Subt p, long th) noexcept{
if(!p) return {nullptr, nullptr};
if(th >= p->key){
Subt q, r;
tie(q, r) = split(p->rch, th);
p->rch = q;
p->maintain();
return {p, r};
}
Subt q, r;
tie(q, r) = split(p->lch, th);
p->lch = r;
p->maintain();
return {q, p};
}
void update(Subt p, long key, ll nll, ll nlr, ll nrl, ll nrr) noexcept{
if(!p) return;
if(key == p->key){
p->nll = nll, p->nlr = nlr, p->nrl = nrl, p->nrr = nrr;
}else if(key < p->key){
update(p->lch, key, nll, nlr, nrl, nrr);
}else{
update(p->rch, key, nll, nlr, nrl, nrr);
}
p->maintain();
}
void increment_key(Subt p, long key, bool dk) noexcept{
if(!p) return;
if(key == p->key){
if(dk){
++p->key;
p->nll = p->nlr;
p->nrl = p->nrr;
}
p->nlr = p->nrr = 0;
}else if(key < p->key){
increment_key(p->lch, key, dk);
}else{
increment_key(p->rch, key, dk);
}
p->maintain();
}
tuple<long, ll, ll, ll, ll> query(Subt p, long th) noexcept{
if(!p) return {-1, 0, 0, 0, 0};
if(th < p->key){
return query(p->lch, th);
}
ll a=p->nll, b=p->nlr, c=p->nrl, d=p->nrr;
if(p->lch){
tie(a, b, c, d) = loli(p->lch->subtll, p->lch->subtlr, p->lch->subtrl, p->lch->subtrr, a, b, c, d);
}
long key = p->key;
auto t = query(p->rch, th);
if(get<0>(t) == -1){
return {key, a, b, c, d};
}
tie(a, b, c, d) = loli(a, b, c, d, get<1>(t), get<2>(t), get<3>(t), get<4>(t));
return {get<0>(t), a, b, c, d};
}
int main(){
long q, bound=LONG_MAX;
scanf("%*d%ld", &q);
Subt bst;
set<long> black;
while(q--){
long op, k;
scanf("%ld%ld", &op, &k);
if(op == 0){
if(k>bound || black.find(k)!=black.end()){
puts("0"); continue;
}
if(!bst || k<*black.begin()){
printf("%lld\n", get<2>(f(k)));
continue;
}
auto t = query(bst, k);
auto u = f(k-get<0>(t)-1);
ll ans = (get<3>(t)*get<2>(u)+get<4>(t)*get<2>(u)+get<4>(t)*get<1>(u))%P;
printf("%lld\n", ans);
}else{
auto p = black.insert(k);
if(!p.second) continue;
if(k > bound) continue;
auto it = p.first;
if(it!=black.begin() && *prev(it)==k-1){
if(prev(it)!=black.begin() && *prev(it, 2)==k-2){
bound = k-3;
bst = split(bst, bound).first;
continue;
}
if(next(it)!=black.end() && *next(it)==k+1){
bound = k-2;
bst = split(bst, bound).first;
continue;
}
if(++it != black.end()){
auto t = f(*it-k-2);
if(next(it)!=black.end() && *next(it)==*it+1){
update(bst, *it+1, get<2>(t), 0, get<1>(t), 0);
}else{
update(bst, *it, get<1>(t), get<2>(t), get<0>(t), get<1>(t));
}
}
increment_key(bst, k-1, true);
}else if(next(it)!=black.end() && *next(it)==k+1){
if(next(it, 2)!=black.end() && *next(it, 2)==k+2){
bound = k-1;
bst = split(bst, bound).first;
continue;
}
increment_key(bst, k+1, false);
}else{
if(++it != black.end()){
auto t = f(*it-k-2);
if(next(it)!=black.end() && *next(it)==*it+1){
update(bst, *it+1, get<2>(t), 0, get<1>(t), 0);
}else{
update(bst, *it, get<1>(t), get<2>(t), get<0>(t), get<1>(t));
}
}
if(--it == black.begin()){
auto t = f(k-1);
Subt p, q;
tie(p, q) = split(bst, k);
bst = merge(merge(p, make_shared<Node>(k, 0, 0, get<1>(t), get<2>(t))), q);
}else{
auto t = f(k-*prev(it)-2);
Subt p, q;
tie(p, q) = split(bst, k);
bst = merge(merge(p, make_shared<Node>(k, get<1>(t), get<2>(t), get<0>(t), get<1>(t))), q);
}
}
}
}
}
I2luY2x1ZGU8Y2xpbWl0cz4KI2luY2x1ZGU8Y3N0ZGlvPgojaW5jbHVkZTxtZW1vcnk+CiNpbmNsdWRlPHJhbmRvbT4KI2luY2x1ZGU8c2V0PgojaW5jbHVkZTx0dXBsZT4KdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbGwgPSBsb25nIGxvbmc7CmNvbnN0ZXhwciBsbCBQID0gMTAwMDAwMDAwNzsKCi8vIFIgPSBaX1BbeF0gLyAoeF4zLXheMi14LTEpCnN0cnVjdCBSewogICAgLy8gYXheMiArIGJ4ICsgYwogICAgbGwgYSwgYiwgYzsKICAgIFIoKSBub2V4Y2VwdCA9IGRlZmF1bHQ7CiAgICBjb25zdGV4cHIgUihsbCBhLCBsbCBiLCBsbCBjKSBub2V4Y2VwdDogYSgoYSVQK1ApJVApLCBiKChiJVArUCklUCksIGMoKGMlUCtQKSVQKXt9CiAgICBjb25zdGV4cHIgUiBvcGVyYXRvciAqKFIgY29uc3QgJmcpIG5vZXhjZXB0ewogICAgICAgIGxsIGE0ID0gYSpnLmEsIGEzID0gYSpnLmIrYipnLmEsIGEyID0gYSpnLmMrYipnLmIrYypnLmEsIGExID0gYipnLmMrYypnLmIsIGEwID0gYypnLmM7CiAgICAgICAgcmV0dXJuIHsyKmE0K2EzK2EyLCAyKmE0K2EzK2ExLCBhNCthMythMH07CiAgICB9CiAgICBjb25zdGV4cHIgUiAmb3BlcmF0b3IgKj0oUiBjb25zdCAmZykgbm9leGNlcHR7CiAgICAgICAgcmV0dXJuICp0aGlzID0gKnRoaXMgKiBnOwogICAgfQp9OwoKdHVwbGU8bGwsIGxsLCBsbD4gZihsb25nIG4pIG5vZXhjZXB0ewogICAgUiB4cCgwLCAxLCAwKSwgeG4oMCwgMCwgMSk7CiAgICBmb3IoOyBuOyBuPj49MSl7CiAgICAgICAgaWYobiYxKSB4biAqPSB4cDsKICAgICAgICB4cCAqPSB4cDsKICAgIH0KICAgIHJldHVybiB7eG4uYSwgKHhuLmEreG4uYiklUCwgKDIqeG4uYSt4bi5iK3huLmMpJVB9Owp9Cgp0dXBsZTxsbCwgbGwsIGxsLCBsbD4gbG9saShsbCBsbDEsIGxsIGxyMSwgbGwgcmwxLCBsbCBycjEsIGxsIGxsMiwgbGwgbHIyLCBsbCBybDIsIGxsIHJyMikgbm9leGNlcHR7CiAgICByZXR1cm4gewogICAgICAgIChsbDEqbGwyK2xyMSpsbDIrbHIxKnJsMiklUCwKICAgICAgICAobGwxKmxyMitscjEqbHIyK2xyMSpycjIpJVAsCiAgICAgICAgKHJsMSpsbDIrcnIxKmxsMitycjEqcmwyKSVQLAogICAgICAgIChybDEqbHIyK3JyMSpscjIrcnIxKnJyMiklUAogICAgfTsKfQoKc3RydWN0IE5vZGV7CiAgICBzdGF0aWMgbXQxOTkzN182NCByYW5kOwogICAgbG9uZyBrZXk7CiAgICBkZWNsdHlwZShyYW5kKCkpIGZpeCA9IHJhbmQoKTsKICAgIGxsIG5sbCwgbmxyLCBucmwsIG5ycjsKICAgIGxsIHN1YnRsbCwgc3VidGxyLCBzdWJ0cmwsIHN1YnRycjsKICAgIHNoYXJlZF9wdHI8Tm9kZT4gbGNoLCByY2g7CiAgICBOb2RlKCkgbm9leGNlcHQgPSBkZWZhdWx0OwogICAgTm9kZShsb25nIGtleSwgbGwgbmxsLCBsbCBubHIsIGxsIG5ybCwgbGwgbnJyKSBub2V4Y2VwdDoga2V5KGtleSksIG5sbChubGwpLCBubHIobmxyKSwgbnJsKG5ybCksIG5ycihucnIpLCBzdWJ0bGwobmxsKSwgc3VidGxyKG5sciksIHN1YnRybChucmwpLCBzdWJ0cnIobnJyKXt9CiAgICB2b2lkIG1haW50YWluKCkgbm9leGNlcHR7CiAgICAgICAgc3VidGxsID0gbmxsLCBzdWJ0bHIgPSBubHIsIHN1YnRybCA9IG5ybCwgc3VidHJyID0gbnJyOwogICAgICAgIGlmKGxjaCl7CiAgICAgICAgICAgIHRpZShzdWJ0bGwsIHN1YnRsciwgc3VidHJsLCBzdWJ0cnIpID0gbG9saShsY2gtPnN1YnRsbCwgbGNoLT5zdWJ0bHIsIGxjaC0+c3VidHJsLCBsY2gtPnN1YnRyciwgc3VidGxsLCBzdWJ0bHIsIHN1YnRybCwgc3VidHJyKTsKICAgICAgICB9CiAgICAgICAgaWYocmNoKXsKICAgICAgICAgICAgdGllKHN1YnRsbCwgc3VidGxyLCBzdWJ0cmwsIHN1YnRycikgPSBsb2xpKHN1YnRsbCwgc3VidGxyLCBzdWJ0cmwsIHN1YnRyciwgcmNoLT5zdWJ0bGwsIHJjaC0+c3VidGxyLCByY2gtPnN1YnRybCwgcmNoLT5zdWJ0cnIpOwogICAgICAgIH0KICAgIH0KfTsKbXQxOTkzN182NCBOb2RlOjpyYW5kKHJhbmRvbV9kZXZpY2V7fSgpKTsKdXNpbmcgU3VidCA9IHNoYXJlZF9wdHI8Tm9kZT47ClN1YnQgbWVyZ2UoU3VidCBwLCBTdWJ0IHEpIG5vZXhjZXB0ewogICAgaWYoIXApIHJldHVybiBxOwogICAgaWYoIXEpIHJldHVybiBwOwogICAgaWYocC0+Zml4IDwgcS0+Zml4KSBzd2FwKHAsIHEpOwogICAgaWYocS0+a2V5IDwgcC0+a2V5KSBwLT5sY2ggPSBtZXJnZShwLT5sY2gsIHEpOwogICAgZWxzZSBwLT5yY2ggPSBtZXJnZShwLT5yY2gsIHEpOwogICAgcC0+bWFpbnRhaW4oKTsKICAgIHJldHVybiBwOwp9CnBhaXI8U3VidCwgU3VidD4gc3BsaXQoU3VidCBwLCBsb25nIHRoKSBub2V4Y2VwdHsKICAgIGlmKCFwKSByZXR1cm4ge251bGxwdHIsIG51bGxwdHJ9OwogICAgaWYodGggPj0gcC0+a2V5KXsKICAgICAgICBTdWJ0IHEsIHI7CiAgICAgICAgdGllKHEsIHIpID0gc3BsaXQocC0+cmNoLCB0aCk7CiAgICAgICAgcC0+cmNoID0gcTsKICAgICAgICBwLT5tYWludGFpbigpOwogICAgICAgIHJldHVybiB7cCwgcn07CiAgICB9CiAgICBTdWJ0IHEsIHI7CiAgICB0aWUocSwgcikgPSBzcGxpdChwLT5sY2gsIHRoKTsKICAgIHAtPmxjaCA9IHI7CiAgICBwLT5tYWludGFpbigpOwogICAgcmV0dXJuIHtxLCBwfTsKfQp2b2lkIHVwZGF0ZShTdWJ0IHAsIGxvbmcga2V5LCBsbCBubGwsIGxsIG5sciwgbGwgbnJsLCBsbCBucnIpIG5vZXhjZXB0ewogICAgaWYoIXApIHJldHVybjsKICAgIGlmKGtleSA9PSBwLT5rZXkpewogICAgICAgIHAtPm5sbCA9IG5sbCwgcC0+bmxyID0gbmxyLCBwLT5ucmwgPSBucmwsIHAtPm5yciA9IG5ycjsKICAgIH1lbHNlIGlmKGtleSA8IHAtPmtleSl7CiAgICAgICAgdXBkYXRlKHAtPmxjaCwga2V5LCBubGwsIG5sciwgbnJsLCBucnIpOwogICAgfWVsc2V7CiAgICAgICAgdXBkYXRlKHAtPnJjaCwga2V5LCBubGwsIG5sciwgbnJsLCBucnIpOwogICAgfQogICAgcC0+bWFpbnRhaW4oKTsKfQp2b2lkIGluY3JlbWVudF9rZXkoU3VidCBwLCBsb25nIGtleSwgYm9vbCBkaykgbm9leGNlcHR7CiAgICBpZighcCkgcmV0dXJuOwogICAgaWYoa2V5ID09IHAtPmtleSl7CiAgICAgICAgaWYoZGspewogICAgICAgICAgICArK3AtPmtleTsKICAgICAgICAgICAgcC0+bmxsID0gcC0+bmxyOwogICAgICAgICAgICBwLT5ucmwgPSBwLT5ucnI7CiAgICAgICAgfQogICAgICAgIHAtPm5sciA9IHAtPm5yciA9IDA7CiAgICB9ZWxzZSBpZihrZXkgPCBwLT5rZXkpewogICAgICAgIGluY3JlbWVudF9rZXkocC0+bGNoLCBrZXksIGRrKTsKICAgIH1lbHNlewogICAgICAgIGluY3JlbWVudF9rZXkocC0+cmNoLCBrZXksIGRrKTsKICAgIH0KICAgIHAtPm1haW50YWluKCk7Cn0KdHVwbGU8bG9uZywgbGwsIGxsLCBsbCwgbGw+IHF1ZXJ5KFN1YnQgcCwgbG9uZyB0aCkgbm9leGNlcHR7CiAgICBpZighcCkgcmV0dXJuIHstMSwgMCwgMCwgMCwgMH07CiAgICBpZih0aCA8IHAtPmtleSl7CiAgICAgICAgcmV0dXJuIHF1ZXJ5KHAtPmxjaCwgdGgpOwogICAgfQogICAgbGwgYT1wLT5ubGwsIGI9cC0+bmxyLCBjPXAtPm5ybCwgZD1wLT5ucnI7CiAgICBpZihwLT5sY2gpewogICAgICAgIHRpZShhLCBiLCBjLCBkKSA9IGxvbGkocC0+bGNoLT5zdWJ0bGwsIHAtPmxjaC0+c3VidGxyLCBwLT5sY2gtPnN1YnRybCwgcC0+bGNoLT5zdWJ0cnIsIGEsIGIsIGMsIGQpOwogICAgfQogICAgbG9uZyBrZXkgPSBwLT5rZXk7CiAgICBhdXRvIHQgPSBxdWVyeShwLT5yY2gsIHRoKTsKICAgIGlmKGdldDwwPih0KSA9PSAtMSl7CiAgICAgICAgcmV0dXJuIHtrZXksIGEsIGIsIGMsIGR9OwogICAgfQogICAgdGllKGEsIGIsIGMsIGQpID0gbG9saShhLCBiLCBjLCBkLCBnZXQ8MT4odCksIGdldDwyPih0KSwgZ2V0PDM+KHQpLCBnZXQ8ND4odCkpOwogICAgcmV0dXJuIHtnZXQ8MD4odCksIGEsIGIsIGMsIGR9Owp9CgppbnQgbWFpbigpewogICAgbG9uZyBxLCBib3VuZD1MT05HX01BWDsKICAgIHNjYW5mKCIlKmQlbGQiLCAmcSk7CiAgICBTdWJ0IGJzdDsKICAgIHNldDxsb25nPiBibGFjazsKICAgIHdoaWxlKHEtLSl7CiAgICAgICAgbG9uZyBvcCwgazsKICAgICAgICBzY2FuZigiJWxkJWxkIiwgJm9wLCAmayk7CiAgICAgICAgaWYob3AgPT0gMCl7CiAgICAgICAgICAgIGlmKGs+Ym91bmQgfHwgYmxhY2suZmluZChrKSE9YmxhY2suZW5kKCkpewogICAgICAgICAgICAgICAgcHV0cygiMCIpOyBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZighYnN0IHx8IGs8KmJsYWNrLmJlZ2luKCkpewogICAgICAgICAgICAgICAgcHJpbnRmKCIlbGxkXG4iLCBnZXQ8Mj4oZihrKSkpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYXV0byB0ID0gcXVlcnkoYnN0LCBrKTsKICAgICAgICAgICAgYXV0byB1ID0gZihrLWdldDwwPih0KS0xKTsKICAgICAgICAgICAgbGwgYW5zID0gKGdldDwzPih0KSpnZXQ8Mj4odSkrZ2V0PDQ+KHQpKmdldDwyPih1KStnZXQ8ND4odCkqZ2V0PDE+KHUpKSVQOwogICAgICAgICAgICBwcmludGYoIiVsbGRcbiIsIGFucyk7CiAgICAgICAgfWVsc2V7CiAgICAgICAgICAgIGF1dG8gcCA9IGJsYWNrLmluc2VydChrKTsKICAgICAgICAgICAgaWYoIXAuc2Vjb25kKSBjb250aW51ZTsKICAgICAgICAgICAgaWYoayA+IGJvdW5kKSBjb250aW51ZTsKICAgICAgICAgICAgYXV0byBpdCA9IHAuZmlyc3Q7CiAgICAgICAgICAgIGlmKGl0IT1ibGFjay5iZWdpbigpICYmICpwcmV2KGl0KT09ay0xKXsKICAgICAgICAgICAgICAgIGlmKHByZXYoaXQpIT1ibGFjay5iZWdpbigpICYmICpwcmV2KGl0LCAyKT09ay0yKXsKICAgICAgICAgICAgICAgICAgICBib3VuZCA9IGstMzsKICAgICAgICAgICAgICAgICAgICBic3QgPSBzcGxpdChic3QsIGJvdW5kKS5maXJzdDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKG5leHQoaXQpIT1ibGFjay5lbmQoKSAmJiAqbmV4dChpdCk9PWsrMSl7CiAgICAgICAgICAgICAgICAgICAgYm91bmQgPSBrLTI7CiAgICAgICAgICAgICAgICAgICAgYnN0ID0gc3BsaXQoYnN0LCBib3VuZCkuZmlyc3Q7CiAgICAgICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZigrK2l0ICE9IGJsYWNrLmVuZCgpKXsKICAgICAgICAgICAgICAgICAgICBhdXRvIHQgPSBmKCppdC1rLTIpOwogICAgICAgICAgICAgICAgICAgIGlmKG5leHQoaXQpIT1ibGFjay5lbmQoKSAmJiAqbmV4dChpdCk9PSppdCsxKXsKICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKGJzdCwgKml0KzEsIGdldDwyPih0KSwgMCwgZ2V0PDE+KHQpLCAwKTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKGJzdCwgKml0LCBnZXQ8MT4odCksIGdldDwyPih0KSwgZ2V0PDA+KHQpLCBnZXQ8MT4odCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGluY3JlbWVudF9rZXkoYnN0LCBrLTEsIHRydWUpOwogICAgICAgICAgICB9ZWxzZSBpZihuZXh0KGl0KSE9YmxhY2suZW5kKCkgJiYgKm5leHQoaXQpPT1rKzEpewogICAgICAgICAgICAgICAgaWYobmV4dChpdCwgMikhPWJsYWNrLmVuZCgpICYmICpuZXh0KGl0LCAyKT09aysyKXsKICAgICAgICAgICAgICAgICAgICBib3VuZCA9IGstMTsKICAgICAgICAgICAgICAgICAgICBic3QgPSBzcGxpdChic3QsIGJvdW5kKS5maXJzdDsKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGluY3JlbWVudF9rZXkoYnN0LCBrKzEsIGZhbHNlKTsKICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICBpZigrK2l0ICE9IGJsYWNrLmVuZCgpKXsKICAgICAgICAgICAgICAgICAgICBhdXRvIHQgPSBmKCppdC1rLTIpOwogICAgICAgICAgICAgICAgICAgIGlmKG5leHQoaXQpIT1ibGFjay5lbmQoKSAmJiAqbmV4dChpdCk9PSppdCsxKXsKICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKGJzdCwgKml0KzEsIGdldDwyPih0KSwgMCwgZ2V0PDE+KHQpLCAwKTsKICAgICAgICAgICAgICAgICAgICB9ZWxzZXsKICAgICAgICAgICAgICAgICAgICAgICAgdXBkYXRlKGJzdCwgKml0LCBnZXQ8MT4odCksIGdldDwyPih0KSwgZ2V0PDA+KHQpLCBnZXQ8MT4odCkpOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKC0taXQgPT0gYmxhY2suYmVnaW4oKSl7CiAgICAgICAgICAgICAgICAgICAgYXV0byB0ID0gZihrLTEpOwogICAgICAgICAgICAgICAgICAgIFN1YnQgcCwgcTsKICAgICAgICAgICAgICAgICAgICB0aWUocCwgcSkgPSBzcGxpdChic3QsIGspOwogICAgICAgICAgICAgICAgICAgIGJzdCA9IG1lcmdlKG1lcmdlKHAsIG1ha2Vfc2hhcmVkPE5vZGU+KGssIDAsIDAsIGdldDwxPih0KSwgZ2V0PDI+KHQpKSksIHEpOwogICAgICAgICAgICAgICAgfWVsc2V7CiAgICAgICAgICAgICAgICAgICAgYXV0byB0ID0gZihrLSpwcmV2KGl0KS0yKTsKICAgICAgICAgICAgICAgICAgICBTdWJ0IHAsIHE7CiAgICAgICAgICAgICAgICAgICAgdGllKHAsIHEpID0gc3BsaXQoYnN0LCBrKTsKICAgICAgICAgICAgICAgICAgICBic3QgPSBtZXJnZShtZXJnZShwLCBtYWtlX3NoYXJlZDxOb2RlPihrLCBnZXQ8MT4odCksIGdldDwyPih0KSwgZ2V0PDA+KHQpLCBnZXQ8MT4odCkpKSwgcSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9Cn0K