```go
package main
import (
"fmt"
)
var divisors []int
var lcmToIdx map[int]int
var nextLcm [10][48]int
var isValid [2520][48]bool
var numDiv int
func gcd(a, b int) int {
for b != 0 {
a, b = b, a%b
}
return a
}
func lcm(a, b int) int {
return a / gcd(a, b) * b
}
func init() {
for i := 1; i <= 2520; i++ {
if 2520%i == 0 {
divisors = append(divisors, i)
}
}
numDiv = len(divisors)
lcmToIdx = make(map[int]int, numDiv)
for idx, v := range divisors {
lcmToIdx[v] = idx
}
for d := 0; d <= 9; d++ {
for idx, val := range divisors {
if d == 0 {
nextLcm[d][idx] = idx
} else {
newL := lcm(val, d)
nextLcm[d][idx] = lcmToIdx[newL]
}
}
}
for mod := 0; mod < 2520; mod++ {
for idx, val := range divisors {
isValid[mod][idx] = (mod % val == 0)
}
}
}
func countBeautiful(x int64) int64 {
if x <= 0 {
return 0
}
s := fmt.Sprintf("%d", x)
digits := make([]int, len(s))
for i, c := range s {
digits[i] = int(c - '0')
}
n := len(digits)
memoSize := n * 2520 * numDiv
memo := make([]int64, memoSize)
for i := range memo {
memo[i] = -1
}
var dfs func(pos, mod, lcmIdx int, tight bool) int64
dfs = func(pos, mod, lcmIdx int, tight bool) int64 {
if pos == n {
if isValid[mod][lcmIdx] {
return 1
}
return 0
}
if !tight {
idx := pos*2520*numDiv + mod*numDiv + lcmIdx
if memo[idx] != -1 {
return memo[idx]
}
}
limit := 9
if tight {
limit = digits[pos]
}
var ans int64 = 0
for d := 0; d <= limit; d++ {
newMod := (mod*10 + d) % 2520
newLcmIdx := nextLcm[d][lcmIdx]
newTight := tight && d == limit
ans += dfs(pos+1, newMod, newLcmIdx, newTight)
}
if !tight {
idx := pos*2520*numDiv + mod*numDiv + lcmIdx
memo[idx] = ans
}
return ans
}
return dfs(0, 0, lcmToIdx[1], true) - 1
}
func main() {
var t int
fmt.Scan(&t)
for i := 0; i < t; i++ {
var l, r int64
fmt.Scan(&l, &r)
res := countBeautiful(r) - countBeautiful(l-1)
fmt.Println(res)
}
}
```