//start of jonathanirvings' template v3.0.3 (BETA)

#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
typedef pair<string,string> pss;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<pii> vii;
typedef vector<LL> vl;
typedef vector<vl> vvl;

double EPS = 1e-9;
int INF = 1000000005;
long long INFF = 1000000000000000005LL;
double PI = acos(-1);
int dirx[8] = {-1,0,0,1,-1,-1,1,1};
int diry[8] = {0,1,-1,0,-1,1,-1,1};

#ifdef TESTING
  #define DEBUG fprintf(stderr,"====TESTING====\n")
  #define VALUE(x) cerr << "The value of " << #x << " is " << x << endl
  #define debug(...) fprintf(stderr, __VA_ARGS__)
#else
  #define DEBUG 
  #define VALUE(x)
  #define debug(...)
#endif

#define FOR(a,b,c) for (int (a)=(b);(a)<(c);++(a))
#define FORN(a,b,c) for (int (a)=(b);(a)<=(c);++(a))
#define FORD(a,b,c) for (int (a)=(b);(a)>=(c);--(a))
#define FORSQ(a,b,c) for (int (a)=(b);(a)*(a)<=(c);++(a))
#define FORC(a,b,c) for (char (a)=(b);(a)<=(c);++(a))
#define FOREACH(a,b) for (auto &(a) : (b))
#define REP(i,n) FOR(i,0,n)
#define REPN(i,n) FORN(i,1,n)
#define MAX(a,b) a = max(a,b)
#define MIN(a,b) a = min(a,b)
#define SQR(x) ((LL)(x) * (x))
#define RESET(a,b) memset(a,b,sizeof(a))
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define ALL(v) v.begin(),v.end()
#define ALLA(arr,sz) arr,arr+sz
#define SIZE(v) (int)v.size()
#define SORT(v) sort(ALL(v))
#define REVERSE(v) reverse(ALL(v))
#define SORTA(arr,sz) sort(ALLA(arr,sz))
#define REVERSEA(arr,sz) reverse(ALLA(arr,sz))
#define PERMUTE next_permutation
#define TC(t) while(t--)

inline string IntToString(LL a){
  char x[100];
  sprintf(x,"%lld",a); string s = x;
  return s;
}

inline LL StringToInt(string a){
  char x[100]; LL res;
  strcpy(x,a.c_str()); sscanf(x,"%lld",&res);
  return res;
}

inline string GetString(void){
  char x[1000005];
  scanf("%s",x); string s = x;
  return s;
}

inline string uppercase(string s){
  int n = SIZE(s); 
  REP(i,n) if (s[i] >= 'a' && s[i] <= 'z') s[i] = s[i] - 'a' + 'A';
  return s;
}

inline string lowercase(string s){
  int n = SIZE(s); 
  REP(i,n) if (s[i] >= 'A' && s[i] <= 'Z') s[i] = s[i] - 'A' + 'a';
  return s;
}

inline void OPEN (string s) {
  #ifndef TESTING
  freopen ((s + ".in").c_str (), "r", stdin);
  freopen ((s + ".out").c_str (), "w", stdout);
  #endif
}

//end of jonathanirvings' template v3.0.3 (BETA)

LL MOD = 1e9 + 7;
LL risan = 0;

void add(LL x)
{
  risan += x;
  risan %= MOD;
}

LL bigmod(LL a, LL b)
{
  if (b== 0) return 1;
  LL tmp = bigmod(a,b/2);
  LL tmp2 = tmp * tmp % MOD;
  if (b % 2 == 0) return tmp2;
  return tmp2 * a % MOD;
}

LL big(LL a,LL b)
{
  if (b== 0) return 1;
  LL tmp = big(a,b/2);
  LL tmp2 = tmp * tmp;
  if (b % 2 == 0) return tmp2;
  return tmp2 * a;
}

LL ada(int x)
{
  return 9 * bigmod(10, x - 1) % MOD;
}

LL adagakmod(int x)
{
  return 9 * big(10, x - 1);
}

LL hitung(int a, int goal)
{
  if (goal % a != 0) return 0;
  int tepat = goal / a;
  // VALUE(tepat);
  // VALUE(ada(a));
  // VALUE(ada(a)-tepat + 1 + MOD);
  if (a <= 12)
  {
    LL max_a = adagakmod(a);
    if (tepat > max_a) return 0;
  }
  return (ada(a) - tepat + 1 + MOD) % MOD;
}

LL x,y,d;

void extendedEuclid(LL a, LL b) {
  if (b == 0) { x = 1; y = 0; d = a; return; } 
  extendedEuclid(b, a % b);
  LL x1 = y;
  LL y1 = x - (a / b) * y;
  x = x1;
  y = y1; 
}

LL ceil(LL a,LL b)
{
  return (a + b - 1) / b;
}

int cnt = 0;
LL sum = 0;

LL hitung(int a,int b,int goal)
{
  // debug("%d %d %d\n",a,b,goal);
  LL max_a = goal / a;
  LL max_b = goal / b;
  if (a <= 12) MIN(max_a, adagakmod(a));
  if (b <= 12) MIN(max_b, adagakmod(b));
  LL coba = 0;
  // FORN(i,1,max_a) FORN(j,1,max_b) if(a*i + b*j == goal) ++coba;
  // return coba;

  LL GCD = b == a + 1 ? 1 : __gcd(a,b);
  if (goal % GCD != 0) {assert(coba == 0); return 0;}
  extendedEuclid(a,b);
  x *= goal / GCD;
  y *= goal / GCD;
  if (x <= 0)
  {
    LL butuh = ceil(llabs(x)+1,b/GCD);
    x += (b/GCD)*butuh;
    y -= (a/GCD)*butuh;
  }
  // x positif
  {
    LL butuh = (x - 1) / (b/GCD);
    x -= (b/GCD) * butuh;
    y += (a/GCD) * butuh;
  }
  // x positif terkecil
  if (y <= 0) {assert(coba == 0); return 0;}
  if (y > max_b)
  {
    LL butuh = ceil(y - max_b,a/GCD);
    x += (b/GCD) * butuh;
    y -= (a/GCD) * butuh;
  }
  if (x > max_a) {assert(coba == 0); return 0;}
  LL bisa = (max_a - x) / (b/GCD);
  MIN(bisa, (y-1) / (a/GCD));

  debug("%d %d %lld\n",a,b,bisa+1);
  ++cnt;
  sum = (sum + bisa + 1) % MOD;

  // debug("%lld %lld %d %d %d %lld\n",max_a,max_b,a,b,goal,bisa + 1);
  // debug("%lld %lld %d %lld %d %lld %lld\n",max_a,max_b,a,x,b,y,goal);

  // assert(bisa + 1 == coba);
  return bisa + 1;

  // if (x > max_a)
  // {

  // }
  // debug("%lld %lld %d %lld %d %lld %lld\n",max_a,max_b,a,x,b,y,goal);
  return 0;
}

int s;

int f(int x)
{
  int ret = 0;
  while (x > 0)
  {
    ret++;
    x/=10;
  }
  return ret;
}

int main()
{
  scanf("%d",&s);
  // int risan2 = 0;
  // FORN(i,1,100000000)
  // {
  //   int now = 0;
  //   FORN(j,i,100000000) 
  //   {
  //     now += f(j);
  //     if (now == s)
  //     {
  //       ++risan2;
  //       break;
  //     }
  //     if (now > s) break;
  //   }
  // }
  // VALUE(risan2);
  for (int i = 1; i * i <= s; ++i) if(s % i == 0)
  {
    add(hitung(i,s));
    if (s/i != i) add(hitung(s/i,s));
  }
  // VALUE(risan);
  // FORN(i,1,s/2) add(hitung(i,i+1,s));
  unordered_set<int> ss;
  if (s <= 1e7)
  {
    FORN(i,1,s/2) add(hitung(i,i+1,s));
  } else {
    FORN(i,1,s/2+2) 
    {
      ss.insert(max(1,min(s/2,s/i)));
      ss.insert(max(1,min(s/2,s/i-1)));
      // ss.insert(max(1,min(s/2,s/i+1)));
    }
    for (int i : ss) add(hitung(i,i+1,s));
  }
  // VALUE(risan);
  FORN(l,2,12)
  {
    if (l * adagakmod(l) > s) break;
    LL tot = 0;
    FORN(r,l,12)
    {
      tot += r * adagakmod(r);
      if (tot > s) break;
      add(hitung(l-1,r+1,s - tot));
    }
  }
  printf("%lld\n",risan);
  VALUE(cnt);
  VALUE(sum);
  return 0;
}











Measured memory_bytes: 1536