#include <bits/stdc++.h>
template <typename T>
struct ScanfSpecifier {};
template <>
struct ScanfSpecifier<char*> {
  static constexpr const char* value = "%s";
};
template <>
struct ScanfSpecifier<int> {
  static constexpr const char* value = "%d";
};
template <>
struct ScanfSpecifier<double> {
  static constexpr const char* value = "%lf";
};
template <>
struct ScanfSpecifier<float> {
  static constexpr const char* value = "%f";
};
template <>
struct ScanfSpecifier<char> {
  static constexpr const char* value = "%c";
};
template <>
struct ScanfSpecifier<const char*> {
  static constexpr const char* value = "%s";
};
template <>
struct ScanfSpecifier<unsigned long> {
  static constexpr const char* value = "%lu";
};
template <>
struct ScanfSpecifier<unsigned int> {
  static constexpr const char* value = "%u";
};
template <>
struct ScanfSpecifier<long long int> {
  static constexpr const char* value = "%lld";
};
template <typename T>
int RD(T& arg) {
  return std::scanf(ScanfSpecifier<T>::value, &arg);
}
template <int S>
int RD(char (&arg)[S]) {
  return std::scanf("%s", arg);
}
int RD(char* arg) { return std::scanf("%s", arg); }
template <>
int RD<char>(char& arg) {
  return std::scanf(" %c", &arg);
}
template <typename T, typename... Args>
int RD(T& arg1, Args&... args) {
  return RD(arg1) + RD(args...);
}
template <typename T>
T RD() {
  T ret;
  RD(ret);
  return ret;
}
template <typename It>
void RDV(It begin, It end) {
  while (begin != end) RD(*begin++);
}
template <typename C>
void RDV(C& c) {
  RDV(std::begin(c), std::end(c));
}
template <typename T>
void WT(T arg) {
  std::printf(ScanfSpecifier<T>::value, arg);
}
template <typename T, typename U>
void WT(std::pair<T, U> arg) {
  std::printf("(");
  WT(arg.first);
  std::printf(", ");
  WT(arg.second);
  std::printf(")");
}
template <typename... Args>
void WT(Args... args) {
  int alc = 0;
  int dummy[] = {((alc++ ? std::printf(" ") : 0), WT(args), 0)...};
}
template <typename... Args>
void WTL(Args... args) {
  WT(args...);
  std::printf("\n");
}
template <typename It>
void WTV(It begin, It end) {
  int alc = 0;
  while (begin != end) (alc++ ? std::printf(" ") : 0), WT(*begin++);
}
template <typename C>
void WTV(const C& c) {
  WTV(std::begin(c), std::end(c));
}
template <typename It>
void WTVL(It begin, It end) {
  WTV(begin, end);
  std::printf("\n");
}
template <typename C>
void WTVL(const C& c) {
  WTVL(std::begin(c), std::end(c));
}
struct Range {
  struct It {
    int num, step;
    int operator*() { return num; }
    void operator++() { num += step; }
    bool operator!=(const It& other) { return num != other.num; }
  };
  Range(int ee) : b(0), e(ee) {}
  Range(int bb, int ee) : b(bb), e(ee) {}
  It begin() { return {b, (b < e ? 1 : -1)}; }
  It end() { return {e, 0}; }
  int b, e;
};
template <typename T>
inline T& UMAX(T& x, T y) {
  if (x < y) x = y;
  return x;
}
template <typename T>
inline T& UMIN(T& x, T y) {
  if (y < x) x = y;
  return x;
}
template <typename T, typename... Args>
struct ArithmiticPromotion {
  typedef decltype(T() + typename ArithmiticPromotion<Args...>::type()) type;
};
template <typename T, typename U>
struct ArithmiticPromotion<T, U> {
  typedef decltype(T() + U()) type;
};
template <typename T>
struct ArithmiticPromotion<T, T> {};
template <typename T>
struct ArithmiticPromotion<T> {};
template <typename T, typename U>
typename ArithmiticPromotion<T, U>::T MAX(T a, U b) {
  return a < b ? b : a;
}
template <typename T, typename... Args>
typename ArithmiticPromotion<T, Args...>::T MAX(T a, Args... args) {
  return MAX(a, MAX(args...));
}
template <typename T, typename U>
typename ArithmiticPromotion<T, U>::T MIN(T a, U b) {
  return a < b ? a : b;
}
template <typename T, typename... Args>
typename ArithmiticPromotion<T, Args...>::T MIN(T a, Args... args) {
  return MIN(a, MIN(args...));
}
using RG = Range;
using namespace std;
char L[32], R[32];
void pad(char* s) {
  int l = strlen(s);
  reverse(s, s + l);
  for (int i : RG(l, 19)) s[i] = '0';
  reverse(s, s + 19);
  for (int i : RG(19)) s[i] -= '0';
}
long long int ans;
int num[10];
void dfs(int pos, int r, int total) {
  if (pos < 10) {
    for (int i = 0; i <= r; i++) {
      num[pos] = i;
      dfs(pos + 1, r - i, total + i);
    }
  } else {
    {
      bool check = true;
      int use = 0;
      bool b = false;
      int tmp[10] = {};
      int mn = 1;
      for (int i = 0; i < 19; i++) {
        while (mn < 10 && tmp[mn] == num[mn]) mn++;
        if (!b) {
          for (int d = L[i] + 1; d < R[i]; d++)
            if ((!d || tmp[d] + 1 <= num[d]) && use + 19 - i - !d >= total) {
              ans++;
              return;
            }
        } else if (R[i]) {
          if (use + 19 - i - 1 >= total ||
              (mn < R[i] && use + 19 - i >= total)) {
            ans++;
            return;
          }
        }
        if (R[i]) {
          ++use;
          if (++tmp[R[i]] > num[R[i]]) {
            check = false;
            break;
          }
        }
        if (L[i] < R[i]) b = true;
      }
      if (check && use == total) {
        ans++;
        return;
      }
    }
    {
      bool check = true;
      int use = 0;
      bool b = false;
      int tmp[10] = {};
      int mx = 9;
      for (int i = 0; i < 19; i++) {
        while (mx > 0 && tmp[mx] == num[mx]) mx--;
        if (!b) {
          for (int d = L[i] + 1; d < R[i]; d++)
            if (tmp[d] + 1 <= num[d] && use + 19 - i - !d >= total) {
              ans++;
              return;
            }
        } else {
          if (mx > L[i] && use + 19 - i >= total) {
            ans++;
            return;
          }
        }
        if (L[i]) {
          ++use;
          if (++tmp[L[i]] > num[L[i]]) {
            check = false;
            break;
          }
        }
        if (L[i] < R[i]) b = true;
      }
      if (check && use == total) {
        ans++;
        return;
      }
    }
  }
}
int main() {
  RD(L, R);
  pad(L), pad(R);
  dfs(1, 18, 0);
  WTL(ans);
}
