#define _CRT_SECURE_NO_WARNINGS
#include <bits/stdc++.h>
#include <random>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define fi first
#define se second
#define sz(x) ((int)(x).size())
typedef vector<int> vi;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef double db;
mt19937 mrand(random_device{}());
const ll mod = 1000000007;
int rnd(int x) { return mrand() % x; }
ll powmod(ll a, ll b) { ll res = 1; a %= mod; assert(b >= 0); for (; b; b >>= 1) { if (b & 1)res = res * a % mod; a = a * a % mod; }return res; }
ll gcd(ll a, ll b) { return b ? gcd(b, a % b) : a; }

static uint MD = mod;
struct ModInt {
	using M = ModInt;
	uint v;
	ModInt(ll _v = 0) { set_v(uint(_v % MD + MD)); }
	M& set_v(uint _v)
	{
        v = (_v < MD) ? _v : _v - MD;
        return *this;
	}
	explicit operator bool() const { return v != 0; }
	M operator-() const { return M() - *this; }
	M operator+(const M& r) const { return M().set_v(v + r.v); }
	M operator-(const M& r) const { return M().set_v(v + MD - r.v); }
	M operator*(const M& r) const { return M().set_v(uint(ull(v) * r.v % MD)); }
	M operator/(const M& r) const { return *this * r.inv(); }
	M& operator+=(const M& r) { return *this = *this + r; }
	M& operator-=(const M& r) { return *this = *this - r; }
	M& operator*=(const M& r) { return *this = *this * r; }
	M& operator/=(const M& r) { return *this = *this / r; }
	bool operator==(const M& r) const { return v == r.v; }
	M pow(ll n) const
    {
        M x = *this, r = 1;
        while (n) {
            if (n & 1) r *= x;
            x *= x;
            n >>= 1;
        }
        return r;
    }
	M inv() const { return pow(MD - 2); }
	friend ostream& operator<<(ostream& os, const M& r) { return os << r.v; }
};
using Mint = ModInt;
//head

int dp[15][10];
//int dp2[15][10];
int dp3[15][10];

int main()
{
    ios::sync_with_stdio(false);
#ifdef RG
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout); 
#endif
	rep(i, 1, 15) {
		rep(j, 0, 10) {
			if (i == 1) dp[i][j] = 1;
			else {
				dp[i][j] = 0;
				rep(k, max(0, j - 1), min(10, j + 2)) {
					dp[i][j] += dp[i - 1][k];
				}
			}
		}
	}

	//dp2[1][0] = 0;
	//dp2[1][1] = 1;
	//rep(i, 1, 15) {
	//	rep(j, 0, 10) {
	//		if (i == 1 && j <= 1) continue;
	//		if (j == 0) {
	//			dp2[i][j] = dp2[i - 1][9] + dp[i][j];
	//		}
	//		else {
	//			dp2[i][j] = dp2[i][j - 1] + dp[i][j];
	//		}
	//	}
	//}

	dp3[1][0] = 0;
	dp3[1][1] = 1;
	rep(i, 1, 15) {
		rep(j, 1, 10) {
			if (i == 1 && j <= 1) continue;
			if (j == 1) {
				dp3[i][j] = dp3[i - 1][9] + dp[i][j];
			}
			else {
				dp3[i][j] = dp3[i][j - 1] + dp[i][j];
			}
		}
	}

	int n; cin >> n;
	string ans = "";
	int flag = 0;
	per(i, 1, 15) {
		per(j, 1, 10) {
			if (i == 1 && dp3[i][j] == n) {
				ans += '0' + j;
				break;
			}
			if (dp3[i][j] < n) {
				n -= dp3[i][j];
				int sj = j;
				int si = i;
				if (j == 9) {
					ans += '1';
					sj = 0;
					si = i + 1;
				}
				else {
					ans += '0' + j + 1;
				}
				per(k, 1, si) {
					/*rep(jj, sj, min(sj+2,10)) {
						if (n == 1 && dp[k][jj] == n) {
							ans += '0' + jj;
							break;
						}
						else if (dp[k][jj] < n) {
							n -= dp[k][jj];
							ans += '0' + jj+1;
							break;
						}
					}*/
					int jj = max(sj, 0);
					while(jj < min(sj + 3, 10)) {
						if (dp[k][jj] < n) {
							n -= dp[k][jj];
						}
						else break;
						++jj;
					}
					ans += '0' + jj;
					sj = jj - 1;
				}
				flag = 1;
				break;
			}
		}
		if (flag) break;
	}

	cout << ans << endl;
    return 0;
}


Measured memory_bytes: 256