#include<bits/stdc++.h>
using namespace std;
// 0 - [n-1]
int wantedIndex;
void printBCD(uint64_t bcd){
char buf[17];
char *c = buf + 16;
do{
*--c = '0' + (bcd & 0x0F);
bcd >>= 4;
}while(bcd > 0L);
buf[16] = '\0';
puts(c);
}
[[ noreturn ]] void returnBCD(uint64_t bcd) {
printBCD(bcd);
exit(EXIT_SUCCESS);
}
uint64_t bcd(uint64_t n){
int ret = 0;
int sh = 0;
while(n > 0){
ret += (n % 10) << sh;
n /= 10;
sh += 4;
}
return ret;
}
uint64_t get1f(uint64_t prefix, uint64_t number, int nWidth){
int nnumbers = (nWidth >> 2) * 9 + 10;
if(wantedIndex >= nnumbers) return nnumbers;
if(nWidth == 0){
returnBCD(prefix << 4 | wantedIndex);
}else{
//int i = 0;
char msd = number >> (nWidth - 4);
if(msd > wantedIndex)
returnBCD(prefix << 4 | wantedIndex << nWidth | number);
wantedIndex -= msd;
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
int pp = (prefix | number) & ~nMask;
wantedIndex -= get1f( pp, number & nMask, nW);
int i = msd + 1 + wantedIndex;
assert(i < 10);
returnBCD(prefix << 4 | i << nWidth | number);
}
}
uint64_t get2f(uint64_t prefix, uint64_t number, int nWidth){
int nnumbers = 100;
if(nWidth >= 16) nnumbers = 1270;
else if(nWidth >= 12) nnumbers = 856;
else if(nWidth >= 8) nnumbers = 523;
else if(nWidth >= 4) nnumbers = 271;
if(wantedIndex >= nnumbers) return nnumbers;
if(nWidth == 0){
returnBCD(prefix << 4 | bcd(wantedIndex) );
}else{
int i = 0;
char msd = number >> (nWidth - 4);
while(i < msd)
wantedIndex -= get1f(prefix << 4 | i++ << nWidth, number, nWidth);
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
wantedIndex -= get2f(prefix | msd << nW, number & nMask, nW);
i++;
while(i < 10)
wantedIndex -= get1f(prefix << 4 | i++ << nWidth, number, nWidth);
}
throw "Should not return get2f";
}
uint64_t get3f(uint64_t prefix, uint64_t number, int nWidth){
int nnumbers = 1000;
if(nWidth >= 16) nnumbers = 27280;
else if(nWidth >= 12) nnumbers = 15850;
else if(nWidth >= 8) nnumbers = 8146;
else if(nWidth >= 4) nnumbers = 3439;
if(wantedIndex >= nnumbers) return nnumbers;
if(nWidth == 0){
returnBCD(prefix << 4 | bcd(wantedIndex) );
}else{
int i = 0;
char msd = number >> (nWidth - 4);
while(i < msd)
wantedIndex -= get2f(prefix << 4 | i++ << nWidth, number, nWidth);
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
wantedIndex -= get3f(prefix | msd << nW, number & nMask, nW);
i++;
while(i < 10)
wantedIndex -= get2f(prefix << 4 | i++ << nWidth, number, nWidth);
}
throw "Should not return get3f";
}
uint64_t get4f(uint64_t prefix, uint64_t number, int nWidth){
int nnumbers = 10000;
if(nWidth >= 16) nnumbers = 502435;
else if(nWidth >= 12) nnumbers = 256915;
else if(nWidth >= 8) nnumbers = 114265;
else if(nWidth >= 4) nnumbers = 40951;
if(wantedIndex >= nnumbers) return nnumbers;
if(nWidth == 0){
returnBCD(prefix << 4 | bcd(wantedIndex) );
}else{
int i = 0;
char msd = number >> (nWidth - 4);
while(i < msd)
wantedIndex -= get3f(prefix << 4 | i++ << nWidth, number, nWidth);
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
wantedIndex -= get4f(prefix | msd << nW, number & nMask, nW);
i++;
while(i < 10)
wantedIndex -= get3f(prefix << 4 | i++ << nWidth, number, nWidth);
}
throw "Should not return get4f";
}
uint64_t get5f(uint64_t prefix, uint64_t number, int nWidth){
int nnumbers = 100000;
if(nWidth >= 16) nnumbers = 8331094;
else if(nWidth >= 12) nnumbers = 3809179;
else if(nWidth >= 8) nnumbers = 1496944;
else if(nWidth >= 4) nnumbers = 468559;
if(wantedIndex >= nnumbers) return nnumbers;
if(nWidth == 0){
returnBCD(prefix << 4 | bcd(wantedIndex) );
}else{
int i = 0;
char msd = number >> (nWidth - 4);
while(i < msd)
wantedIndex -= get4f(prefix << 4 | i++ << nWidth, number, nWidth);
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
wantedIndex -= get5f(prefix | msd << nW, number & nMask, nW);
i++;
while(i < 10)
wantedIndex -= get4f(prefix << 4 | i++ << nWidth, number, nWidth);
}
throw "Should not return get5f";
}
uint64_t get1(uint64_t prefix, uint64_t number, int nWidth, bool zero){
int i = !zero;
uint64_t n = 0;
if(nWidth != 0){
char msd = number >> (nWidth - 4);
while(i < msd){
//printBCD(prefix << 4 | i << nWidth | number);
i++;
n++;
}
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
int pp = (prefix | number) & ~nMask;
n += get1( pp, number & nMask, nW, true);
i++;
while(i < 10){
//printBCD(prefix << 4 | i << nWidth | number);
i++;
n++;
}
}else{
while(i < 10){
//printBCD(prefix << 4 | i);
i++;
n++;
}
}
//printf("Get1 (%d): %lu\n", nWidth, n);
return n;
}
uint64_t get2(uint64_t prefix, uint64_t number, int nWidth, bool zero){
int i = !zero;
uint64_t n = 0;
if(nWidth > 0){
// Most significant digit
char msd = number >> (nWidth - 4);
while(i < msd){
n += get1(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
n += get2(prefix | msd << nW, number & nMask, nW, true);
i++;
while(i < 10){
n += get1(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
}else{
i = 0;
while(1){
printBCD(prefix << 8 | i);
if( (++i & 0x0F) <= 9){
continue;
}
i+= 0x10 - 10;
if(i >= 0xA0) break;
}
n+= 100;
}
//printf("Get2 (%d): %lu\n", nWidth, n);
return n;
}
uint64_t get3(uint64_t prefix, uint64_t number, int nWidth, bool zero){
int i = !zero;
uint64_t n = 0;
if(nWidth > 0){
// Most significant digit
char msd = number >> (nWidth - 4);
while(i < msd){
wantedIndex = 0xFFFFFFF;
n += get2f(prefix << 4 | i << nWidth, number, nWidth);
i++;
}
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
n += get3(prefix | msd << nW, number & nMask, nW, true);
i++;
while(i < 10){
wantedIndex = 0xFFFFFFF;
n += get2f(prefix << 4 | i << nWidth, number, nWidth);
i++;
}
}else{
i = 0;
while(1){
//printBCD(prefix << 12 | i);
if( (++i & 0x0F) <= 9){
continue;
}
i+= 0x10 - 10;
if( (i & 0xFF) < 0xA0) continue;
i+= 0x100 - 0xA0;
if(i >= 0xA00) break;
}
n+= 1000;
}
printf("Get3 (%d): %lu\n", nWidth, n);
return n;
}
int depth = 1;
uint64_t get4(uint64_t prefix, uint64_t number, int nWidth, bool zero){
int i = !zero;
uint64_t n = 0;
if(nWidth > 0){
// Most significant digit
char msd = number >> (nWidth - 4);
while(i < msd){
n += get3(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
depth++;
n += get4(prefix | msd << nW, number & nMask, nW, true);
depth--;
i++;
while(i < 10){
n += get3(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
}else{
i = 0;
while(1){
//printBCD(prefix << 16 | i);
if( (++i & 0x0F) <= 9){
continue;
}
i+= 0x10 - 10;
if( (i & 0xFF) < 0xA0) continue;
i+= 0x100 - 0xA0;
if( (i & 0xFFF) < 0xA00) continue;
i+= 0x1000 - 0xA00;
if(i >= 0xA000) break;
}
n+= 10000;
}
printf("Get4 (%d): %lu\n", nWidth, n);
return n;
}
uint64_t get5(uint64_t prefix, uint64_t number, int nWidth, bool zero){
int i = !zero;
uint64_t n = 0;
if(nWidth > 0){
// Most significant digit
char msd = number >> (nWidth - 4);
while(i < msd){
n += get4(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
int nW = nWidth - 4;
int nMask = (1 << nW) - 1;
n += get5(prefix | msd << nW, number & nMask, nW, true);
i++;
while(i < 10){
n += get4(prefix << 4 | i << nWidth, number, nWidth, true);
i++;
}
}else{
i = 0;
/*while(1){
//printBCD(prefix << 16 | i);
if( (++i & 0x0F) <= 9){
continue;
}
i+= 0x10 - 10;
if( (i & 0xFF) < 0xA0) continue;
i+= 0x100 - 0xA0;
if( (i & 0xFFF) < 0xA00) continue;
i+= 0x1000 - 0xA00;
if(i >= 0xA000) break;
}*/
n+= 100000;
}
printf("Get5 (%d): %lu\n", nWidth, n);
return n;
}
int main(int argc, char *argv[]){
cin >> wantedIndex;
wantedIndex--;
//get1(0, 0x2021, 16, false);
/*const char str[] = "2021";
puts(str);*/
get5f(0, 0x2021, 16);
//get2f(0, 0x2021, 16);
}