#include <iostream>
#include <stdio.h>
#include <stdlib.h> //rand() 0~RAND_MAX2147483647
#include <math.h>
#include <time.h>   //srand((unsigned int)time(NULL));
#include <unistd.h> //sleep
#include <algorithm>
#include <cmath>
#include <vector>
#include <regex> //正規表現
#include <map>
#include <unordered_map>
#include <set>
#include <cassert> //assart
#include <numeric>
#include <iterator>
#include <list>

using namespace std;
#define ll long long int
#define FOR(i,min,max) for(int i=(min);i<(max);i++)
#define FOReq(i,min,max) for(int i=(min);i<=(max);i++)
#define FORREV(i,max,min) for(int i=(max)-1;i>=(min);i--)
#define FORREVeq(i,max,min) for(int i=(max);i>=(min);i--)
const int MOD=1e9+7;
const int MOD2=998244353;
const int not0=1;
const int INF=2000000001;
const ll INFll=2e18;
//const int MAX_V=10000;
const double  Micro=1e-5;

int UnUsedVariable(){
    if(INF || Micro || MOD || INFll || MOD2 || not0){;}
    return 0;
}

#define pf printf
#define sf scanf
#define inarray(array,min,max) FOR(i,min,max){cin>>array[i];}
#define inarrayW(arrayA,arrayB,min,max) FOR(i,min,max){cin>>arrayA[i]>>arrayB[i];}
#define br printf("\n");
#define OutputAndReturn0(x) {cout<<(x)<<endl;return 0;}
#define elif else if

#define issame(a,b,c,d) ((a)==(b) and (b)==(c) and (c)==(d))
#define isdiff3(a,b,c) ((a)!=(b) and (b)!=(c) and (c)!=(a))
#define isdiff4(a,b,c,d) ((a)!=(b) and (b)!=(c) and (c)!=(a) and (d)!=(a) and (d)!=(b) and (d)!=(c))
#define Func3(f,a,b,c) (f)((f)((a),(b)),(c))
#define Func4(f,a,b,c,d) (f)((f)((f)((a),(b)),(c)),(d))

inline int isEven(int x){return x%2==0;}
inline int isOdd (int x){return x%2==1;}
inline ll  gcd(ll a,ll b){ if(b==0)return a;else return gcd(b,a%b);}//最大公約数 なお一方が0なら答えは他方になるので番兵は０で良い また、負の数もOK -4%3=-1となるため
inline ll  lcm(ll a,ll b){return a*b/gcd(a,b);}//MODやオーバーフローには注意！
//inline ll  ceil(double a){return (ll)a+1;}
//ans = accumulate(A, A+N, 0, [](int a, int b) {return gcd(a,b);});

//Eと名のつくのはデバッグ用！
int EintN(ll array[],const ll num){
    for(int i=0;i<num;i++){cerr<<array[i]<<" ";}
    br;
    return 0;
}
int EintNN(const int heighth,const int width,int array[heighth][width]){
    FOR(i, 0, heighth){
        FOR(k, 0, width){
            {cerr<<array[i][k]<<" ";}
        }
        br;
    }
    br;
    return 0;
}
int Eint(string str,const ll num){
    cerr<<str<<" is "<<num<<" now."<<endl;
    return 0;
}









string S;
ll DP[10][2][2][2][2]={};//digit,bind,3,5,7
ll doDP(int digit,int tight,int three,int five,int seven){
    
    if (DP[digit][tight][three][five][seven] >= 0) {
        return DP[digit][tight][three][five][seven];
    }
    
    // すべての桁を遷移したときに、条件xが成立する場合を数えます。
    // 今回の場合は、数に対する条件はなくすべての数を数えます。
    if (digit == S.length()) {
        return DP[digit][tight][three][five][seven] =min({three,five,seven});
    }
    
    // 現在着目している桁の数が何か
    int d = S[digit]-'0';
    
    // DP遷移
    ll ret = 0;
    
    // i-1桁までが元の数字とぴったり同じ場合は tight = 1 なので、dまで
    // そうでない場合は、任意の数字まで遷移できるので 9 まで
    for (int e = 0; e <= (tight == 1 ? d : 9); e++) {
        
        // 次の遷移を考える時、tightが1で今回選択しているeがもとの数字dと同じ場合は
        // ぴったり同じなのでtight = 1 そうでない場合は小さいので tight = 0
        if(not (isdiff4(e, 3, 5, 7))) ret += doDP(digit+1, tight == 1 && d == e,three || e==3,five || e==5,seven || e==7);
    }
    return DP[digit][tight][three][five][seven] = ret;
    
}

int prob(){
    ll ans;ans=0;
    
    FOR(a, 0, 10){
        FOR(b, 0, 2){
            FOR(c, 0, 2){
                FOR(d, 0, 2){
                    FOR(e, 0, 2){
                        DP[a][b][c][d][e]=-1;
                    }
                }
            }
        }
    }
    
    
    
    cin>>S;
    ans+=doDP(0,1,0,0,0);
    FOR(i, 1, S.length()){
        ans+=doDP(i,0,0,0,0);
    }
//    FOR(i, 0, 10){
//        cout<<i<<"  "<<DP[i][i==0][0][0][0]<<endl;
//    }
    OutputAndReturn0(ans);
    return 0;
}


signed main(){
    prob();
    return 0;
}


Measured memory_bytes: 256