#include <fstream>
#include <cstring>
using namespace std;
#define DIM 8+(1<<17)
#define in "nums.in"
#define out "nums.out"
#define LMAX 100010
struct Trie{
Trie *fii[10];
int cnt;
Trie()
{
for(int i = 0; i < 10; i++)
fii[i] = NULL;
cnt = 0;
}
};
Trie *numbers[LMAX];
int arb[DIM],start,finish,position,value,ans;
int maxL,M,solCount = - 1,lungime;
char sol[LMAX],curent[LMAX];
ifstream fin(in);
ofstream fout(out);
void query(int left,int right,int node)
{
if(start <= left && right <= finish)
{
ans += arb[node];
return;
}
int center = (left + right)/2;
if(start <= center)
query(left,center,2*node);
if(center < finish)
query(center+1,right,2*node+1);
}
void update(int left,int right,int node)
{
if(left == right)
{
arb[node]++;
return;
}
int center = (left + right)/2;
if(position <= center)
update(left,center,2*node);
else
update(center+1,right,2*node+1);
arb[node] = arb[2*node] + arb[2*node+1];
}
int bs(int key)
{
int left = 1, right = LMAX, center,val = 0;
start = 1;
while(left <= right)
{
center = (left + right)/2;
finish = center;
ans = 0;
query(1,LMAX,1);
if(ans == key)
{
val = center;
right = center - 1;
}
else
if(ans > key)
right = center - 1;
else
left = center + 1;
}
ans = 0;
center = (left + right)/2;
if(center == 0)
center++;
finish = center;
query(1,LMAX,1);
if(val != 0)
return val-1;
else
if(ans > key)
center--;
return center;
}
int find(int key)
{
int i,poz = 0;
start = 1;
for(i=1; i<LMAX; i++)
{
ans = 0;
finish = i;
query(1,LMAX,1);
if(ans < key)
poz = i;
else
break;
}
return poz;
}
void insert(Trie *node,char *s)
{
node->cnt++;
if(*s >= '0' && *s <= '9')
if(node->fii[*s-'0'])
insert(node->fii[*s-'0'],s+1);
else
{
node->fii[*s-'0'] = new Trie();
insert(node->fii[*s-'0'],s+1);
}
}
bool exists(Trie *node,char *s)
{
if(*s < '0' || *s >'9')
return 1;
else
{
if(*s >= '0' && *s <= '9')
if(node->fii[*s-'0'])
return 0 + exists(node->fii[*s-'0'],s+1);
else
return 0;
}
}
inline bool hasSons(Trie *node)
{
for(int i = 0; i < 10; i++)
if(node->fii[i])
return 1;
return 0;
}
int stringToNumber(char *S)
{
int lg = strlen(S), i = 0,ans = 0;
for(i = 0; i < lg; i++)
ans = ans * 10 + S[i] - '0';
return ans;
}
void TrieQuery(Trie *node,int position)
{
int i;
if(solCount < lungime-1)
for(i = 0; i < 10; i++)
if(node->fii[i])
if(node->fii[i]->cnt < position)
position -= node->fii[i]->cnt;
else
{
sol[++solCount] = i + '0';
TrieQuery(node->fii[i],position);
break;
}
}
void solve1()
{
int lg = strlen(curent);
lg-=2;
position = lg;
if(!exists(numbers[lg],curent+2))
{
update(1,LMAX,1);
insert(numbers[lg],curent+2);
}
}
void solve2(int key)
{
int poz = find(key);
start = 1;
finish = poz;
ans = 0;
if(finish != 0)
query(1,LMAX,1);
key -= ans;
solCount = -1;
lungime = poz+1;
TrieQuery(numbers[poz+1],key);
for(poz = 0; poz<=solCount; poz++)
fout<<sol[poz];
fout<<'\n';
}
int main()
{
int N,i;
fin>>N;
fin.get();
char *s = NULL;
for(i=1; i<=LMAX; i++)
numbers[i] = new Trie();
for(i=1; i<=N; i++)
{
strcpy(curent," ");
fin.get(curent,LMAX,'\n');
fin.get();
switch(curent[0])
{
case '1': solve1(); break;
case '0': solve2(stringToNumber(curent+2));
}
}
fin.close();
fout.close();
return 0;
}