<p>You are given two numeric strings <code>num1</code> and <code>num2</code> and two integers <code>max_sum</code> and <code>min_sum</code>. We denote an integer <code>x</code> to be <em>good</em> if:</p>

<ul>
	<li><code>num1 &lt;= x &lt;= num2</code></li>
	<li><code>min_sum &lt;= digit_sum(x) &lt;= max_sum</code>.</li>
</ul>

<p>Return <em>the number of good integers</em>. Since the answer may be large, return it modulo <code>10<sup>9</sup> + 7</code>.</p>

<p>Note that <code>digit_sum(x)</code> denotes the sum of the digits of <code>x</code>.</p>

<p>&nbsp;</p>
<p><strong class="example">Example 1:</strong></p>

<pre>
<strong>Input:</strong> num1 = &quot;1&quot;, num2 = &quot;12&quot;, <code>min_sum</code> = 1, max_sum = 8
<strong>Output:</strong> 11
<strong>Explanation:</strong> There are 11 integers whose sum of digits lies between 1 and 8 are 1,2,3,4,5,6,7,8,10,11, and 12. Thus, we return 11.
</pre>

<p><strong class="example">Example 2:</strong></p>

<pre>
<strong>Input:</strong> num1 = &quot;1&quot;, num2 = &quot;5&quot;, <code>min_sum</code> = 1, max_sum = 5
<strong>Output:</strong> 5
<strong>Explanation:</strong> The 5 integers whose sum of digits lies between 1 and 5 are 1,2,3,4, and 5. Thus, we return 5.
</pre>

<p>&nbsp;</p>
<p><strong>Constraints:</strong></p>

<ul>
	<li><code>1 &lt;= num1 &lt;= num2 &lt;= 10<sup>22</sup></code></li>
	<li><code>1 &lt;= min_sum &lt;= max_sum &lt;= 400</code></li>
</ul>

MOD = int(1e9+7)


@cache
def cnt_ints_mx(digits: int, mx: int) -> int:
    if mx == 0 or digits == 0:
        return 1

    digits -= 1
    return sum(cnt_ints_mx(digits, _mx) for _mx in range(mx, max(mx-10, -1), -1))


def cnt_ints_rng(digits: int, mn: int, mx: int) -> int:
    if digits < 0:
        return 0
    if mx < 0:
        return 0
    if mn < 1:
        return cnt_ints_mx(digits, mx)
    return cnt_ints_mx(digits, mx) - cnt_ints_mx(digits, mn-1)


class Solution:
    def count(self, num1: str, num2: str, min_sum: int, max_sum: int) -> int:
        n1 = tuple(map(int, reversed(num1)))
        n2 = tuple(map(int, reversed(num2)))
        ln1 = len(n1)
        ln2 = len(n2)

        if ln1 == ln2:
            i = ln1 - 1
            while n1[i] == n2[i] and i > 0:
                min_sum -= n1[i]
                max_sum -= n1[i]
                i -= 1
            ln1 = i + 1
            ln2 = i + 1

        cnt = cnt_ints_rng(ln2, min_sum, max_sum)

        mn, mx = min_sum, max_sum
        for i in range(ln1-1, -1, -1):
            for _ in range(n1[i]):
                cnt -= cnt_ints_rng(i, mn, mx)
                mn -= 1
                mx -= 1

        mn, mx = min_sum, max_sum
        for i in range(ln2-1, -1, -1):
            mn -= 9
            mx -= 9
            for _ in range(9, n2[i], -1):
                cnt -= cnt_ints_rng(i, mn, mx)
                mn += 1
                mx += 1

        return cnt % MOD

18000