/**
* Count total clap digits between two numbers a and b.
* Uses prefix sum technique: f(b) - f(a - 1)
* @param {number} a
* @param {number} b
* @returns {number}
*/
function countClapsInRange(a, b) {
if (a > b) return 0;
/**
* Count the total number of digits 3, 6, or 9 appearing in numbers from 1 to n.
* This uses Digit DP: digit-by-digit DFS + memoization.
*/
function countTotalClapsUpTo(n) {
const digits = n.toString();
const memo = new Map();
// Set of digits that represent a "clap" in the 369 game
const clapDigits = new Set([3, 6, 9]);
/**
* Recursive function to count claps digit by digit
* @param {number} digitIndex - Current digit position (from left to right)
* @param {number} clapCount - Number of clap digits seen so far
* @param {boolean} isLimited - True if current digit must not exceed original number
* @returns {number} - Total claps accumulated from this position onward
*/
function countClapsByDigit(digitIndex, clapCount, isLimited) {
// Use memoization to avoid recomputing overlapping sub problems
const memoKey = `${digitIndex},${clapCount},${isLimited}`;
if (memo.has(memoKey)) return memo.get(memoKey);
// Base case: reached the end of number
if (digitIndex === digits.length) return clapCount;
// Determine the highest digit can use at this position
const maxDigit = isLimited ? Number(digits[digitIndex]) : 9;
let total = 0;
// Try all possible digits at this position
for (let digit = 0; digit <= maxDigit; digit++) {
// If current digit == maxDigit and still limited, let remain limited
const nextIsLimited = isLimited && (digit === maxDigit);
// Add 1 to clap count if current digit is 3, 6, or 9
const nextClapCount = clapCount + (clapDigits.has(digit) ? 1 : 0);
// Recurse to next digit
total += countClapsByDigit(
digitIndex + 1,
nextClapCount,
nextIsLimited
);
}
// Memoize the result for this state
memo.set(memoKey, total);
return total;
}
// Start recursion from the first digit, with 0 clap digits, and tight constraint
return countClapsByDigit(0, 0, true);
}
return countTotalClapsUpTo(b) - countTotalClapsUpTo(a - 1);
}
let input = '';
process.stdin.on('data', function (chunk) {
input += chunk;
});
process.stdin.on('end', function () {
const lines = input.trim().split('\n');
for (const line of lines) {
const [a, b] = line.trim().split(/\s+/).map(Number);
console.log(countClapsInRange(a, b));
}
});