#include <iostream>
#include <math.h>
#include <algorithm>
#include <queue>
#include <vector>
#include <map>
#include <iomanip>
using namespace std;

typedef long long ll;
#define rep(i, n) for(long long i = 0; i < (long long)(n); i++)
#define repi(i,s,n) for (int i = (int)s; i < (int)n; i++)
#define memset(v, h) memset((v), h, sizeof(v))
int dx[4]={1,0,-1,0};
int dy[4]={0,1,0,-1};
using P = pair<ll, ll>;
const int INF = 1001001001;

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

const int MAX = 500010;
const int MOD = 1000000007;

bool comInit;
long long fac[MAX], finv[MAX], inv[MAX];

void cominit() {
    fac[0] = fac[1] = 1;
    finv[0] = finv[1] = 1;
    inv[1] = 1;
    for (int i = 2; i < MAX; i++){
        fac[i] = fac[i - 1] * i % MOD;
        inv[i] = MOD - inv[MOD%i] * (MOD / i) % MOD;
        finv[i] = finv[i - 1] * inv[i] % MOD;
    }
}

long long com(ll n, ll k){
    if(!comInit)
    {
        cominit();
    }
    if (n < k) return 0;
    if (n < 0 || k < 0) return 0;
    return fac[n] * (finv[k] * finv[n - k] % MOD) % MOD;
}

ll modpow(ll a, ll n, ll mod) {
    ll res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

ll moddiv(ll x, ll y, ll mod)
{
    y = modpow(y, mod-2, mod);
    return x * y % mod;
}

ll modcomb(ll n, ll r, ll mod) {
    ll x = 1;
    ll y = 1;

    rep(i, r)
    {
        x = (x * (n - i)) % mod;
        y = (y * (i + 1)) % mod;
    }

    return moddiv(x, y, mod);
}

struct uf {
    vector<ll> par;

    uf(int n)
    {
        for(int i = 0; i < n; i++) {
            par.push_back(-1);
        }
    }

    ll root(int x) 
    {
        if (par[x] < 0) return x;
        return par[x] = root(par[x]);
    }

    void unite(int x, int y) 
    {
        int rx = root(x);
        int ry = root(y);
        if (rx == ry) return;
        if(par[rx] < par[ry]) 
        {
            ll r = rx;
            rx = ry;
            ry = r;
        }

        par[rx] += par[ry];
        par[ry] = rx;
    }

    bool same(int x, int y) 
    {
        int rx = root(x);
        int ry = root(y);
        return rx == ry;
    }

    ll size(int x)
    {
        return -par[root(x)];
    }
};

class Radix {
private:
  const char* s;
  int a[128];
public:
  Radix(const char* s = "0123456789ABCDEF") : s(s) {
    int i;
    for(i = 0; s[i]; ++i)
      a[(int)s[i]] = i;
  }
  std::string to(long long p, int q) {
    int i;
    if(!p)
      return "0";
    char t[64] = { };
    for(i = 62; p; --i) {
      t[i] = s[p % q];
      p /= q;
    }
    return std::string(t + i + 1);
  }
  std::string to(const std::string& t, int p, int q) {
    return to(to(t, p), q);
  }
  long long to(const std::string& t, int p) {
    int i;
    long long sm = a[(int)t[0]];
    for(i = 1; i < (int)t.length(); ++i)
      sm = sm * p + a[(int)t[i]];
    return sm;
  }
};

struct node
{
    public: ll x;
    public: ll y;

    node(ll xx, ll yy)
    {
        x = xx;
        y = yy;
    }
};

  bool initComb;
  std::vector<std::vector<long long>> combC;

ll comb(int n, int r) {

  if(!initComb)
  {
      combC = vector<std::vector<long long>>(n + 1,std::vector<long long>(n + 1, 0));
      for (int i = 0; i < combC.size(); i++) {
    combC[i][0] = 1;
    combC[i][i] = 1;
  }
  for (int j = 1; j < combC.size(); j++) {
    for (int k = 1; k < j; k++) {
      combC[j][k] = (combC[j - 1][k - 1] + combC[j - 1][k]);
    }
  }
      initComb = true;
  }

  return combC[n][r];
}

ll digit(ll num)
{
    if(num < 10)
    {
        return 1;
    }

    ll d = 1;
    ll k = 10;
    while(num >= k)
    {
        d++;
        k *= 10;
    }

    return d;
}

ll digitNum(ll num, ll count)
{
    ll a = (num % (ll) pow((double) 10, (double) count));
    return a / pow(10, count - 1);
}

bool less_abs(int lhs, int rhs) {
    if(lhs < 0)
    {
        lhs *= -1;
    }
    if(rhs < 0)
    {
        rhs *= -1;
    }

    return lhs < rhs;
}

bool IsTrueBit(int bit, int index)
{
    return (bit & (1 << index));
}

int main(){
    ll k;
    cin >> k;

    if(k < 10)
    {
        cout << k << endl;
        return 0;
    }
    string MAX = "3234566669";

    vector<ll> list;
    queue<string> a;
    ll count = 0;

    rep(i, 10)
    {
        a.push(to_string(i));
    }

    while(list.size() < k * 2)
    {
        vector<string> oo;
        ll al;
        while(a.size() > 0)
        {
            string s = a.front();
            a.pop();
            count++;

            if(s[0] != '0')
            {
                ll num = stoll(s);
                list.push_back(num);
            }
            ll dig = s.size();
            al = pow(10, dig);
            int dist = s[0] - '0';
            char delta = '1' - '0';
            char w = s[0];
            if(dist > 0)
            {
                w--;
                string f1{w};
                oo.push_back(f1 + s);
                w++;
            }
            string f2{w};
            oo.push_back(f2 + s);

            w++;
            if(w <= '9')
            {
                string f3{w};
                oo.push_back(f3 + s);
            }
        }
        
        rep(i, oo.size())
        {
            a.push(oo[i]);
        }
    }

    sort(list.begin(), list.end());
    cout << list[k - 1] << endl;

    return 0;
}

Measured memory_bytes: 81184