#include <bits/stdc++.h>
#include <bits/extc++.h>
int main() {
using namespace std;
using namespace chrono;
using namespace __gnu_pbds;
using clock = high_resolution_clock;
const int M = 2, N = 2e4;
using ivec = array<int,N>;
using imat = array<ivec,M>;
using iset = set<int>;
mt19937 random(clock::now().time_since_epoch().count());
set<int> s;
tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> t;
const function<int(int)> tester[] = {
[&](int x){ return int(distance(s.begin(),s.find(x))); },
[&](int x){ return int(t.order_of_key(x)); } };
int v[N], result[M][N];
const auto test_set = [&](const string& prompt, int i) {
const auto t0 = clock::now();
const auto& f = tester[i];
for (int j = 0; j < N; ++j)
result[i][j] = f(v[j]);
const auto t1 = clock::now();
const auto time = duration_cast<milliseconds>(t1-t0).count();
cout << prompt << ": elapsed time = " << time << " msec." << endl; };
for (int x, size = 0; size < N; )
if (x = random(), s.find(x) == s.end())
s.insert(x), t.insert(x), v[size++] = x;
shuffle(v,v+N,random), test_set("iset",0), test_set("oset",1);
for (int j = 0; j < N; ++j)
if (result[0][j] != result[1][j])
cout << "Failed.", exit(0);
cout << "Passed"; }
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNpbmNsdWRlIDxiaXRzL2V4dGMrKy5oPgoKaW50IG1haW4oKSB7Cgl1c2luZyBuYW1lc3BhY2Ugc3RkOwoJdXNpbmcgbmFtZXNwYWNlIGNocm9ubzsKCXVzaW5nIG5hbWVzcGFjZSBfX2dudV9wYmRzOwoJdXNpbmcgY2xvY2sgPSBoaWdoX3Jlc29sdXRpb25fY2xvY2s7Cgljb25zdCBpbnQgTSA9IDIsIE4gPSAyZTQ7Cgl1c2luZyBpdmVjID0gYXJyYXk8aW50LE4+OwoJdXNpbmcgaW1hdCA9IGFycmF5PGl2ZWMsTT47Cgl1c2luZyBpc2V0ID0gc2V0PGludD47CgltdDE5OTM3IHJhbmRvbShjbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCkpOwoJc2V0PGludD4gczsgCgl0cmVlPGludCxudWxsX3R5cGUsbGVzczxpbnQ+LHJiX3RyZWVfdGFnLHRyZWVfb3JkZXJfc3RhdGlzdGljc19ub2RlX3VwZGF0ZT4gdDsKCWNvbnN0IGZ1bmN0aW9uPGludChpbnQpPiB0ZXN0ZXJbXSA9IHsKCQlbJl0oaW50IHgpeyByZXR1cm4gaW50KGRpc3RhbmNlKHMuYmVnaW4oKSxzLmZpbmQoeCkpKTsgfSwKCQlbJl0oaW50IHgpeyByZXR1cm4gaW50KHQub3JkZXJfb2Zfa2V5KHgpKTsgfSB9OwoJaW50IHZbTl0sIHJlc3VsdFtNXVtOXTsKCWNvbnN0IGF1dG8gdGVzdF9zZXQgPSBbJl0oY29uc3Qgc3RyaW5nJiBwcm9tcHQsIGludCBpKSB7CgkJY29uc3QgYXV0byB0MCA9IGNsb2NrOjpub3coKTsKCQljb25zdCBhdXRvJiBmID0gdGVzdGVyW2ldOwoJCWZvciAoaW50IGogPSAwOyBqIDwgTjsgKytqKQoJCQlyZXN1bHRbaV1bal0gPSBmKHZbal0pOwoJCWNvbnN0IGF1dG8gdDEgPSBjbG9jazo6bm93KCk7CgkJY29uc3QgYXV0byB0aW1lID0gZHVyYXRpb25fY2FzdDxtaWxsaXNlY29uZHM+KHQxLXQwKS5jb3VudCgpOwoJCWNvdXQgPDwgcHJvbXB0IDw8ICI6IGVsYXBzZWQgdGltZSA9ICIgPDwgdGltZSA8PCAiIG1zZWMuIiA8PCBlbmRsOyB9OwoJZm9yIChpbnQgeCwgc2l6ZSA9IDA7IHNpemUgPCBOOyApCgkJaWYgKHggPSByYW5kb20oKSwgcy5maW5kKHgpID09IHMuZW5kKCkpCgkJCXMuaW5zZXJ0KHgpLCB0Lmluc2VydCh4KSwgdltzaXplKytdID0geDsKCXNodWZmbGUodix2K04scmFuZG9tKSwgdGVzdF9zZXQoImlzZXQiLDApLCB0ZXN0X3NldCgib3NldCIsMSk7Cglmb3IgKGludCBqID0gMDsgaiA8IE47ICsraikKCQlpZiAocmVzdWx0WzBdW2pdICE9IHJlc3VsdFsxXVtqXSkKCQkJY291dCA8PCAiRmFpbGVkLiIsIGV4aXQoMCk7Cgljb3V0IDw8ICJQYXNzZWQiOyB9Cg==