#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <vector>
#include <list>
#include <algorithm>
#include <functional>
#include <map>
#include <set>
#include <cstring>
#include <string>
#include <cctype>
#include <cassert>
#include <queue>
#include <unordered_set>
#include <unordered_map>

using namespace std;

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define rep(i,n) for(int i = 0; i < (n); i++)
#define repr(i,b,e) for(int i = (b); i <= (e); i++)
#define INF (1001001001)
#define EPS (1e-12)

#define pr(x) do{cerr << (#x) << " = " << (x) << endl;}while(0)
#define pri(x,i) do{cerr << (#x) << "[" << i << "] = " << (x[i]) << endl;}while(0)
#define pra(x) do{rep(__i,(x).size()) pri(x,__i);}while(0)
#define pran(x,n) do{rep(__i,n) pri(x,__i);}while(0)
#define pral(x) do{cerr << (#x) << " =";rep(__i,(x).size()) cerr<<" "<<(x[__i]);cerr<<endl;}while(0)
#define prar(x,b,e) do{repr(__i,b,e) pri(x,__i);}while(0)

typedef long long ll;
typedef pair<int, int> pint;
typedef vector<int> vint;
typedef vector<pint> vpint;

template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {os<<"{"; rep(i,t.size()) {os<<t[i]<<",";} os<<"}"<<endl; return os;}
template<class T,size_t n> ostream& operator<<(ostream &os, const array<T,n> &t) {os<<"{"; rep(i,n) {os<<t[i]<<",";} os<<"}"<<endl; return os;}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
template<class T> inline bool CHMAX(T &l,const T &r){return l<r?l=r,1:0;}
template<class T> inline bool CHMIN(T &l,const T &r){return l>r?l=r,1:0;}

ll MOD = 1000000007;

function<void(int,int)> tensi_no_3p=[&](int v,int d){
};

int in() {
	int a;
	scanf("%d ", &a);
	return a;
}

std::vector<int> enum_div(int n)//nの約数を列挙
{
	std::vector<int> ret;
	for(int i=1 ; i*i<=n ; ++i)
	{
		if(n%i == 0)
		{
			ret.push_back(i);
			if(i*i!=n)
			{
				ret.push_back(n/i);
			}
		}
	}
	return ret;
}

ll tenpowermod(ll x) {
	ll ret = 1;
	ll prod = 10;
	while (x > 0) {
		if (x % 2) ret = ret * prod % MOD;
		prod = prod * prod % MOD;
		x /= 2;
	}
	return ret;
}

int main() {
	ll S = in();
	ll sq = (ll)(sqrt(S) + EPS);
	ll ans = 0;
	
	// 2つ以上またぎ
	ll r = 1, sum = 0;
	for (int i = 1;; i++) {
		if ((r * 9 + 2) * i > S) break;
		sum = (r * 9 + 2) * i;
		r *= 10;
	}
	pr(r);
	pr(sum);
	ll l = r / 10 - 1;
	ll orig = l;
	if (l > 0) {
		while (sum < S) {
			if (l == 1) break;
			l--;
			sum += log10(l + .1) + 1;
		}
		for (; l <= orig;) {
			if (sum == S) ans++;
			if (sum <= S) {
				r++;
				int gain = log10(r + .1) + 1;
				sum += gain;
			}
			else {
				int loss = log10(l + .1) + 1;
				l++;
				sum -= loss;
			}
		}
		
		r = orig + 1;
		l = r / 10 - 1;
		if (l > 0) {
			orig = r * 10;
			ll origL = l;
			sum = log10(r + .1) * (r - l + 1);
			while (sum < S) {
				if (l == 1) break;
				l--;
				sum += log10(l + .1) + 1;
			}
			for (; l <= origL && r < orig;) {
				if (sum == S) ans++;
				if (sum <= S) {
					r++;
					int gain = log10(r + .1) + 1;
					sum += gain;
				}
				else {
					int loss = log10(l + .1) + 1;
					l++;
					sum -= loss;
				}
			}
		}
	}
	ans %= MOD;
	pr(ans);
	
	vector<ll> tenp(14);
	tenp[0] = 1;
	repr(i, 1, 13) tenp[i] = tenp[i-1] * 10;
	
	// 0つまたぎ
	vint divs = enum_div(S);
	for (ll d : divs) {
		if (d >= 9 || tenp[d] - tenp[d-1] - S / d + 1 >= 1) {
			ll temp = tenpowermod(d) - tenpowermod(d - 1) - S / d + 1;
			while (temp < 0) temp += MOD;
			ans = (ans + temp) % MOD;
		}
	}
	
	pr(r);
	
	// 1つまたぎ
	int ub = min(S, 20000000ll);
	pr(ub);
	for (ll k = 1; k <= ub; k++) {
		ll y = (S - 1) / k;
		if (k * (y + 1) <= S) continue;
		if (y >= 9) ans++;
		else if (k * (y + 1) - S <= tenp[y] - tenp[y - 1] && S - k * y <= tenp[y + 1] - tenp[y]) ans++;
	}
	ans %= MOD;
	cout << ans << endl;
	return 0;
}


Measured memory_bytes: 512