//package CodeChef.LongChallenge.August2019;
import java.io.BufferedReader ;
import java.io.IOException ;
import java.io.InputStreamReader ;
import java.math.BigInteger ;
class Encoding {
static double POS = 100005 ;
static long [ ] [ ] [ ] DP = new long [ ( int ) POS] [ 10 ] [ 2 ] ;
static long MOD = 1000000000 + 7 ;
static long [ ] tenpow = new long [ ( int ) POS] ;
private static long digitDP
( int length,
String number,
int pos,
int of,
int prev
) { //prev = block continues or no! if ( pos == length)
return 0 ;
if ( DP[ pos] [ prev] [ of] != - 1 ) {
return DP[ pos] [ prev] [ of] ;
}
if ( prev > 0 && DP[ pos] [ 0 ] [ of] != - 1 ) {
long tp = tenpow[ length - ( pos + 1 ) ] ;
return DP[ pos] [ prev] [ of] = ( ( DP[ pos] [ 0 ] [ of] % MOD) - ( ( ( ( prev % MOD) * ( tp % MOD) ) % MOD) * ( tp % MOD) ) % MOD) % MOD;
}
int maxDigit = 9 ;
if ( of == 0 ) {
maxDigit = number.charAt ( pos) - 48 ;
}
long res = 0L;
for ( int dgt = 0 ; dgt <= maxDigit; dgt++ ) {
int nof = of;
if ( of == 0 && dgt < maxDigit) {
nof = 1 ;
}
res = ( ( res % MOD) + digitDP( length, number, pos + 1 , nof, dgt) % MOD) % MOD;
if ( prev != dgt) {
if ( nof == 1 ) {
long tp = tenpow[ length - ( pos + 1 ) ] ;
res = ( ( res % MOD) + ( ( ( ( dgt % MOD) * ( tp % MOD) ) % MOD) * ( tp % MOD) ) % MOD) % MOD;
} else {
long tp = tenpow[ length - ( pos + 1 ) ] ;
res = ( ( res % MOD) + ( ( ( ( dgt % MOD) * ( tp % MOD) ) % MOD) * ( getN( pos, number) % MOD) ) % MOD) % MOD;
}
}
// if (dgt == d) {
// if (prev == 0) {
// //((res % MOD) + ((d * tenpow[length - (pos + 1)]) % MOD)) % MOD;
// if (nof == 1) {
// long tp = tenpow[length - (pos + 1)];
// res = ((res % MOD) + ((((d % MOD) * (tp % MOD)) % MOD) * (tp % MOD)) % MOD) % MOD;
// } else {
// long tp = tenpow[length - (pos + 1)];
// res = ((res % MOD) + ((((d % MOD) * (tp % MOD)) % MOD) * (getN(pos, number) % MOD)) % MOD) % MOD;
// }
// }
// }
}
return DP[ pos] [ prev] [ of] = res;
}
private static long getN
( int pos,
String number
) { if ( pos == number.length ( ) - 1 ) {
return 1 ;
}
return bigInteger.
mod ( BigInteger .
valueOf ( MOD
) ) .
longValue ( ) + 1 ; }
private static long solve
( int length,
String number
) { for ( int i = 0 ; i < POS; i++ ) {
for ( int j = 0 ; j < 10 ; j++ ) {
DP[ i] [ j] [ 0 ] = - 1 ; DP[ i] [ j] [ 1 ] = - 1 ;
}
}
long ans = digitDP( length, number, 0 , 0 , 0 ) % MOD;
return ans;
}
private static void calculateTenPow( ) {
long calc = 1 ;
tenpow[ 0 ] = 1 ;
for ( int i = 1 ; i < ( int ) POS; i++ ) {
calc = ( ( calc % MOD) * 10 ) % MOD;
tenpow[ i] = calc;
}
}
int T
= Integer .
parseInt ( bufferedReader.
readLine ( ) ) ; calculateTenPow( ) ;
while ( T-- > 0 ) {
String [ ] input1
= bufferedReader.
readLine ( ) .
split ( " " ) ; int lnum1
= Integer .
parseInt ( input1
[ 0 ] ) ; String [ ] input2
= bufferedReader.
readLine ( ) .
split ( " " ) ; int lnum2
= Integer .
parseInt ( input2
[ 0 ] ) ; System .
out .
println ( ( MOD
+ solve
( lnum2, num2
) - solve
( lnum1, bigInteger1.
toString ( ) ) ) % MOD
) ; }
}
}
Ly9wYWNrYWdlIENvZGVDaGVmLkxvbmdDaGFsbGVuZ2UuQXVndXN0MjAxOTsKCmltcG9ydCBqYXZhLmlvLkJ1ZmZlcmVkUmVhZGVyOwppbXBvcnQgamF2YS5pby5JT0V4Y2VwdGlvbjsKaW1wb3J0IGphdmEuaW8uSW5wdXRTdHJlYW1SZWFkZXI7CmltcG9ydCBqYXZhLm1hdGguQmlnSW50ZWdlcjsKCmNsYXNzIEVuY29kaW5nIHsKCiAgICBzdGF0aWMgZG91YmxlIFBPUyA9IDEwMDAwNTsKICAgIHN0YXRpYyBsb25nW11bXVtdIERQID0gbmV3IGxvbmdbKGludClQT1NdWzEwXVsyXTsKICAgIHN0YXRpYyBsb25nIE1PRCA9IDEwMDAwMDAwMDAgKyA3OwogICAgc3RhdGljIGxvbmdbXSB0ZW5wb3cgPSBuZXcgbG9uZ1soaW50KVBPU107CgogICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBkaWdpdERQKGludCBsZW5ndGgsIFN0cmluZyBudW1iZXIsIGludCBwb3MsIGludCBvZiwgaW50IHByZXYpIHsgLy9wcmV2ID0gYmxvY2sgY29udGludWVzIG9yIG5vIQogICAgICAgIGlmIChwb3MgPT0gbGVuZ3RoKQogICAgICAgICAgICByZXR1cm4gMDsKCiAgICAgICAgaWYgKERQW3Bvc11bcHJldl1bb2ZdICE9IC0xKSB7CiAgICAgICAgICAgIHJldHVybiBEUFtwb3NdW3ByZXZdW29mXTsKICAgICAgICB9CgogICAgICAgIGlmIChwcmV2ID4gMCAmJiBEUFtwb3NdWzBdW29mXSAhPSAtMSkgewogICAgICAgICAgICBsb25nIHRwID0gdGVucG93W2xlbmd0aCAtIChwb3MgKyAxKV07CiAgICAgICAgICAgIHJldHVybiBEUFtwb3NdW3ByZXZdW29mXSA9ICgoRFBbcG9zXVswXVtvZl0gJSBNT0QpIC0gKCgoKHByZXYgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICUgTU9EOwogICAgICAgIH0KCiAgICAgICAgaW50IG1heERpZ2l0ID0gOTsKCiAgICAgICAgaWYgKG9mID09IDApIHsKICAgICAgICAgICAgbWF4RGlnaXQgPSBudW1iZXIuY2hhckF0KHBvcykgLSA0ODsKICAgICAgICB9CgogICAgICAgIGxvbmcgcmVzID0gMEw7CgogICAgICAgIGZvciAoaW50IGRndCA9IDA7IGRndCA8PSBtYXhEaWdpdDsgZGd0KyspIHsKICAgICAgICAgICAgaW50IG5vZiA9IG9mOwogICAgICAgICAgICBpZiAob2YgPT0gMCAmJiBkZ3QgPCBtYXhEaWdpdCkgewogICAgICAgICAgICAgICAgbm9mID0gMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmVzID0gKChyZXMgJSBNT0QpICsgZGlnaXREUChsZW5ndGgsIG51bWJlciwgcG9zICsgMSwgbm9mLCBkZ3QpICUgTU9EKSAlIE1PRDsKCiAgICAgICAgICAgIGlmIChwcmV2ICE9IGRndCkgewogICAgICAgICAgICAgICAgaWYgKG5vZiA9PSAxKSB7CiAgICAgICAgICAgICAgICAgICAgbG9uZyB0cCA9IHRlbnBvd1tsZW5ndGggLSAocG9zICsgMSldOwogICAgICAgICAgICAgICAgICAgIHJlcyA9ICgocmVzICUgTU9EKSArICgoKChkZ3QgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICUgTU9EOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBsb25nIHRwID0gdGVucG93W2xlbmd0aCAtIChwb3MgKyAxKV07CiAgICAgICAgICAgICAgICAgICAgcmVzID0gKChyZXMgJSBNT0QpICsgKCgoKGRndCAlIE1PRCkgKiAodHAgJSBNT0QpKSAlIE1PRCkgKiAoZ2V0Tihwb3MsIG51bWJlcikgJSBNT0QpKSAlIE1PRCkgJSBNT0Q7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCi8vICAgICAgICAgICAgaWYgKGRndCA9PSBkKSB7Ci8vICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IDApIHsKLy8gICAgICAgICAgICAgICAgICAgIC8vKChyZXMgJSBNT0QpICsgKChkICogdGVucG93W2xlbmd0aCAtIChwb3MgKyAxKV0pICUgTU9EKSkgJSBNT0Q7Ci8vICAgICAgICAgICAgICAgICAgICBpZiAobm9mID09IDEpIHsKLy8gICAgICAgICAgICAgICAgICAgICAgICBsb25nIHRwID0gdGVucG93W2xlbmd0aCAtIChwb3MgKyAxKV07Ci8vICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gKChyZXMgJSBNT0QpICsgKCgoKGQgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICUgTU9EOwovLyAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHsKLy8gICAgICAgICAgICAgICAgICAgICAgICBsb25nIHRwID0gdGVucG93W2xlbmd0aCAtIChwb3MgKyAxKV07Ci8vICAgICAgICAgICAgICAgICAgICAgICAgcmVzID0gKChyZXMgJSBNT0QpICsgKCgoKGQgJSBNT0QpICogKHRwICUgTU9EKSkgJSBNT0QpICogKGdldE4ocG9zLCBudW1iZXIpICUgTU9EKSkgJSBNT0QpICUgTU9EOwovLyAgICAgICAgICAgICAgICAgICAgfQovLyAgICAgICAgICAgICAgICB9Ci8vICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgcmV0dXJuIERQW3Bvc11bcHJldl1bb2ZdID0gcmVzOwoKICAgIH0KCiAgICBwcml2YXRlIHN0YXRpYyBsb25nIGdldE4oaW50IHBvcywgU3RyaW5nIG51bWJlcikgewogICAgICAgIGlmIChwb3MgPT0gbnVtYmVyLmxlbmd0aCgpIC0gMSkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgQmlnSW50ZWdlciBiaWdJbnRlZ2VyID0gbmV3IEJpZ0ludGVnZXIobnVtYmVyLnN1YnN0cmluZyhwb3MgKyAxKSk7CiAgICAgICAgcmV0dXJuIGJpZ0ludGVnZXIubW9kKEJpZ0ludGVnZXIudmFsdWVPZihNT0QpKS5sb25nVmFsdWUoKSArIDE7CiAgICB9CgogICAgcHJpdmF0ZSBzdGF0aWMgbG9uZyBzb2x2ZShpbnQgbGVuZ3RoLCBTdHJpbmcgbnVtYmVyKSB7CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBQT1M7IGkrKykgewogICAgICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IDEwOyBqKyspIHsKICAgICAgICAgICAgICAgIERQW2ldW2pdWzBdID0gLTE7IERQW2ldW2pdWzFdID0gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgbG9uZyBhbnMgPSBkaWdpdERQKGxlbmd0aCwgbnVtYmVyLCAwLCAwLCAwKSAlIE1PRDsKICAgICAgICByZXR1cm4gYW5zOwogICAgfQoKICAgIHByaXZhdGUgc3RhdGljIHZvaWQgY2FsY3VsYXRlVGVuUG93KCkgewogICAgICAgIGxvbmcgY2FsYyA9IDE7CiAgICAgICAgdGVucG93WzBdID0gMTsKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IChpbnQpUE9TOyBpKyspIHsKICAgICAgICAgICAgY2FsYyA9ICgoY2FsYyAlIE1PRCkgKiAxMCkgJSBNT0Q7CiAgICAgICAgICAgIHRlbnBvd1tpXSA9IGNhbGM7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgQnVmZmVyZWRSZWFkZXIgYnVmZmVyZWRSZWFkZXIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKFN5c3RlbS5pbikpOwogICAgICAgIGludCBUID0gSW50ZWdlci5wYXJzZUludChidWZmZXJlZFJlYWRlci5yZWFkTGluZSgpKTsKICAgICAgICBjYWxjdWxhdGVUZW5Qb3coKTsKICAgICAgICB3aGlsZSAoVC0tID4gMCkgewogICAgICAgICAgICBTdHJpbmdbXSBpbnB1dDEgPSBidWZmZXJlZFJlYWRlci5yZWFkTGluZSgpLnNwbGl0KCIgIik7CiAgICAgICAgICAgIGludCBsbnVtMSA9IEludGVnZXIucGFyc2VJbnQoaW5wdXQxWzBdKTsKICAgICAgICAgICAgU3RyaW5nIG51bTEgPSBpbnB1dDFbMV07CiAgICAgICAgICAgIFN0cmluZ1tdIGlucHV0MiA9IGJ1ZmZlcmVkUmVhZGVyLnJlYWRMaW5lKCkuc3BsaXQoIiAiKTsKICAgICAgICAgICAgaW50IGxudW0yID0gSW50ZWdlci5wYXJzZUludChpbnB1dDJbMF0pOwogICAgICAgICAgICBTdHJpbmcgbnVtMiA9IGlucHV0MlsxXTsKICAgICAgICAgICAgQmlnSW50ZWdlciBiaWdJbnRlZ2VyID0gbmV3IEJpZ0ludGVnZXIobnVtMSk7CiAgICAgICAgICAgIEJpZ0ludGVnZXIgYmlnSW50ZWdlcjEgPSBiaWdJbnRlZ2VyLnN1YnRyYWN0KEJpZ0ludGVnZXIuT05FKTsKICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKChNT0QgKyBzb2x2ZShsbnVtMiwgbnVtMikgLSBzb2x2ZShsbnVtMSwgYmlnSW50ZWdlcjEudG9TdHJpbmcoKSkpICUgTU9EKTsKICAgICAgICB9CiAgICB9Cn0=