#include <bits/stdc++.h>
// iostream is too mainstream
#include <cstdio>
// bitch please
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <cmath>
#include <iomanip>
#include <time.h>
#define dibs reserve
#define OVER9000 1234567890
#define ALL_THE(CAKE,LIE) for(auto LIE =CAKE.begin(); LIE != CAKE.end(); LIE++)
#define tisic 47
#define soclose 1e-8
#define chocolate win
// so much chocolate
#define patkan 9
#define ff first
#define ss second
#define abs(x) (((x) < 0)?-(x):(x))
#define uint unsigned int
#define dbl long double
#define pi 3.14159265358979323846
using namespace std;
// mylittledoge

using cat = long long;

#ifdef DONLINE_JUDGE
	// palindromic tree is better than splay tree!
	#define lld I64d
#endif

cat gcd(cat x, cat y) {
	if(x > y) swap(x, y);
	return (x == 0) ? y : gcd(y%x, x);
}

cat pw(cat a, cat e, cat mod) {
	if(e <= 0) return 1;
	cat x = pw(a, e/2, mod);
	x = (x * x) % mod;
	if(e&1) x = (x * a) % mod;
	return x;
}

int main() {
	cin.sync_with_stdio(0);
	cin.tie(0);
	cout << fixed << setprecision(10);
	cat S;
	cin >> S;
	cat ans = 0, mod = 1000000007;
	// l+1 < r
	for(cat l = 0, pwl = 1; 9*pwl <= S; l++, pwl *= 10)
		for(cat r = l, pwr = pwl; r <= S; r++, pwr *= 10) if(l+1 < r) {
			cat s = S, pw_cur = pwl;
			for(int k = l+1; k < r; k++) {
				pw_cur *= 10;
				s -= 9*pw_cur * (k+1);
				if(s < 0) break;
			}
			if(s < 0) break;
			cat A = l+1, B = r+1;
			cat g = gcd(A, B);
			A /= g, B /= g;
			if(s%g != 0) continue;
			s /= g;
			cat bl = 1, ar = 1;
			while(bl < A && (s-bl*B)%A != 0) bl++;
			while(ar < B && (s-ar*A)%B != 0) ar++;
			if(bl > A || ar > B || bl*B > s || ar*A > s) continue;
			cat br = (s-ar*A)/B, al = (s-bl*B)/A;
			bl += A*(max(0LL, al-9*pwl)/B);
			al -= B*(max(0LL, al-9*pwl)/B);
			while(al > 9*pwl) bl += A, al -= B;
			if(9*pwr < bl) continue;
			ar += B*(max(0LL, br-9*pwr)/A);
			br -= A*(max(0LL, br-9*pwr)/A);
			while(br > 9*pwr) br -= A, ar += B;
			if(9*pwl < ar) continue;
			if(br <= 0 && al <= 0 && bl > br) continue;
			ans += ((br-bl)/A+1) % mod;
		}
	for(cat d = 1; d*d <= S; d++) if(S%d == 0) {
		cat l = d-1;
		cat pw0 = 1;
		if(l <= 17) for(int i = 0; i < l; i++) pw0 *= 10;
		if(l > 17 || S/d <= 9*pw0) ans += (9*pw(10, l, mod)+1-S/d) % mod;
		if(S/d != d) {
			l = S/d-1;
			cat pw0 = 1;
			if(l <= 17) for(int i = 0; i < l; i++) pw0 *= 10;
			if(l > 17 || d <= 9*pw0) ans += (9*pw(10, l, mod)+1-d) % mod;
		}
	}
	cat maxl = 0;
	for(cat l = 0; l*l <= max(16LL*16, S); l++) {
		maxl = l;
		// a*(l+1)+b*(l+2) == S
		cat bl = S%(l+1), ar = (-S)%(l+2);
		if(bl <= 0) bl += l+1;
		if(ar <= 0) ar += l+2;
		if(bl*(l+2) > S || ar*(l+1) > S) continue;
		cat br = (S-ar*(l+1))/(l+2), al = (S-bl*(l+2))/(l+1);
		if(l <= 16) {
			cat pwl = 1;
			for(int i = 0; i < l; i++) pwl *= 10;
			ar += (l+2) * (max(0LL, br-90*pwl)/(l+1));
			br -= (l+1) * (max(0LL, br-90*pwl)/(l+1));
			while(br > 90*pwl) br -= l+1, ar += l+2;
			if(9*pwl < ar) continue;
			bl += (l+1) * (max(0LL, al-9*pwl)/(l+2));
			al -= (l+2) * (max(0LL, al-9*pwl)/(l+2));
			while(al > 9*pwl) bl += l+1, al -= l+2;
			if(90*pwl < bl) continue;
		}
		if(al <= 0 || br <= 0 || br < bl) continue;
		ans += ((br-bl)/(l+1)+1) % mod;
	}
	for(cat sab = 1; sab*(maxl+1) <= S; sab++) {
		cat br = min(sab, S-sab*(maxl+1))-1;
		cat rem = (br-S) % sab;
		if(rem < 0) rem += sab;
		br -= rem;
		cat bl = S%sab;
		if(bl == 0) bl += sab;
		if(br >= bl) ans += ((br-bl)/sab+1) % mod;
	}
	ans %= mod;
	if(ans < 0) ans += mod;
	cout << ans << "\n";
	return 0;}

// look at my code
// my code is amazing


Measured memory_bytes: 256