#include #include #include #include #include #include using namespace std; struct DigitDP { using Func=function; vector funcs; vector ubs; size_t size, n; int64_t mod; vector dp; DigitDP(int64_t mod): size(2), mod(mod) {} void add_func(size_t ub, const Func &&func) { size *= ub; ubs.push_back(ub); funcs.push_back(func); } void store(const string &number) { n = number.length(); dp.assign(size*(n+1), 0); dp[0]=1; vector indices(funcs.size()); for (size_t pos=0; pos &dp, vector &indices, size_t depth=0 ) { if (depth == funcs.size()) { size_t ub=tight? 9:(number[pos]-'0'); for (size_t d=0; d<=ub; ++d) { size_t next=pos+1, prev=pos; (next <<= 1) |= (tight || d < ub); (prev <<= 1) |= tight; for (size_t i=0; i pair count_up(Satisfies satisfies) { vector indices(funcs.size()); pair res; count_up(indices, satisfies, res); return res; } template void count_up( vector &indices, Satisfies satisfies, pair &res, size_t depth=0 ) { if (depth == indices.size()) { if (!satisfies(indices)) return; size_t lt=(n<<1), eq=(n<<1|1); for (size_t i=0; isize_t { return k || d == 3; }); d.add_func(3, [](size_t l, size_t d)->size_t { return (l + d) % 3; }); d.add_func(8, [](size_t m, size_t d)->size_t { return (m * 10 + d) % 8; }); int64_t res=0; auto satisfies=[](const vector &v)->bool { return (v[0] || v[1] == 0) && v[2] != 0; }; d.store(B); res += d.count_up(satisfies).second; d.store(A); res -= d.count_up(satisfies).first; return (res += mod) % mod; } int main() { string A, B; { char tmp[16384]; scanf("%s", tmp); A = tmp; scanf("%s", tmp); B = tmp; } printf("%lld\n", count(A, B)); return 0; }