#include <bits/stdc++.h>
using namespace std;
#define null NULL
#define mp make_pair
#define pb(a) push_back(a)
#define sz(a) ((int)(a).size())
#define all(a) a.begin() , a.end()
#define fi first
#define se second
#define relaxMin(a , b) (a) = min((a),(b))
#define relaxMax(a , b) (a) = max((a),(b))
#define SQR(a) ((a)*(a))
#define PI 3.14159265358979323846
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef long long ll;

const ll MAX_VAL = 1E9;

// Modular operations
const int MOD = 1E9 + 7;

int Add(int a, int b, int m = MOD){
  a += b;
  if(a >= m) a -= m;
  return a;
}

int Sub(int a, int b, int m = MOD){
  a -= b;
  if(a < 0) a += m;
  return a;
}

int AddTo(int& to, int w, int m = MOD){
  to += w;
  if(to >= m) to -= m;
  return to;
}

int SubTo(int& to, int w, int m = MOD){
  to -= w;
  if(to < 0) to += m;
  return to;
}

int Mult(int a, int b, int m = MOD){
  return (a * 1LL * b) % m;
}

int Pow(int a, ll deg, int m = MOD){
  int res = 1 % m;
  for(;deg > 0;deg >>= 1, a = Mult(a, a, m))
    if(deg & 1) res = Mult(res, a, m);
  return res;
}
// </end>

int S;

ll DivFloor(ll c, ll z){
  ll r = c / z;
  while(r * z > c) --r;
  while((r + 1) * z <= c) ++r;
  return r;
}

ll DivCeil(ll c, ll z){
  ll r = c / z;
  while(r * z < c) ++r;
  while((r - 1) * z >= c) --r;
  return r;
}

ll _Gcd(ll a, ll b){
  if(a < b) swap(a, b);
  if(a == b + 1) return 1;

  while(b) a %= b, swap(a, b);
  return a;
}

void Gcd(ll a, ll b, ll& ca, ll& cb){
  if(a + 1 == b){
    ca = -1, cb = 1;
    return;
  }
  if(a == b + 1){
    ca = 1, cb = -1;
    return;
  }

  if(b == 0) ca = 1, cb = 0;
  else {
    ll d = a / b;
    Gcd(b, a - b * d, cb, ca);
    cb -= d * ca;
  }
}

pair<ll, ll> SolveEq(ll a, ll b){
  ll x, y;
  Gcd(a, b, x, y);
  return mp(x, y);
}

int Count(ll a, ll b, ll how,
          ll max_a, ll max_b){
  ll gcd = _Gcd(a, b);
  if(how % gcd != 0) return 0;

  ll da = b / gcd;
  ll db = a / gcd;

  auto coef = SolveEq(a, b);
  ll ca = coef.fi * (how / gcd);
  ll cb = coef.se * (how / gcd);

  ll plo = max(DivCeil(1-ca, da), DivCeil(cb - max_b, db));
  ll phi = min(DivFloor(cb - 1, db), DivFloor(max_a - ca, da));

  if(plo > phi) return 0;
  return (phi - plo + 1) % MOD;
}

ll HowByLen(int len){
  ll res = 9;
  while(len > 1){
    res *= 10;
    if(res > MAX_VAL) return res;
    --len;
  }
  return res;
}

int HowByLenExact(int len){
  return Mult(9, Pow(10, len - 1));
}

int main(){
  cin >> S;
  //S = 100000000;
  int ans = 0;

  for(int i = 1;i * i <= S;++i)
    if(S % i == 0){
      vi del = {i};
      if(i * i != S) del.pb(S / i);
      for(int d : del){
        int take = S / d;
        if(take <= HowByLen(d))
          AddTo(ans, Sub(HowByLenExact(d), take - 1));
      }
    }

  for(int i = 1;i <= min(S, 100000);++i){
    AddTo(ans, Count(i, i + 1, S,
                     HowByLen(i), HowByLen(i + 1)));
  }
  for(int i = 100001;i <= S;++i){
    ll xy = S / i;
    ll y = S - xy * i;
    if(0 < y && y < xy){
      //AddTo(ans, Count(i, i + 1, S,
      //                 HowByLen(i), HowByLen(i + 1)));
      AddTo(ans, 1);
    }
  }

  for(int l = 1;l <= 10;++l)
    for(int r = l + 2;r <= 10;++r){
      ll left = S;
      for(int i = l + 1;i < r;++i){
        left -= HowByLen(i) * i;
        if(left < 0) break;
      }
      if(left <= 0) continue;
      AddTo(ans, Count(l, r, left,
                       HowByLen(l), HowByLen(r)));
    }

  cout << ans << '\n';

  return 0;
}


Measured memory_bytes: 256