import java.util.*;

public class Euler305 {

    static class Op {
        byte[] endState;
        long[] addCount;

        Op(byte[] endState, long[] addCount) {
            this.endState = endState;
            this.addCount = addCount;
        }

        @Override
        public boolean equals(Object obj) {
            Op other = (Op) obj;
            return Arrays.equals(endState, other.endState) && Arrays.equals(addCount, other.addCount);
        }

        @Override
        public int hashCode() {
            int h = 1;
            for (byte b : endState)
                h = 31 * h + b;
            for (long c : addCount)
                h = 31 * h + (int) (c ^ (c >>> 32));
            return h;
        }
    }

    static class PatternEngine {
        String pattern;
        int L;

        int[][] nextState;
        byte[][] out;

        List<Op> ops = new ArrayList<>();
        Map<Op, Integer> opToId = new HashMap<>();

        int idIdentity = -1;
        int[] digitOpId = new int[10];

        Map<Long, Integer> composeCache = new HashMap<>();
        Map<Long, Integer> appendCache = new HashMap<>();
        Map<Long, Integer> fullBlockCache = new HashMap<>();

        long[] pow10 = new long[21];

        PatternEngine(String pattern) {
            this.pattern = pattern;
            this.L = pattern.length();
            nextState = new int[L + 1][10];
            out = new byte[L + 1][10];

            buildAutomaton();
            buildDigitOperators();

            pow10[0] = 1;
            for (int i = 1; i <= 20; ++i) {
                pow10[i] = pow10[i - 1] * 10L;
            }
        }

        long makeKey(int a, int b) {
            return (((long) a) << 32) | (b & 0xFFFFFFFFL);
        }

        int internOp(Op op) {
            Integer id = opToId.get(op);
            if (id != null)
                return id;
            int newId = ops.size();
            ops.add(op);
            opToId.put(op, newId);
            return newId;
        }

        void buildAutomaton() {
            int[] pi = new int[L];
            for (int i = 1; i < L; ++i) {
                int j = pi[i - 1];
                while (j > 0 && pattern.charAt(i) != pattern.charAt(j)) {
                    j = pi[j - 1];
                }
                if (pattern.charAt(i) == pattern.charAt(j)) {
                    j++;
                }
                pi[i] = j;
            }

            for (int st = 0; st <= L; ++st) {
                for (int d = 0; d < 10; ++d) {
                    char c = (char) ('0' + d);
                    int j = st;
                    while (j > 0 && (j == L || pattern.charAt(j) != c)) {
                        j = pi[j - 1];
                    }
                    if (j < L && pattern.charAt(j) == c) {
                        j++;
                    }
                    if (j == L) {
                        out[st][d] = 1;
                        j = pi[L - 1];
                    }
                    nextState[st][d] = j;
                }
            }
        }

        void buildDigitOperators() {
            byte[] es = new byte[L + 1];
            long[] ac = new long[L + 1];
            for (int s = 0; s <= L; ++s)
                es[s] = (byte) s;
            idIdentity = internOp(new Op(es, ac));

            for (int d = 0; d < 10; ++d) {
                byte[] esd = new byte[L + 1];
                long[] acd = new long[L + 1];
                for (int s = 0; s <= L; ++s) {
                    esd[s] = (byte) nextState[s][d];
                    acd[s] = out[s][d];
                }
                digitOpId[d] = internOp(new Op(esd, acd));
            }
        }

        int composeIds(int idA, int idB) {
            long key = makeKey(idA, idB);
            Integer cached = composeCache.get(key);
            if (cached != null)
                return cached;

            Op A = ops.get(idA);
            Op B = ops.get(idB);

            byte[] CEs = new byte[L + 1];
            long[] CAc = new long[L + 1];

            for (int s = 0; s <= L; ++s) {
                int mid = A.endState[s];
                CEs[s] = B.endState[mid];
                CAc[s] = A.addCount[s] + B.addCount[mid];
            }

            int id = internOp(new Op(CEs, CAc));
            composeCache.put(key, id);
            return id;
        }

        int appendDigit(int opId, int d) {
            long key = makeKey(opId, d);
            Integer cached = appendCache.get(key);
            if (cached != null)
                return cached;
            int id = composeIds(opId, digitOpId[d]);
            appendCache.put(key, id);
            return id;
        }

        int fullBlock(int prefixOp, int remDigits) {
            long key = makeKey(prefixOp, remDigits);
            Integer cached = fullBlockCache.get(key);
            if (cached != null)
                return cached;

            int id;
            if (remDigits == 0) {
                id = prefixOp;
            } else {
                int res = idIdentity;
                for (int d = 0; d < 10; ++d) {
                    int child = fullBlock(appendDigit(prefixOp, d), remDigits - 1);
                    res = composeIds(res, child);
                }
                id = res;
            }
            fullBlockCache.put(key, id);
            return id;
        }

        int partialBlock(int prefixOp, int remDigits, long upperSuffix) {
            if (remDigits == 0)
                return prefixOp;

            long base = pow10[remDigits - 1];
            int first = (int) (upperSuffix / base);
            long rest = upperSuffix % base;

            int res = idIdentity;
            for (int d = 0; d < first; ++d) {
                int child = fullBlock(appendDigit(prefixOp, d), remDigits - 1);
                res = composeIds(res, child);
            }

            int last = partialBlock(appendDigit(prefixOp, first), remDigits - 1, rest);
            res = composeIds(res, last);
            return res;
        }

        int rangeOperator(long N) {
            if (N == 0)
                return idIdentity;

            String s = String.valueOf(N);
            int D = s.length();
            int res = idIdentity;

            for (int d = 1; d < D; ++d) {
                int rem = d - 1;
                for (int a = 1; a < 10; ++a) {
                    int block = fullBlock(digitOpId[a], rem);
                    res = composeIds(res, block);
                }
            }

            int first = s.charAt(0) - '0';
            int rem = D - 1;
            for (int a = 1; a < first; ++a) {
                int block = fullBlock(digitOpId[a], rem);
                res = composeIds(res, block);
            }

            if (rem == 0) {
                res = composeIds(res, digitOpId[first]);
            } else {
                long suffix = Long.parseLong(s.substring(1));
                int part = partialBlock(digitOpId[first], rem, suffix);
                res = composeIds(res, part);
            }

            return res;
        }

        long[] occAndState(long N) {
            int opId = rangeOperator(N);
            Op op = ops.get(opId);
            return new long[] { op.addCount[0], op.endState[0] };
        }

        long digitsBefore(long N) {
            if (N == 0)
                return 0;

            String s = String.valueOf(N);
            int D = s.length();

            long total = 0;
            for (int d = 1; d < D; ++d) {
                total += 9L * pow10[d - 1] * d;
            }

            total += (N - pow10[D - 1] + 1) * D;
            return total;
        }

        long nthOccurrencePosition(long targetOccurrence) {
            long hi = 1;
            while (occAndState(hi)[0] < targetOccurrence) {
                hi *= 2;
            }

            long lo = 1;
            while (lo < hi) {
                long mid = lo + (hi - lo) / 2;
                if (occAndState(mid)[0] >= targetOccurrence) {
                    hi = mid;
                } else {
                    lo = mid + 1;
                }
            }

            long number = lo;
            long[] before = occAndState(number - 1);
            long beforeCount = before[0];
            int beforeState = (int) before[1];

            long needInside = targetOccurrence - beforeCount;
            long prefixDigits = digitsBefore(number - 1);

            long foundInside = 0;
            int state = beforeState;
            String numStr = String.valueOf(number);

            for (int i = 0; i < numStr.length(); ++i) {
                int d = numStr.charAt(i) - '0';
                if (out[state][d] != 0) {
                    foundInside++;
                    if (foundInside == needInside) {
                        long endPos = prefixDigits + i + 1;
                        return endPos - L + 1;
                    }
                }
                state = nextState[state][d];
            }

            return 0;
        }
    }

    public static String solve() {
        int kMax = 13;
        long sum = 0;
        long n = 1;
        for (int k = 1; k <= kMax; ++k) {
            n *= 3;
            PatternEngine engine = new PatternEngine(String.valueOf(n));
            sum += engine.nthOccurrencePosition(n);
        }
        return String.valueOf(sum);
    }

    public static void main(String[] args) {
        System.out.println(solve());
    }
}
