#include <bits/stdc++.h>
#include <chrono>
using namespace std;
typedef long long ll;
#define tr(container, it) \
    for (auto it = container.begin(); it != container.end(); it++)
#define scontains(c, x) ((c).find(x) != (c).end())   //O(log n)
#define contains(c, x) (find((c).begin(),(c).end(),x) != (c).end()) //O(n)
#define ill(_x)  ll _x;scanf("%lld",&_x);
#define idb(_x)  double _x;scanf("%lf",&_x);
#define pll pair<ll,ll>
#define pii pair<int,int>
#define mll map<ll,ll>
#define vll vector<ll>
#define sll set<ll>
#define vs vector<string>
#define in0(x, a, b)((x)>=a && (x)<=b    )
#define in1(x, a, b)((x)>a && (x)<b)
#define  rep(i, begin, end) for (__typeof(end) i = (begin) - ((begin) > (end)); i != (end) - ((begin) > (end)); i += 1 - 2 * ((begin) > (end)))
const double pi = 3.14159265358979323846;
const double e  = 2.71828182845904523536;
const int INF = 0x3f3f3f3f;
const int MOD = (int) (1e9) + 7;

//cout << "Plz enter the number of bits" <<endl;
//cin >> size;
//
//freopen("/home/joduskame/Desktop/cp/IO/Output.txt", "w", stdout);
//cout << setw(max(3,size))<<"num"<<"  two_c" <<" one_c" <<endl;
//int show_index=MX-size-1;
//cout << setw(max(3,size))<<-(int)pow(2,size-1)<< ": " << (bitset<MX>(-(int)pow(2,size-1)).to_string()).substr(show_index,size)<<" Not exist"<<"\n";
//for (int i = -(int)pow(2,size-1)+1; i < (int)pow(2,size-1); ++i) {
//bitset<MX> bt=i<0? bitset<MX>((int)(pow(2,size)-1) ^(-i)):bitset<MX>(i);
//cout << setw(max(3,size))<<i<< ": " << (bitset<MX>(i).to_string()).substr(show_index,size)<<" "<<bt.to_string().substr(show_index,size)<<"\n";
//}

// Binary search (note boundaries in the caller)
int CeilIndex(std::vector<int> &v, int l, int r, int key) {
    while (r-l > 1) {
        int m = l + (r-l)/2;
        if (v[m] >= key)
            r = m;
        else
            l = m;
    }
    vector<int> a;
    a.clear();

    return r;
}

int LongestIncreasingSubsequenceLength(std::vector<int> &v) {
    if (v.size() == 0)
        return 0;

    std::vector<int> tail(v.size(), 0);
    int length = 1; // always points empty slot in tail

    tail[0] = v[0];
    for (size_t i = 1; i < v.size(); i++) {
        if (v[i] < tail[0])
            // new smallest value
            tail[0] = v[i];
        else if (v[i] > tail[length-1])
            // v[i] extends largest subsequence
            tail[length++] = v[i];
        else
            // v[i] will become end candidate of an existing subsequence or
            // Throw away larger elements in all LIS, to make room for upcoming grater elements than v[i]
            // (and also, v[i] would have already appeared in one of LIS, identify the location and replace it)
            tail[CeilIndex(tail, -1, length-1, v[i])] = v[i];
    }

    return length;
}

void swap2(int &a,int &b){
    a^=b^=a^=b;
}

int add(int x,int y){
    while(y){
        x=x^y;
        y=((x^y)&y)<<1;
    }
    return x;
}

int min2(int x, int y)
{
    return  y + ((x - y) & ((x - y) >> 31));
}

int min3(int a,int b,int c){
    int d=1;
    while (a-- && b-- &&c-- &&d++){}
    return d-1;

}

template<typename T>
bool isPrime(T n)
{
    if (n <= 1) return false;
    if (n == 2) return true;
    if (n % 2 == 0) return false;
    T m = sqrt(n);


    for (T i = 3; i <= m; i += 2)
        if (n%i == 0)
            return false;

    return true;
}


int A[100000];
void _(){
    int n;
    cin >> n;
    A[0]=0;
    for (int i = 1; i <= n; ++i) {
        int t=1,s=1;
        int mi=A[i-1]+1;
        for (int t = 6; t <= i; t*=6) {
            mi=min(A[i-t]+1,mi);
        }
        for (int s = 9; s <= i; s*=9) {
            mi=min(A[i-s]+1,mi);
        }
        A[i]=mi;
    }

    cout << A[n];
}


int main() {
#ifdef debug
    freopen("/home/joduskame/Desktop/cp/IO/Input.txt", "r", stdin);
    freopen("/home/joduskame/Desktop/cp/IO/Output.txt", "w", stdout);
#endif

    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    _();
    return 0;

}








Measured memory_bytes: 640