#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


enum Type{
	FULL_MATCH,
	ELSE,
};

ll length,POW[16];
ll num_array[20];
ll memo[18][2]; //memo[初めてG数が成立した桁数][先頭桁から、Nと数が一致し続けているか] = 残りの桁を埋める場合の数
//ll dp[18][1000][5][2]; //dp[桁数][pre_num][パターンと一致している文字の数][先頭からNと数が一致し続けているか] = 場合の数
ll dp[18][10][5][2];

ll getNUM(ll pre_num,ll next){
	//return (10*pre_num+next)%1000;
	return next;
}

ll recursive(ll pre_num,ll digit,Type type, ll pattern_match_num){

	if(pattern_match_num == 4){ //digit-1桁目でG数が成立した場合

		return memo[digit-1][type]; //残りの桁を埋める場合の数をreturn
	}

	if(digit == length)return 0; //G数が成立しないならreturn 0;

	if(dp[digit][pre_num][pattern_match_num][type] != -1){
		return dp[digit][pre_num][pattern_match_num][type]; //計算済ならreturn
	}

	ll ret = 0;
	ll limit;
	if(type == FULL_MATCH){
		limit = num_array[digit]-1;
	}else{
		limit = 9;
	}

	for(int next = 0; next <= limit; next++){
		switch(pattern_match_num){
		case 0:
			if(next == 5){
				ret += recursive(getNUM(pre_num,next),digit+1,ELSE,1);
			}else{
				ret += recursive(getNUM(pre_num,next),digit+1,ELSE,0);
			}
			break;
		case 1:
			if(next == 1){
				ret += recursive(getNUM(pre_num,next),digit+1,ELSE,2);
			}else{
				if(next == 5){
					ret += recursive(getNUM(pre_num,next),digit+1,ELSE,1);
				}else{
					ret += recursive(getNUM(pre_num,next),digit+1,ELSE,0);
				}
			}
			break;
		case 2:
			ret += recursive(getNUM(pre_num,next),digit+1,ELSE,3);
			break;
		case 3:
			if(next == 3){
				ret += recursive(getNUM(pre_num,next),digit+1,ELSE,4);
			}else{

				if(next == 5){
					ret += recursive(getNUM(pre_num,next),digit+1,ELSE,1);
				}else{
					if(pre_num == 5 && next == 1){ //★★コーナーケース★★
						ret += recursive(getNUM(pre_num,next),digit+1,ELSE,2);
					}else{
						ret += recursive(getNUM(pre_num,next),digit+1,ELSE,0);
					}
				}
			}
			break;
		}
	}

	if(type == FULL_MATCH){
		switch(pattern_match_num){
		case 0:
			if(num_array[digit] == 5){
				ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,1);
			}else{
				ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,0);
			}
			break;
		case 1:
			if(num_array[digit] == 1){
				ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,2);
			}else{
				if(num_array[digit] == 5){
					ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,1);
				}else{
					ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,0);
				}
			}
			break;
		case 2:
			ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,3);
			break;
		case 3:
			if(num_array[digit] == 3){
				ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,4);
			}else{
				if(num_array[digit] == 5){
					ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,1);
				}else{
					if(pre_num == 5 && num_array[digit] == 1){ //★★コーナーケース★★
						ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,2);
					}else{
						ret += recursive(getNUM(pre_num,num_array[digit]),digit+1,FULL_MATCH,0);
					}
				}
			}
			break;
		}
	}
	return dp[digit][pre_num][pattern_match_num][type] = ret;
}


int main(){

	for(int i = 0; i < 16; i++){ //最速の成立は3桁目(0オリジン) よって、最大残桁は14
		POW[i] = pow(10,i);
	}

	ll N;
	scanf("%lld",&N);

	if(N <= 5102){
		printf("0\n");
		return 0;
	}

	stack<ll> S;

	ll tmp = N;

	//Nを桁別に分解する
	while(tmp > 0){
		S.push(tmp%10);
		tmp /= 10;
	}

	ll index = 0;

	while(!S.empty()){
		num_array[index++] = S.top();
		S.pop();
	}

	length = index;
	int rest_digit;

	//先頭からの一致がfalseの場合のmemoを埋める
	for(int digit = 3; digit <= length-1; digit++){
		rest_digit = length-(digit+1);
		memo[digit][ELSE] = POW[rest_digit];
	}

	//先頭からの一致がtrueの場合のメモを埋める
	for(int digit = 3; digit <= length-1; digit++){
		rest_digit = length-(digit+1);
		memo[digit][FULL_MATCH] = (N%POW[rest_digit])+1; //+1は末尾0の分
	}

	for(int digit = 0; digit <= length-1; digit++){
		//for(int pre_num = 0; pre_num <= 999; pre_num++){
		for(int pre_num = 0; pre_num <= 9; pre_num++){
			for(int match_num = 0; match_num <= 4; match_num++){
				for(int p = 0; p <= 1; p++)dp[digit][pre_num][match_num][p] = -1;
			}
		}
	}

	printf("%lld\n",recursive(0,0,FULL_MATCH,0));

	return 0;
}



Measured memory_bytes: 3392