/*
*/

//#pragma GCC optimize("O3")
#define _CRT_SECURE_NO_WARNINGS
#include <fstream>
#include <iostream>
#include <string>
#include <complex>
#include <math.h>
#include <set>
#include <vector>
#include <map>
#include <queue>
#include <stdio.h>
#include <stack>
#include <algorithm>
#include <list>
#include <ctime>

#include <memory.h>
#include <assert.h>

#define y0 sdkfaslhagaklsldk

#define y1 aasdfasdfasdf
#define yn askfhwqriuperikldjk
#define j1 assdgsdgasghsf
#define tm sdfjahlfasfh
#define lr asgasgash
#define norm asdfasdgasdgsd
#define have adsgagshdshfhds
#define ends asdgahhfdsfshdshfd

#define eps 1e-8
#define M_PI 3.141592653589793
#define bsize 512

#define ldouble long double
using namespace std;

#define bs 1000000007

const int N = 600031;

int n;
long long ans;

long long ttl;

long long total_digits_used(int len){
	long long ttl=9;
	for (int i=2;i<=len;i++)
		ttl=ttl*10;
	return ttl*len;
}

long long count_with(long long x){
	long long res=9;
	for (int i=2;i<=x;i++){
		res*=10;
	}
	return res;
}

long long naive_solver(long long fi,long long max_a,long long se,long long max_b,long long unused){
	long long res=0;
	long long nn=unused;
	for (int i=1;i<=max_a;i++){
		long long here=fi*i;
		long long rem=nn-here;
		if (rem>0&&rem%se==0&&rem/se<=max_b&&rem/se>0)
			++res;
	}
	return res;
}

int fuckin_smart_solver(int fi,int max_a,int se,int max_b,int unused){
	--max_a;
	--max_b;
	unused-=fi;
	unused-=se;
	if (unused<0)
		return 0;

	int REM=unused%se;
	int used_b=unused/se;

	if (REM!=0){
		REM=se-REM;
		used_b++;
	}

	int used_a=REM;

	used_b-=REM;

	if (used_b<0)
		return 0;
	if (used_a>max_a)
		return 0;

	//cout<<used_a<<" " <<used_b<<" "<<fi<<" "<<se<<" "<<max_a<<" "<<max_b<<endl;
	// + se* a, - fi*b
	int L=0;
	int R=used_b/fi;
	int should_sub=(used_b-max_b)/fi;
	if ((used_b-max_b)%fi)
		++should_sub;
	if (used_b>max_b)
		L=should_sub;
	R=min(R,(max_a-used_a)/se);
	if (R<L)return 0;
	return R-L+1;
}


int main(){
//	freopen("apache.in","r",stdin);
//	freopen("apache.out","w",stdout);
	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);
	ios_base::sync_with_stdio(0);
//	cin.tie(0);

	cin>>n;

	for (int fi=1;fi<=n;fi++){
		if (fi==1)
			ttl=9;
		else
			ttl=ttl*10%bs;
		for (int se=fi;se<=n;se++){
			if (se>9&&se>fi+1)
				break;
			if (fi==se&&n%fi!=0)
				continue;
			if (fi==se){ // easy case
				int span=n/fi;
				int ways=ttl-span+1;
				if (ways<0&&fi<9)
					continue;
				if (ways<0)
					ways+=bs;
				ans+=ways;
				ans%=bs;
				continue;
			}
			long long used_ib=0;
			for (int q=fi+1;q<se;q++){
				used_ib+=total_digits_used(q);
			}
			if (used_ib>n-fi-se)
				continue;
			// max shift now
			int rem=n-used_ib;
			int max_a,max_b;
			// a*fi+b*se=rem
			if (fi<10)
				max_a=ttl;
			else
				max_a=n;
			max_a=min(max_a,n);
			if (se<10)
				max_b=count_with(se);
			else
				max_b=n;
			max_b=min(max_b,n);
			if (fi+1<se){
				ans+=naive_solver(fi,max_a,se,max_b,rem);
				if (ans>=bs)
					ans-=bs;
			}
			else
			{
				ans+=fuckin_smart_solver(fi,max_a,se,max_b,rem);
//				ans%=bs;
				if (ans>=bs)
					ans-=bs;
				//long long here=fuckin_smart_solver(fi,max_a,se,max_b,rem);
				//long long othr=naive_solver(fi,max_a,se,max_b,rem);
				//cout<<fi<<" "<<max_a<<" "<<se<<" "<<max_b<<" "<<rem<<" "<<here<<" "<<othr<<endl;
//				ans+=naive_solver(fi,max_a,se,max_b,rem);
			}
		}
	}

	cout<<ans<<endl;

//	cin.get(); cin.get();
	return 0;
}


Measured memory_bytes: 384