<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>

class Solution:
    M = 1000000007

    def add(self, x, y) -> int:
        x += y
        if x >= self.M:
            x -= self.M
        return x

    def sub(self, x, y) -> int:
        x -= y
        if x < 0:
            x += self.M
        return x

    def count_strings(self, s, min_sum, max_sum) -> int:
        n = len(s)
        m = min(max_sum, 9 * n)
        dp = [[[0 for _ in range(m + 1)] for _ in range(2)] for _ in range(2)]
        dp[0][0][0] = 1
        last = 0
        for i in range(n):
            p = i * 9
            now = last ^ 1
            dp[now] = [[0 for _ in range(m + 1)] for _ in range(2)]
            for j in range(2):
                for k in range(min(m, p) + 1):
                    if dp[last][j][k] == 0:
                        continue
                    for c in range(ord('9') if j else ord(s[i]), ord('0') - 1, -1):
                        q = k + c - ord('0')
                        if q <= m:
                            dp[now][j or (c < ord(s[i]))][q] = self.add(
                                dp[now][j or (c < ord(s[i]))][q], dp[last][j][k]
                            )
            last ^= 1
        r = 0
        for i in range(2):
            for j in range(min_sum, m + 1):
                r = self.add(r, dp[last][i][j])
        return r

    def count(self, num1, num2, min_sum, max_sum) -> int:
        s = sum(int(c) for c in num1)
        r = self.count_strings(num2, min_sum, max_sum)
        r = self.sub(r, self.count_strings(num1, min_sum, max_sum))
        if min_sum <= s <= max_sum:
            r = self.add(r, 1)
        return r
387