1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#include <bits/stdc++.h>
#include <unistd.h>
using namespace std;
#define REP(i,n) for(int _n=(n), i=0;i<_n;++i)
#define FOR(i,a,b) for(int i=(a),_b=(b);i<=_b;++i)
#define FORD(i,a,b) for(int i=(a),_b=(b);i>=_b;--i)
#define TRACE(x) cerr << "TRACE(" #x ")" << endl;
#define DEBUG(x) cerr << #x << " = " << (x) << endl;
typedef long long LL; typedef unsigned long long ULL;

const int LCM = 2520;
const int MAX_DIGITS = 19;

LL memo[MAX_DIGITS][2][LCM][(1 << 9) + 5];

vector<int> convertToDigits(LL x)
{
    vector<int> res;
    while (x)
    {
        res.emplace_back(x%10);
        x /= 10;
    }
    reverse(res.begin(), res.end());
    return res;
}

LL ileMniejszychOdZeZbioru(const vector<int> &originalDigits, int idx, int tight, int rem, int mask)
{
    LL& res = memo[idx][tight][rem][mask];
    //printf("idx=%d tight=%d rem=%d mask=%d\n", idx, tight, rem, mask);
 
    // Return the if result for the
    // current iteration is calculated
    if (res != -1) {
        return res;
    }

    res = 0;
    if (idx == originalDigits.size())
    {
        bool all = true;
        for (int d = 1; d < 10; d++) {
            if (mask & (1 << (d - 1))) {
                if (rem % d != 0) {
                    all = false;
                    break;
                }
            }
        }
       // printf("cnt=%d\n");
        res = all ? 1 : 0;
        return res;
    }

    for (int d=1; d <= 9; d++)
    {
        if (tight && (d > originalDigits[idx]))
        {
            continue;
        }
        int newTight = ((tight == 1) ? (d == originalDigits[idx]): 0);
        int newRem = (rem * 10 + d) % LCM;
        int newMask =  (mask | (1 << (d - 1)));
        res += ileMniejszychOdZeZbioru(originalDigits, idx + 1, newTight, newRem, newMask);
    }

    return res;
}

LL ileMniejszychOd(LL x)
{
    //printf("ileMniejszychOd %lld\n", x);
    if (x == 0)
    {
        return 0;
    }
    memset(memo, -1, sizeof(memo));

    auto digits = convertToDigits(x);
    LL res = 0;
    for (int i=0; i < digits.size(); i++)
    {
       int tight = i == 0 ? 1 : 0;
       //printf("calculating...\n");
       res += ileMniejszychOdZeZbioru(digits, i, tight, 0, 0);
    }
    // printf("%lld\n", res);
    return res;
}

LL solve(LL a, LL b)
{
    return ileMniejszychOd(b) - ileMniejszychOd(a-1);
}

int main() {
    LL a, b;

    int x = scanf("%lld%lld", &a, &b);
    printf("%lld\n", solve(a,b));
    return 0;
}