/*input
1000
*/
#include <bits/stdc++.h>
using namespace std;
#define sp ' '
#define endl '\n'
#define fi first
#define se second
#define mp make_pair
#define N
// #define int long long
#define bit(x,y) ((x>>y)&1LL)
#define loop(i,l,r) for(int i=l; i<=r; i++)
#define see(x) {cout << x << endl;}
#define what_is(x) cerr << #x << " is " << x << endl;
#define error(args...) { string _s = #args; replace(_s.begin(), _s.end(), ',', ' '); stringstream _ss(_s); istream_iterator<string> _it(_ss); err(_it, args); }
void err(istream_iterator<string> it) {}
template<typename T, typename... Args>
void err(istream_iterator<string> it, T a, Args... args) {
    cerr << *it << " = " << a << endl;
    err(++it, args...);
}
template <class T1, class T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a) {
    return os << '(' << a.first << ", " << a.second << ')';
}
template <class T>
ostream &operator<<(ostream &os, const vector<T> &a) {
    os << '[';
    for (unsigned int i = 0; i < a.size(); i++)
        os << a[i] << (i < a.size() - 1 ? ", " : "");
    os << ']';
    return os;
}
template <class T>
ostream &operator<<(ostream &os, const set<T> &a) {
    os << '{';
    for (typename set<T>::iterator it = a.begin(); it != a.end(); it++) {
        typename set<T>::iterator jt = it;
        os << *it << (++jt != a.end() ? ", " : "");
    }
    os << '}';
    return os;
}
template <class T1, class T2>
ostream &operator<<(ostream &os, map<T1, T2> &a) {
    os << "{\n";
    for (typename map<T1, T2>::iterator it = a.begin(); it != a.end(); it++) {
        typename map<T1, T2>::iterator jt = it;
        os << "  " << it->first << ": " << it->second << (++jt != a.end() ? ",\n" : "\n");
    }
    os << '}';
    return os;
}

int S;


int gcd(int a , int b) {
    if (b == 0) return a;
    a %= b;
    return gcd(b, a);
}

const int mod = 1e9 + 7;
#define pow binPow
long long binPow(long long a, long long q) {
    long long ret = 1;
    for (int i = 0; (1LL << i) <= q; i++) {
        if (q & (1LL << i)) ret = (ret * a) % mod;
        a = (a * a) % mod;
    }
    return ret;
}

#define pow binPow
long long binPownomod(long long a, long long q) {
    long long ret = 1;
    for (int i = 0; (1LL << i) <= q; i++) {
        if (q & (1LL << i)) ret = (ret * a);
        a = (a * a);
    }
    return ret;
}


int numHasDig(int x) {
    return 1LL * 9 * binPow(10, x - 1) % mod;
}

int debugCal(int num1, int num2, int need) {
    int ret = 0;
    int lim1 = 1e9; int lim2 = 1e9;
    if (num1 <= 10) lim1 = 9 * binPownomod(10, num1 - 1);
    if (num2 <= 10) lim2 = 9 * binPownomod(10, num2 - 1);
    for (int i = 1; i <= lim1 && i * num1 <= need; i++) {
        int sub = need - i * num1;
        if (sub % num2) continue;
        int j = sub / num2;
        if (j == 0 || j > lim2) continue;
        ret++;
    }
    return ret;
}

// no need
int singleCal(int base) {
    int ret = S / base;
    if (base <= 10) {
        if (9 * binPownomod(10, base - 1) < ret) return 0;
    }
    return numHasDig(base) - ret + 1;
}

// deep optimize
int calBig(int base) {
    int All = S / base;
    int B = S % base;
    if (B > All) return 0;
    int ret = (All - B) / (base + 1) + 1;
    if (S % (base + 1) == 0) ret--;
    if (S % base == 0) ret--;
    return ret;
}

int findmin(int All, int B, int lcm, int base, int diff) {
    int l = 0, r = 1e8;
    while (l != r) {
        int mid = (l + r) / 2;
        int u = All - mid * lcm / base; int v = B + mid * lcm / diff;
        if ((u - v) > numHasDig(base)) l = mid + 1;
        else r = mid;
    }
    return l;
}

int findmax(int All, int B, int lcm, int base, int diff) {
    int l = 0, r = 1e8;
    while (l != r) {
        int mid = (l + r + 1) / 2;
        int u = All - mid * lcm / base; int v = B + mid * lcm / diff;
        if (u < v || v > numHasDig(base + diff)) r = mid - 1;
        else l = mid;
    }
    return l;
}

int calSmall(int base, int diff, int need) {
    int ret = 0;
    if (base > need) return ret;
    int B = -1; int All = -1;
    loop(i, 0, base - 1) {
        if ((need - i * diff) % base == 0) {
            All = (need - i * diff) / base;
            B = i;
            break;
        }
    }
    if (B == -1 || All < B || B > numHasDig(base + diff)) return ret;
    int gcdx = gcd(base, diff);
    int lcm = (base) * (diff) / gcdx;
    int mn = findmin(All, B, lcm, base, diff);
    int mx = findmax(All, B, lcm, base, diff);
    if (B + mn * lcm / diff == 0) mn++;
    if (All - mx * lcm / base == B + mx * lcm / diff) mx--;
    if (mx < mn) return 0;
    if (All - mn * lcm / base <= B + mn * lcm / diff) return 0;
    ret = (mx - mn + 1);
    return ret;
}

signed main() {
    ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    // ensure i j not empty
    // optimize full speed
    cin >> S;
    int ans = 0;
    loop(i, 1, S) {
        if (S % i != 0) continue;
        ans = (ans + singleCal(i));
        if (ans < 0) ans += mod;
        if (ans >= mod) ans -= mod;
    }

    loop(i, 10, S) {
        ans = (ans + calBig(i));
        if (ans >= mod) ans -= mod;
    }

    loop(i, 1, 9) {
        loop(j, i + 1, 10) {
            long long need = S;
            loop(k, i + 1, j - 1) {
                need -= k * 1LL * 9 * binPownomod(10, k - 1);
            }
            if (need < 0) break;
            ans += calSmall(i, j - i, need);
            ans %= mod;
        }
    }
    cout << ans << endl;

}

Measured memory_bytes: 256