//
// main.cpp
// xrqrs
//
// Created by Saras Gupta on 06/01/15.
// Copyright (c) 2015 sarasgupta. All rights reserved.
//
#include <iostream>
#include <algorithm>
#include <cmath>
#include <vector>
#define N 524288
//2^19=524288
#define mp(x,y) make_pair(x,y)
using namespace std;
typedef struct node {
int lp[ 2 ] ,rp[ 2 ] ,l,r,ct,mx;
//lp and rp point to the node's left and right child. [0] refers to the segment tree no. and [1] refers to the node number
//l and r are the left and right limits of the node
//ct is the counter for that node
//mx stores the number of elements <=r
} node;
vector< vector< node> > v( 500005 ) ; //array of segment trees
int ctr= 1 ,bin[ 20 ] ;
//ctr is the number of segment trees which are valid
//bin[i]=2^i
//make a base segment tree when there are no elements in the array
void init_tree( int it, int l, int r) {
v[ 0 ] [ it] .l = l;
v[ 0 ] [ it] .r = r;
v[ 0 ] [ it] .ct = 0 ;
v[ 0 ] [ it] .mx = 0 ;
if ( l! = r) {
int mid= ( l+ r) / 2 ;
init_tree( ( 2 * it) + 1 , l, mid) ;
init_tree( ( 2 * it) + 2 , mid+ 1 , r) ;
v[ 0 ] [ it] .lp [ 0 ] = 0 ;
v[ 0 ] [ it] .lp [ 1 ] = ( 2 * it) + 1 ;
v[ 0 ] [ it] .rp [ 0 ] = 0 ;
v[ 0 ] [ it] .rp [ 1 ] = ( 2 * it) + 2 ;
//add the index of the node's left and right child.
}
}
void q0( int it, int l, int r, pair< int , int > itm) {
if ( v[ ctr] [ it] .l == l&& v[ ctr] [ it] .r == r) {
v[ ctr] [ it] .lp [ 0 ] = v[ itm.first ] [ itm.second ] .lp [ 0 ] ;
v[ ctr] [ it] .lp [ 1 ] = v[ itm.first ] [ itm.second ] .lp [ 1 ] ;
v[ ctr] [ it] .rp [ 0 ] = v[ itm.first ] [ itm.second ] .rp [ 0 ] ;
v[ ctr] [ it] .rp [ 1 ] = v[ itm.first ] [ itm.second ] .rp [ 1 ] ;
//since there are no more changes below this node, we can easily point to the children of the previous segment tree as this node's children
v[ ctr] [ it] .l = l;
v[ ctr] [ it] .r = r;
v[ ctr] [ it] .ct = v[ itm.first ] [ itm.second ] .ct + 1 ;
v[ ctr] [ it] .mx = 0 ;
if ( l! = r) {
v[ ctr] [ it] .mx = v[ v[ ctr] [ it] .rp [ 0 ] ] [ v[ ctr] [ it] .rp [ 1 ] ] .mx + v[ v[ ctr] [ it] .rp [ 0 ] ] [ v[ ctr] [ it] .rp [ 1 ] ] .ct ;
}
}
else {
int mid= ( v[ ctr] [ it] .l + v[ ctr] [ it] .r ) / 2 ;
v[ ctr] [ it] .ct = v[ itm.first ] [ itm.second ] .ct ;
if ( l<= mid) {
//this means that we have to add a new node as the left child of this node and update this node accordingly
node tp;
v[ ctr] .push_back ( tp) ;
v[ ctr] [ it] .lp [ 0 ] = ctr;
v[ ctr] [ it] .lp [ 1 ] = v[ ctr] .size ( ) - 1 ;
v[ ctr] [ v[ ctr] .size ( ) - 1 ] .l = v[ ctr] [ it] .l ;
v[ ctr] [ v[ ctr] .size ( ) - 1 ] .r = mid;
q0( v[ ctr] .size ( ) - 1 , l, min( mid, r) , mp( v[ itm.first ] [ itm.second ] .lp [ 0 ] , v[ itm.first ] [ itm.second ] .lp [ 1 ] ) ) ;
}
else {
//else we can just point to the children of the prevous segment tree's node
v[ ctr] [ it] .lp [ 0 ] = v[ itm.first ] [ itm.second ] .lp [ 0 ] ;
v[ ctr] [ it] .lp [ 1 ] = v[ itm.first ] [ itm.second ] .lp [ 1 ] ;
}
if ( r> mid) {
//this means that we have to add a new node as the right child of this node and update this node accordingly
node tp;
tp.l = mid+ 1 ;
tp.r = r;
v[ ctr] .push_back ( tp) ;
v[ ctr] [ it] .rp [ 0 ] = ctr;
v[ ctr] [ it] .rp [ 1 ] = v[ ctr] .size ( ) - 1 ;
v[ ctr] [ v[ ctr] .size ( ) - 1 ] .l = mid+ 1 ;
v[ ctr] [ v[ ctr] .size ( ) - 1 ] .r = v[ ctr] [ it] .r ;
q0( v[ ctr] .size ( ) - 1 , max( mid+ 1 , l) , r, mp( v[ itm.first ] [ itm.second ] .rp [ 0 ] , v[ itm.first ] [ itm.second ] .rp [ 1 ] ) ) ;
}
else {
//else we can just point to the children of the prevous segment tree's node
v[ ctr] [ it] .rp [ 0 ] = v[ itm.first ] [ itm.second ] .rp [ 0 ] ;
v[ ctr] [ it] .rp [ 1 ] = v[ itm.first ] [ itm.second ] .rp [ 1 ] ;
}
v[ ctr] [ it] .mx = v[ v[ ctr] [ it] .rp [ 0 ] ] [ v[ ctr] [ it] .rp [ 1 ] ] .mx + v[ v[ ctr] [ it] .rp [ 0 ] ] [ v[ ctr] [ it] .rp [ 1 ] ] .ct ;
//updating mx of this node
}
}
int q3( pair< int , int > it, int r, int sum) {
if ( v[ it.first ] [ it.second ] .l == r&& v[ it.first ] [ it.second ] .r == r) {
return v[ it.first ] [ it.second ] .ct + sum;
}
else {
int mid= ( v[ it.first ] [ it.second ] .l + v[ it.first ] [ it.second ] .r ) / 2 ;
sum+ = v[ it.first ] [ it.second ] .ct ;
if ( mid>= r) {
return q3( mp( v[ it.first ] [ it.second ] .lp [ 0 ] , v[ it.first ] [ it.second ] .lp [ 1 ] ) , r, sum) ;
}
else {
return q3( mp( v[ it.first ] [ it.second ] .rp [ 0 ] , v[ it.first ] [ it.second ] .rp [ 1 ] ) , r, sum) ;
}
}
}
int q3f( int l, int r, int x) {
//ans(l,r,x)=ans(0, r, x)-ans(0, l-1, x)
int ans= q3( mp( r, 0 ) , x, 0 ) ;
//{r, 0} refers to the index of the root of the segment tree
if ( l> 1 ) {
ans- = q3( mp( l- 1 , 0 ) , x, 0 ) ;
}
return ans;
}
int q4t( int l, int r, int k) {
//Res ipsa loquitur
pair< int , int > il( l- 1 , 0 ) ;
pair< int , int > ir( r, 0 ) ;
int p1= 0 ,p2= 0 ;
while ( v[ ir.first ] [ ir.second ] .r - v[ ir.first ] [ ir.second ] .l >= 1 ) {
p1+ = v[ ir.first ] [ ir.second ] .ct ;
p2+ = v[ il.first ] [ il.second ] .ct ;
int p= v[ v[ ir.first ] [ ir.second ] .lp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .lp [ 1 ] ] .mx + v[ v[ ir.first ] [ ir.second ] .lp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .lp [ 1 ] ] .ct + p1;
int q= v[ v[ il.first ] [ il.second ] .lp [ 0 ] ] [ v[ il.first ] [ il.second ] .lp [ 1 ] ] .mx + v[ v[ il.first ] [ il.second ] .lp [ 0 ] ] [ v[ il.first ] [ il.second ] .lp [ 1 ] ] .ct + p2;
if ( p- q>= k) {
ir= mp( v[ ir.first ] [ ir.second ] .lp [ 0 ] , v[ ir.first ] [ ir.second ] .lp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .lp [ 0 ] , v[ il.first ] [ il.second ] .lp [ 1 ] ) ;
}
else {
ir= mp( v[ ir.first ] [ ir.second ] .rp [ 0 ] , v[ ir.first ] [ ir.second ] .rp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .rp [ 0 ] , v[ il.first ] [ il.second ] .rp [ 1 ] ) ;
}
}
return v[ ir.first ] [ ir.second ] .r ;
}
int q1t( int l, int r, int k) {
//if you understand q4t() than you can make this yourself
pair< int , int > il( l- 1 , 0 ) ;
pair< int , int > ir( r, 0 ) ;
int p1= 0 ,p2= 0 ;
int ctrr= r- l+ 1 ;
for ( int i= 18 ; i>= 0 ; i-- ) {
int p= v[ v[ ir.first ] [ ir.second ] .rp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .rp [ 1 ] ] .mx + v[ v[ ir.first ] [ ir.second ] .rp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .rp [ 1 ] ] .ct - ( v[ v[ ir.first ] [ ir.second ] .lp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .lp [ 1 ] ] .mx + v[ v[ ir.first ] [ ir.second ] .lp [ 0 ] ] [ v[ ir.first ] [ ir.second ] .lp [ 1 ] ] .ct ) ;
int q= v[ v[ il.first ] [ il.second ] .rp [ 0 ] ] [ v[ il.first ] [ il.second ] .rp [ 1 ] ] .mx + v[ v[ il.first ] [ il.second ] .rp [ 0 ] ] [ v[ il.first ] [ il.second ] .rp [ 1 ] ] .ct - ( v[ v[ il.first ] [ il.second ] .lp [ 0 ] ] [ v[ il.first ] [ il.second ] .lp [ 1 ] ] .mx + v[ v[ il.first ] [ il.second ] .lp [ 0 ] ] [ v[ il.first ] [ il.second ] .lp [ 1 ] ] .ct ) ;
if ( bin[ i] & k) {
if ( p- q< ctrr) {
ir= mp( v[ ir.first ] [ ir.second ] .lp [ 0 ] , v[ ir.first ] [ ir.second ] .lp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .lp [ 0 ] , v[ il.first ] [ il.second ] .lp [ 1 ] ) ;
ctrr- = p- q;
}
else {
ir= mp( v[ ir.first ] [ ir.second ] .rp [ 0 ] , v[ ir.first ] [ ir.second ] .rp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .rp [ 0 ] , v[ il.first ] [ il.second ] .rp [ 1 ] ) ;
ctrr- = ctrr- ( p- q) ;
}
}
else {
if ( p- q== 0 ) {
ir= mp( v[ ir.first ] [ ir.second ] .lp [ 0 ] , v[ ir.first ] [ ir.second ] .lp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .lp [ 0 ] , v[ il.first ] [ il.second ] .lp [ 1 ] ) ;
ctrr- = p- q;
}
else {
ir= mp( v[ ir.first ] [ ir.second ] .rp [ 0 ] , v[ ir.first ] [ ir.second ] .rp [ 1 ] ) ;
il= mp( v[ il.first ] [ il.second ] .rp [ 0 ] , v[ il.first ] [ il.second ] .rp [ 1 ] ) ;
ctrr- = ctrr- ( p- q) ;
}
}
}
return v[ ir.first ] [ ir.second ] .r ;
}
int main( int argc, const char * argv[ ] ) {
int m,type,l,r,x,cctt= 0 ;
cin >> m;
for ( int i= 0 ; i< 20 ; i++ ) {
bin[ i] = 1 << i;
}
v[ 0 ] .resize ( ( long long int ) ( ( 2 * ( pow ( 2 , ceil ( log2( N) ) ) ) ) - 1 ) ) ;
init_tree( 0 , 0 , N- 1 ) ;
for ( int i= 0 ; i< m; i++ ) {
cin >> type;
if ( type== 0 ) {
cctt++ ;
cin >> x;
v[ ctr] .clear ( ) ;
node tp;
tp.l = 0 ;
tp.r = N- 1 ;
v[ ctr] .push_back ( tp) ;
//initializing the root for this segment tree
q0( 0 , x, N- 1 , mp( ctr- 1 , 0 ) ) ;
ctr++ ;
}
else if ( type== 1 ) {
cin >> l>> r>> x;
cout << q1t( l, r, x) << endl;
}
else if ( type== 2 ) {
cin >> x;
ctr- = x;
//for deleting the last k elements just forget that the last k elements ever existed, it doesn't affect the trees before it.
}
else if ( type== 3 ) {
cin >> l>> r>> x;
cout << q3f( l, r, x) << endl;
}
else {
cin >> l>> r>> x;
cout << q4t( l, r, x) << endl;
}
}
return 0 ;
}
Ly8KLy8gIG1haW4uY3BwCi8vICB4cnFycwovLwovLyAgQ3JlYXRlZCBieSBTYXJhcyBHdXB0YSBvbiAwNi8wMS8xNS4KLy8gIENvcHlyaWdodCAoYykgMjAxNSBzYXJhc2d1cHRhLiBBbGwgcmlnaHRzIHJlc2VydmVkLgovLwoKI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8YWxnb3JpdGhtPgojaW5jbHVkZSA8Y21hdGg+CiNpbmNsdWRlIDx2ZWN0b3I+CgojZGVmaW5lIE4gNTI0Mjg4Ci8vMl4xOT01MjQyODgKI2RlZmluZSBtcCh4LHkpIG1ha2VfcGFpcih4LHkpCgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKdHlwZWRlZiBzdHJ1Y3Qgbm9kZSB7CiAgICBpbnQgbHBbMl0scnBbMl0sbCxyLGN0LG14OwogICAgLy9scCBhbmQgcnAgcG9pbnQgdG8gdGhlIG5vZGUncyBsZWZ0IGFuZCByaWdodCBjaGlsZC4gWzBdIHJlZmVycyB0byB0aGUgc2VnbWVudCB0cmVlIG5vLiBhbmQgWzFdIHJlZmVycyB0byB0aGUgbm9kZSBudW1iZXIKICAgIC8vbCBhbmQgciBhcmUgdGhlIGxlZnQgYW5kIHJpZ2h0IGxpbWl0cyBvZiB0aGUgbm9kZQogICAgLy9jdCBpcyB0aGUgY291bnRlciBmb3IgdGhhdCBub2RlCiAgICAvL214IHN0b3JlcyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIDw9cgp9bm9kZTsKCnZlY3Rvcjx2ZWN0b3I8bm9kZT4gPiB2KDUwMDAwNSk7Ly9hcnJheSBvZiBzZWdtZW50IHRyZWVzCmludCBjdHI9MSxiaW5bMjBdOwovL2N0ciBpcyB0aGUgbnVtYmVyIG9mIHNlZ21lbnQgdHJlZXMgd2hpY2ggYXJlIHZhbGlkCi8vYmluW2ldPTJeaQoKLy9tYWtlIGEgYmFzZSBzZWdtZW50IHRyZWUgd2hlbiB0aGVyZSBhcmUgbm8gZWxlbWVudHMgaW4gdGhlIGFycmF5CnZvaWQgaW5pdF90cmVlKGludCBpdCwgaW50IGwsIGludCByKSB7CiAgICB2WzBdW2l0XS5sPWw7CiAgICB2WzBdW2l0XS5yPXI7CiAgICB2WzBdW2l0XS5jdD0wOwogICAgdlswXVtpdF0ubXg9MDsKICAgIGlmIChsIT1yKSB7CiAgICAgICAgaW50IG1pZD0obCtyKS8yOwogICAgICAgIGluaXRfdHJlZSgoMippdCkrMSwgbCwgbWlkKTsKICAgICAgICBpbml0X3RyZWUoKDIqaXQpKzIsIG1pZCsxLCByKTsKICAgICAgICB2WzBdW2l0XS5scFswXT0wOwogICAgICAgIHZbMF1baXRdLmxwWzFdPSgyKml0KSsxOwogICAgICAgIHZbMF1baXRdLnJwWzBdPTA7CiAgICAgICAgdlswXVtpdF0ucnBbMV09KDIqaXQpKzI7CiAgICAgICAgLy9hZGQgdGhlIGluZGV4IG9mIHRoZSBub2RlJ3MgbGVmdCBhbmQgcmlnaHQgY2hpbGQuCiAgICB9Cn0KCnZvaWQgcTAoaW50IGl0LCBpbnQgbCwgaW50IHIsIHBhaXI8aW50LCBpbnQ+IGl0bSkgewogICAgaWYgKHZbY3RyXVtpdF0ubD09bCYmdltjdHJdW2l0XS5yPT1yKSB7CiAgICAgICAgdltjdHJdW2l0XS5scFswXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ubHBbMF07CiAgICAgICAgdltjdHJdW2l0XS5scFsxXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ubHBbMV07CiAgICAgICAgdltjdHJdW2l0XS5ycFswXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ucnBbMF07CiAgICAgICAgdltjdHJdW2l0XS5ycFsxXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ucnBbMV07CiAgICAgICAgLy9zaW5jZSB0aGVyZSBhcmUgbm8gbW9yZSBjaGFuZ2VzIGJlbG93IHRoaXMgbm9kZSwgd2UgY2FuIGVhc2lseSBwb2ludCB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIHByZXZpb3VzIHNlZ21lbnQgdHJlZSBhcyB0aGlzIG5vZGUncyBjaGlsZHJlbgogICAgICAgIHZbY3RyXVtpdF0ubD1sOwogICAgICAgIHZbY3RyXVtpdF0ucj1yOwogICAgICAgIHZbY3RyXVtpdF0uY3Q9dltpdG0uZmlyc3RdW2l0bS5zZWNvbmRdLmN0KzE7CiAgICAgICAgdltjdHJdW2l0XS5teD0wOwogICAgICAgIGlmIChsIT1yKSB7CiAgICAgICAgICAgIHZbY3RyXVtpdF0ubXg9dlt2W2N0cl1baXRdLnJwWzBdXVt2W2N0cl1baXRdLnJwWzFdXS5teCt2W3ZbY3RyXVtpdF0ucnBbMF1dW3ZbY3RyXVtpdF0ucnBbMV1dLmN0OwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIGludCBtaWQ9KHZbY3RyXVtpdF0ubCt2W2N0cl1baXRdLnIpLzI7CiAgICAgICAgdltjdHJdW2l0XS5jdD12W2l0bS5maXJzdF1baXRtLnNlY29uZF0uY3Q7CiAgICAgICAgaWYgKGw8PW1pZCkgewogICAgICAgICAgICAvL3RoaXMgbWVhbnMgdGhhdCB3ZSBoYXZlIHRvIGFkZCBhIG5ldyBub2RlIGFzIHRoZSBsZWZ0IGNoaWxkIG9mIHRoaXMgbm9kZSBhbmQgdXBkYXRlIHRoaXMgbm9kZSBhY2NvcmRpbmdseQogICAgICAgICAgICBub2RlIHRwOwogICAgICAgICAgICB2W2N0cl0ucHVzaF9iYWNrKHRwKTsKICAgICAgICAgICAgdltjdHJdW2l0XS5scFswXT1jdHI7CiAgICAgICAgICAgIHZbY3RyXVtpdF0ubHBbMV09dltjdHJdLnNpemUoKS0xOwogICAgICAgICAgICB2W2N0cl1bdltjdHJdLnNpemUoKS0xXS5sPXZbY3RyXVtpdF0ubDsKICAgICAgICAgICAgdltjdHJdW3ZbY3RyXS5zaXplKCktMV0ucj1taWQ7CiAgICAgICAgICAgIHEwKHZbY3RyXS5zaXplKCktMSwgbCwgbWluKG1pZCwgciksIG1wKHZbaXRtLmZpcnN0XVtpdG0uc2Vjb25kXS5scFswXSwgdltpdG0uZmlyc3RdW2l0bS5zZWNvbmRdLmxwWzFdKSk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICAvL2Vsc2Ugd2UgY2FuIGp1c3QgcG9pbnQgdG8gdGhlIGNoaWxkcmVuIG9mIHRoZSBwcmV2b3VzIHNlZ21lbnQgdHJlZSdzIG5vZGUKICAgICAgICAgICAgdltjdHJdW2l0XS5scFswXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ubHBbMF07CiAgICAgICAgICAgIHZbY3RyXVtpdF0ubHBbMV09dltpdG0uZmlyc3RdW2l0bS5zZWNvbmRdLmxwWzFdOwogICAgICAgIH0KICAgICAgICBpZiAocj5taWQpIHsKICAgICAgICAgICAgLy90aGlzIG1lYW5zIHRoYXQgd2UgaGF2ZSB0byBhZGQgYSBuZXcgbm9kZSBhcyB0aGUgcmlnaHQgY2hpbGQgb2YgdGhpcyBub2RlIGFuZCB1cGRhdGUgdGhpcyBub2RlIGFjY29yZGluZ2x5CiAgICAgICAgICAgIG5vZGUgdHA7CiAgICAgICAgICAgIHRwLmw9bWlkKzE7CiAgICAgICAgICAgIHRwLnI9cjsKICAgICAgICAgICAgdltjdHJdLnB1c2hfYmFjayh0cCk7CiAgICAgICAgICAgIHZbY3RyXVtpdF0ucnBbMF09Y3RyOwogICAgICAgICAgICB2W2N0cl1baXRdLnJwWzFdPXZbY3RyXS5zaXplKCktMTsKICAgICAgICAgICAgdltjdHJdW3ZbY3RyXS5zaXplKCktMV0ubD1taWQrMTsKICAgICAgICAgICAgdltjdHJdW3ZbY3RyXS5zaXplKCktMV0ucj12W2N0cl1baXRdLnI7CiAgICAgICAgICAgIHEwKHZbY3RyXS5zaXplKCktMSwgbWF4KG1pZCsxLCBsKSwgciwgbXAodltpdG0uZmlyc3RdW2l0bS5zZWNvbmRdLnJwWzBdLCB2W2l0bS5maXJzdF1baXRtLnNlY29uZF0ucnBbMV0pKTsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIC8vZWxzZSB3ZSBjYW4ganVzdCBwb2ludCB0byB0aGUgY2hpbGRyZW4gb2YgdGhlIHByZXZvdXMgc2VnbWVudCB0cmVlJ3Mgbm9kZQogICAgICAgICAgICB2W2N0cl1baXRdLnJwWzBdPXZbaXRtLmZpcnN0XVtpdG0uc2Vjb25kXS5ycFswXTsKICAgICAgICAgICAgdltjdHJdW2l0XS5ycFsxXT12W2l0bS5maXJzdF1baXRtLnNlY29uZF0ucnBbMV07CiAgICAgICAgfQogICAgICAgIHZbY3RyXVtpdF0ubXg9dlt2W2N0cl1baXRdLnJwWzBdXVt2W2N0cl1baXRdLnJwWzFdXS5teCt2W3ZbY3RyXVtpdF0ucnBbMF1dW3ZbY3RyXVtpdF0ucnBbMV1dLmN0OwogICAgICAgIC8vdXBkYXRpbmcgbXggb2YgdGhpcyBub2RlCiAgICB9Cn0KCmludCBxMyhwYWlyPGludCwgaW50PiBpdCwgaW50IHIsIGludCBzdW0pIHsKICAgIGlmICh2W2l0LmZpcnN0XVtpdC5zZWNvbmRdLmw9PXImJnZbaXQuZmlyc3RdW2l0LnNlY29uZF0ucj09cikgewogICAgICAgIHJldHVybiB2W2l0LmZpcnN0XVtpdC5zZWNvbmRdLmN0K3N1bTsKICAgIH0KICAgIGVsc2UgewogICAgICAgIGludCBtaWQ9KHZbaXQuZmlyc3RdW2l0LnNlY29uZF0ubCt2W2l0LmZpcnN0XVtpdC5zZWNvbmRdLnIpLzI7CiAgICAgICAgc3VtKz12W2l0LmZpcnN0XVtpdC5zZWNvbmRdLmN0OwogICAgICAgIGlmIChtaWQ+PXIpIHsKICAgICAgICAgICAgcmV0dXJuIHEzKG1wKHZbaXQuZmlyc3RdW2l0LnNlY29uZF0ubHBbMF0sIHZbaXQuZmlyc3RdW2l0LnNlY29uZF0ubHBbMV0pLCByLCBzdW0pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgcmV0dXJuIHEzKG1wKHZbaXQuZmlyc3RdW2l0LnNlY29uZF0ucnBbMF0sIHZbaXQuZmlyc3RdW2l0LnNlY29uZF0ucnBbMV0pLCByLCBzdW0pOwogICAgICAgIH0KICAgIH0KfQoKaW50IHEzZihpbnQgbCwgaW50IHIsIGludCB4KSB7CiAgICAvL2FucyhsLHIseCk9YW5zKDAsIHIsIHgpLWFucygwLCBsLTEsIHgpCiAgICBpbnQgYW5zPXEzKG1wKHIsIDApLCB4LCAwKTsKICAgIC8ve3IsIDB9IHJlZmVycyB0byB0aGUgaW5kZXggb2YgdGhlIHJvb3Qgb2YgdGhlIHNlZ21lbnQgdHJlZQogICAgaWYgKGw+MSkgewogICAgICAgIGFucy09cTMobXAobC0xLCAwKSwgeCwgMCk7CiAgICB9CiAgICByZXR1cm4gYW5zOwp9CgppbnQgcTR0KGludCBsLCBpbnQgciwgaW50IGspIHsKICAgIC8vUmVzIGlwc2EgbG9xdWl0dXIKICAgIHBhaXI8aW50LCBpbnQ+IGlsKGwtMSwgMCk7CiAgICBwYWlyPGludCwgaW50PiBpcihyLCAwKTsKICAgIGludCBwMT0wLHAyPTA7CiAgICB3aGlsZSAodltpci5maXJzdF1baXIuc2Vjb25kXS5yLXZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubD49MSkgewogICAgICAgIHAxKz12W2lyLmZpcnN0XVtpci5zZWNvbmRdLmN0OwogICAgICAgIHAyKz12W2lsLmZpcnN0XVtpbC5zZWNvbmRdLmN0OwogICAgICAgIGludCBwPXZbdltpci5maXJzdF1baXIuc2Vjb25kXS5scFswXV1bdltpci5maXJzdF1baXIuc2Vjb25kXS5scFsxXV0ubXggKyB2W3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMF1dW3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMV1dLmN0K3AxOwogICAgICAgIGludCBxPXZbdltpbC5maXJzdF1baWwuc2Vjb25kXS5scFswXV1bdltpbC5maXJzdF1baWwuc2Vjb25kXS5scFsxXV0ubXggKyB2W3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMF1dW3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMV1dLmN0K3AyOwogICAgICAgIGlmIChwLXE+PWspIHsKICAgICAgICAgICAgaXI9bXAodltpci5maXJzdF1baXIuc2Vjb25kXS5scFswXSwgdltpci5maXJzdF1baXIuc2Vjb25kXS5scFsxXSk7CiAgICAgICAgICAgIGlsPW1wKHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMF0sIHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMV0pOwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgICAgaXI9bXAodltpci5maXJzdF1baXIuc2Vjb25kXS5ycFswXSwgdltpci5maXJzdF1baXIuc2Vjb25kXS5ycFsxXSk7CiAgICAgICAgICAgIGlsPW1wKHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMF0sIHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMV0pOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnI7Cn0KCmludCBxMXQoaW50IGwsIGludCByLCBpbnQgaykgewogICAgLy9pZiB5b3UgdW5kZXJzdGFuZCBxNHQoKSB0aGFuIHlvdSBjYW4gbWFrZSB0aGlzIHlvdXJzZWxmCiAgICBwYWlyPGludCwgaW50PiBpbChsLTEsIDApOwogICAgcGFpcjxpbnQsIGludD4gaXIociwgMCk7CiAgICBpbnQgcDE9MCxwMj0wOwogICAgaW50IGN0cnI9ci1sKzE7CiAgICBmb3IgKGludCBpPTE4OyBpPj0wOyBpLS0pIHsKICAgICAgICBpbnQgcD12W3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ucnBbMF1dW3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ucnBbMV1dLm14ICsgdlt2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnJwWzBdXVt2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnJwWzFdXS5jdCAgLSAgKHZbdltpci5maXJzdF1baXIuc2Vjb25kXS5scFswXV1bdltpci5maXJzdF1baXIuc2Vjb25kXS5scFsxXV0ubXggKyB2W3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMF1dW3ZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMV1dLmN0KTsKICAgICAgICBpbnQgcT12W3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMF1dW3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMV1dLm14ICsgdlt2W2lsLmZpcnN0XVtpbC5zZWNvbmRdLnJwWzBdXVt2W2lsLmZpcnN0XVtpbC5zZWNvbmRdLnJwWzFdXS5jdCAgLSAgKHZbdltpbC5maXJzdF1baWwuc2Vjb25kXS5scFswXV1bdltpbC5maXJzdF1baWwuc2Vjb25kXS5scFsxXV0ubXggKyB2W3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMF1dW3ZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMV1dLmN0KTsKICAgICAgICBpZiAoYmluW2ldJmspIHsKICAgICAgICAgICAgaWYgKHAtcTxjdHJyKSB7CiAgICAgICAgICAgICAgICBpcj1tcCh2W2lyLmZpcnN0XVtpci5zZWNvbmRdLmxwWzBdLCB2W2lyLmZpcnN0XVtpci5zZWNvbmRdLmxwWzFdKTsKICAgICAgICAgICAgICAgIGlsPW1wKHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMF0sIHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ubHBbMV0pOwogICAgICAgICAgICAgICAgY3Ryci09cC1xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgaXI9bXAodltpci5maXJzdF1baXIuc2Vjb25kXS5ycFswXSwgdltpci5maXJzdF1baXIuc2Vjb25kXS5ycFsxXSk7CiAgICAgICAgICAgICAgICBpbD1tcCh2W2lsLmZpcnN0XVtpbC5zZWNvbmRdLnJwWzBdLCB2W2lsLmZpcnN0XVtpbC5zZWNvbmRdLnJwWzFdKTsKICAgICAgICAgICAgICAgIGN0cnItPWN0cnItKHAtcSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGlmIChwLXE9PTApIHsKICAgICAgICAgICAgICAgIGlyPW1wKHZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMF0sIHZbaXIuZmlyc3RdW2lyLnNlY29uZF0ubHBbMV0pOwogICAgICAgICAgICAgICAgaWw9bXAodltpbC5maXJzdF1baWwuc2Vjb25kXS5scFswXSwgdltpbC5maXJzdF1baWwuc2Vjb25kXS5scFsxXSk7CiAgICAgICAgICAgICAgICBjdHJyLT1wLXE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICBpcj1tcCh2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnJwWzBdLCB2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnJwWzFdKTsKICAgICAgICAgICAgICAgIGlsPW1wKHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMF0sIHZbaWwuZmlyc3RdW2lsLnNlY29uZF0ucnBbMV0pOwogICAgICAgICAgICAgICAgY3Ryci09Y3Ryci0ocC1xKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIHJldHVybiB2W2lyLmZpcnN0XVtpci5zZWNvbmRdLnI7Cn0KCmludCBtYWluKGludCBhcmdjLCBjb25zdCBjaGFyICogYXJndltdKSB7CiAgICBpbnQgbSx0eXBlLGwscix4LGNjdHQ9MDsKICAgIGNpbj4+bTsKICAgIGZvciAoaW50IGk9MDsgaTwyMDsgaSsrKSB7CiAgICAgICAgYmluW2ldPTE8PGk7CiAgICB9CiAgICB2WzBdLnJlc2l6ZSgobG9uZyBsb25nIGludCkoKDIqKHBvdygyLCBjZWlsKGxvZzIoTikpKSkpLTEpKTsKICAgIGluaXRfdHJlZSgwLCAwLCBOLTEpOwogICAgZm9yIChpbnQgaT0wOyBpPG07IGkrKykgewogICAgICAgIGNpbj4+dHlwZTsKICAgICAgICBpZiAodHlwZT09MCkgewogICAgICAgICAgICBjY3R0Kys7CiAgICAgICAgICAgIGNpbj4+eDsKICAgICAgICAgICAgdltjdHJdLmNsZWFyKCk7CiAgICAgICAgICAgIG5vZGUgdHA7CiAgICAgICAgICAgIHRwLmw9MDsKICAgICAgICAgICAgdHAucj1OLTE7CiAgICAgICAgICAgIHZbY3RyXS5wdXNoX2JhY2sodHApOwogICAgICAgICAgICAvL2luaXRpYWxpemluZyB0aGUgcm9vdCBmb3IgdGhpcyBzZWdtZW50IHRyZWUKICAgICAgICAgICAgcTAoMCwgeCwgTi0xLCBtcChjdHItMSwgMCkpOwogICAgICAgICAgICBjdHIrKzsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodHlwZT09MSkgewogICAgICAgICAgICBjaW4+Pmw+PnI+Png7CiAgICAgICAgICAgIGNvdXQ8PHExdChsLCByLCB4KTw8ZW5kbDsKICAgICAgICB9CiAgICAgICAgZWxzZSBpZiAodHlwZT09MikgewogICAgICAgICAgICBjaW4+Png7CiAgICAgICAgICAgIGN0ci09eDsKICAgICAgICAgICAgLy9mb3IgZGVsZXRpbmcgdGhlIGxhc3QgayBlbGVtZW50cyBqdXN0IGZvcmdldCB0aGF0IHRoZSBsYXN0IGsgZWxlbWVudHMgZXZlciBleGlzdGVkLCBpdCBkb2Vzbid0IGFmZmVjdCB0aGUgdHJlZXMgYmVmb3JlIGl0LgogICAgICAgIH0KICAgICAgICBlbHNlIGlmICAodHlwZT09MykgewogICAgICAgICAgICBjaW4+Pmw+PnI+Png7CiAgICAgICAgICAgIGNvdXQ8PHEzZihsLCByLCB4KTw8ZW5kbDsKICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNpbj4+bD4+cj4+eDsKICAgICAgICAgICAgY291dDw8cTR0KGwsIHIsIHgpPDxlbmRsOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiAwOwp9Cg==