// Arup Guha
// 11/14/2012
// Solution to 2012 South East Regional (D1) Problem I: Unhappy Numbers

import java.util.*;

public class i {
	
	// Highest sum of squares of digits of the input.
	public final static int MAXSUM = 18*81;
	
	public static void main(String[] args) {
		
		Scanner stdin = new Scanner(System.in);
	
		// For each number from 1 to MAXSUM, we store 1 in here if it loops forever, 0 otherwise.	
		int[] bruteforce = getBF();
		
		long[][][] table = new long[18][10][MAXSUM+1];
		
		// This table will store the number of values less than (d+1)*10^pow whose sum of squares adds to sum
		// in index table[pow][d][sum].
		for (int i=1; i<10; i++) {
			for (int j=0; j<i; j++) {
				table[0][i][(j+1)*(j+1)] = 1;
				table[0][i][0] = 1;
			}
		}
		
		// This is important for base cases!!!
		table[0][0][0] = 1;
				
		// Fill table.	
		for (int power=1; power<table.length; power++) {
			
			for (int digit=0; digit<10; digit++) {
				for (int sum=0; sum<=MAXSUM; sum++) {
					
					// Basically, for the current count, if the number is 3..., add everything from 2... plus
					// force a 3 in the first spot and add everything else that adds to sum - 3*3.
					if (digit > 0) {
						if (sum >= digit*digit)
							table[power][digit][sum] = table[power][digit-1][sum] + table[power-1][9][sum-digit*digit];
							
						// Here, we can't used digit, so just take the answer from the previous entry...
						else
							table[power][digit][sum] = table[power][digit-1][sum];
					}
					
					// These store the same thing...
					else
						table[power][digit][sum] = table[power-1][9][sum];
				
				}
			}
		}
		
		long low = stdin.nextLong();
		long high = stdin.nextLong();
		
		// Process all cases!
		while (low != 0) {
			System.out.println(solve(high+1, table, bruteforce) - solve(low, table, bruteforce));
			low = stdin.nextLong();
			high = stdin.nextLong();
		}
	}
	
	// Solve the problem using the table and the brute force answers.
	public static long solve(long bound, long[][][] table, int[] bf) {
		
		String s = "" + bound;
		int len = s.length();
		
		long ans = 0;
		
		// Iterate through the number from left to right.
		int processed = 0;
		for (int i=len-1, j=0; i>=0; i--,j++) {
			
			// Use this digit.
			int digit = (int)(s.charAt(j) - '0');
			
			// Screen out the sums that loop, and add the number of items less than 300000 (if digit is 3)
			// that would loop because they reduce to this sum. As we fix digits at the left of our number
			// subtract this out of the sum we are trying to reach.
			for (int k=processed; k<bf.length; k++) 
				if (bf[k] == 1 && digit > 0) 
					ans = ans + table[i][digit-1][k-processed];
				
			// Add in the contribution of this digit.
			processed += (digit*digit);
		}
		
		return ans;
	}
	
	// This will be our lookup chart for small unhappy and happy numbers.
	public static int[] getBF() {
		
		int[] ans = new int[MAXSUM+1];
		
		// These don't loop...
		ans[0] = 0;
		ans[1] = 0;
		
		// This isn't efficient, but it should do...
		for (int i=2; i<ans.length; i++)
			ans[i] = search(i);
		
		return ans;
	}
	
	// Return 1 if val is unhappy, 0 if it's happy.
	public static int search(int val) {
		
		// This is to detect a loop.
		boolean[] reached = new boolean[MAXSUM+1];
		reached[val] = true;
		
		while (true) {
			
			val = getSum(val);
		
			// This is the end.
			if (val == 1)
				return 0;
				
			// This is a loop.
			if (reached[val])
				return 1;
				
			// Mark that we've been here.
			else
				reached[val] = true;
		}
		
	}
	
	// Returns the sum of the digits of val
	public static int getSum(int val) {
		
		long sum = 0;
		while (val > 0) {
			sum = sum + (val%10)*(val%10);
			val /= 10;
		}
		return (int)sum;
	}
	
}