// eddy1021
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
#define mod9 1000000009LL
#define mod7 1000000007LL
#define mod 1000000007LL
#define INF  1023456789LL
#define INF16 10000000000000000LL
#define eps 1e-9
#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#define IOS ios_base::sync_with_stdio(0); cin.tie(0)
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else 
#define debug(...)
#endif
inline LL getint(){
  LL _x=0,_tmp=1; char _tc=getchar();    
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline LL add( LL _x , LL _y , LL _mod = mod7 ){
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline LL sub( LL _x , LL _y , LL _mod = mod7 ){
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline LL mul( LL _x , LL _y , LL _mod = mod7 ){
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
LL mypow( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 1LL;
  LL _ret = mypow( mul( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = mul( _ret , _a , _mod );
  return _ret;
}
LL mymul( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 0LL;
  LL _ret = mymul( add( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = add( _ret , _a , _mod );
  return _ret;
}
inline bool equal( D _x ,  D _y ){
  return _x > _y - eps && _x < _y + eps;
}
void sleep( double sec = 1021 ){
  clock_t s = clock();
  while( clock() - s < CLOCKS_PER_SEC * sec );
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/
#define K (1 << 20)
int fac[ K ] , ifac[ K ] , inv[ K ];
void build(){
  inv[ 0 ] = fac[ 0 ] = ifac[ 0 ] = 1;
  for( int i = 1 ; i < K ; i ++ )
    inv[ i ] = mypow( i , mod - 2 , mod );
  for( int i = 1 ; i < K ; i ++ ){
    fac[ i ] = mul( i , fac[ i - 1 ] );
    ifac[ i ] = mul( ifac[ i - 1 ] , inv[ i ] );
  }
}
int Inv( int x ){
  return x < K ? inv[ x ] : mypow( x , mod - 2 , mod );
}
int C( int a , int b ){
  if( a < b ) return 0;
  if( a < K )
    return mul( fac[ a ] , mul( ifac[ b ] , ifac[ a - b ] ) );
  if( a - b < b ) b = a - b;
  int ret = 1;
  for( int i = 0 ; i < b ; i ++ )
    ret = mul( ret , a - i );
  for( int i = 0 ; i < b ; i ++ )
    ret = mul( ret , Inv( b - i ) );
  return ret;
}
LL s;
void init(){
  cin >> s;
}
int ans;
inline int dgt( int x ){
  int ret = 0;
  while( x ){
    ret ++;
    x /= 10;
  }
  return ret;
}
set<LL> gt;
LL way( LL x ){
  if( x == 7 ) return 9000000LL;
  if( x == 8 ) return 90000000LL;
  if( x == 9 ) return 900000000LL;
  return 9000000000LL;
}
int choose( int a , int b ){
  return sub( mul( 9 , mypow( 10 , a - 1 , mod ) ) , (b - 1) );
}
void cal( LL sm ){
  if( sm < 7 ) return;
  if( gt.find( sm ) != gt.end() ) return;
  gt.insert( sm );
  LL b = s % sm;
  LL a = (s - b) / sm - b;
  LL way_a = way( sm );
  LL way_b = way( sm );
  if( a < 0 ) return;
  if( a > way_a and b > way_b ) return;
  if( b > way_b ) return;
  if( a > way_a ){
    LL dlt = a - way_a;
    LL nd = (dlt + sm) / (sm + 1);
    a -= nd * (sm + 1);
    b += nd * sm;
  }
  if( a <= 0 ) return;
  if( a > way_a and b > way_b ) return;
  if( b > way_b ) return;
  if( b == 0 ){
    ans = add( ans , choose( sm , a ) );
    a -= sm + 1;
    b += sm;
    if( a <= 0 ) return;
    if( a > way_a and b > way_b ) return;
    if( b > way_b ) return;
  }
  ans = add( ans , (a + sm) / (sm + 1) );
}
void solve(){
  LL sum = 0;
  for( int i = 1 , r = 1 ; i < 1000000 ; i ++ ){
    while( sum < s )
      sum += dgt( r ++ );
    if( sum == s )
      ans ++;
    sum -= dgt( i );
  }
  LL sqs = 1;
  while( sqs * sqs <= s ) sqs ++;
  sqs += 10;
  for( LL i = 7 ; i <= sqs ; i ++ )
    cal( i );
  for( LL i = 1 ; i <= sqs ; i ++ )
    cal( s / i );
  cout << ans << endl;
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}


Measured memory_bytes: 13440