Everybody knows that lucky numbers are positive integers that contain only lucky digits 4 and 7 in their decimal representation. For example, numbers 47, 744, 4 are lucky and 5, 17, 467 are not.

Polo the Penguin have two positive integers l and r (l < r), both of them are lucky numbers. Moreover, their lengths (that is, the number of digits in the decimal representation without the leading zeroes) are equal to each other.

Let's assume that n is the number of distinct lucky numbers, each of them cannot be greater than r or less than l, and ai is the i-th (in increasing order) number of them. Find a1·a2 + a2·a3 + ... + an - 1·an. As the answer can be rather large, print the remainder after dividing it by 1000000007 (109 + 7).

Input

The first line contains a positive integer l, and the second line contains a positive integer r (1 ≤ l < r ≤ 10100000). The numbers are given without any leading zeroes.

It is guaranteed that the lengths of the given numbers are equal to each other and that both of them are lucky numbers.

Output

In the single line print a single integer — the answer to the problem modulo 1000000007 (109 + 7).

Examples

Input

4
7


Output

28


Input

474
777


Output

2316330
#include <bits/stdc++.h>
using namespace std;
namespace IO {
const int sz = 1 << 15;
char inbuf[sz], outbuf[sz];
char *pinbuf = inbuf + sz;
char *poutbuf = outbuf;
inline char _getchar() {
  if (pinbuf == inbuf + sz) fread(inbuf, 1, sz, stdin), pinbuf = inbuf;
  return *(pinbuf++);
}
inline void _putchar(char x) {
  if (poutbuf == outbuf + sz) fwrite(outbuf, 1, sz, stdout), poutbuf = outbuf;
  *(poutbuf++) = x;
}
inline void flush() {
  if (poutbuf != outbuf)
    fwrite(outbuf, 1, poutbuf - outbuf, stdout), poutbuf = outbuf;
}
}  // namespace IO
inline int read() {
  int x = 0, p = 1;
  char c = IO::_getchar();
  while (c < '0' || c > '9') {
    if (c == '-') p = -1;
    c = IO::_getchar();
  }
  while (c >= '0' && c <= '9') x = x * 10 + c - 48, c = IO::_getchar();
  return x * p;
}
namespace Mymath {
long long qp(long long x, long long p, long long mod) {
  long long ans = 1;
  while (p) {
    if (p & 1) ans = ans * x % mod;
    x = x * x % mod;
    p >>= 1;
  }
  return ans;
}
long long inv(long long x, long long mod) { return qp(x, mod - 2, mod); }
long long C(long long N, long long K, long long fact[], long long mod) {
  return fact[N] * inv(fact[K], mod) % mod * inv(fact[N - K], mod) % mod;
}
template <typename Tp>
Tp gcd(Tp A, Tp B) {
  if (B == 0) return A;
  return gcd(B, A % B);
}
template <typename Tp>
Tp lcm(Tp A, Tp B) {
  return A * B / gcd(A, B);
}
};  // namespace Mymath
namespace fwt {
using namespace Mymath;
void FWT(int a[], int n, long long mod) {
  for (int d = 1; d < n; d <<= 1)
    for (int m = d << 1, i = 0; i < n; i += m)
      for (int j = 0; j < d; j++) {
        int x = a[i + j], y = a[i + j + d];
        a[i + j] = (x + y) % mod, a[i + j + d] = (x - y + mod) % mod;
      }
}
void UFWT(int a[], int n, long long mod) {
  long long rev = inv(2, mod);
  for (int d = 1; d < n; d <<= 1)
    for (int m = d << 1, i = 0; i < n; i += m)
      for (int j = 0; j < d; j++) {
        int x = a[i + j], y = a[i + j + d];
        a[i + j] = 1LL * (x + y) * rev % mod,
              a[i + j + d] = (1LL * (x - y) * rev % mod + mod) % mod;
      }
}
void solve(int a[], int b[], int n, long long mod) {
  FWT(a, n, mod);
  FWT(b, n, mod);
  for (int i = 0; i < n; i++) a[i] = 1LL * a[i] * b[i] % mod;
  UFWT(a, n, mod);
}
};  // namespace fwt
namespace Maxflow {
const int Maxn = 1005;
struct edge {
  int to, rev, cap;
  edge(int _to, int _rev, int _cap) { to = _to, rev = _rev, cap = _cap; }
};
int src = 1002, snk = 1003;
vector<edge> G[Maxn];
int dist[Maxn], seen[Maxn];
int n;
void Clear() {
  for (int i = 0; i < Maxn; i++) G[i].clear();
}
void bfs(int s) {
  for (int i = 0; i < Maxn; i++) dist[i] = -1;
  dist[s] = 0;
  queue<int> Q;
  Q.push(s);
  while (!Q.empty()) {
    int x = Q.front();
    Q.pop();
    for (int i = 0; i < G[x].size(); i++) {
      edge &e = G[x][i];
      if (e.cap && dist[e.to] == -1) {
        dist[e.to] = dist[x] + 1;
        Q.push(e.to);
      }
    }
  }
}
int dfs(int now, int dest, int fl) {
  if (now == dest) return fl;
  for (int &i = seen[now]; i < G[now].size(); i++) {
    edge &ed = G[now][i];
    if (ed.cap && dist[ed.to] == dist[now] + 1) {
      int f = dfs(ed.to, dest, min(fl, ed.cap));
      if (f) {
        ed.cap -= f;
        G[ed.to][ed.rev].cap += f;
        return f;
      }
    }
  }
  return 0;
}
int dinic(int s = src, int t = snk) {
  int ret = 0;
  while (1) {
    memset(seen, 0, sizeof(seen));
    bfs(s);
    if (dist[t] == -1) return ret;
    int f = dfs(s, t, 2147483647);
    while (f) {
      ret += f;
      f = dfs(s, t, 2147483647);
    }
  }
}
};  // namespace Maxflow
namespace Geometry {
struct iP {
  long long x, y;
  iP(long long _x, long long _y) { x = _x, y = _y; }
  iP() { x = y = 0; }
  iP operator+(iP p) { return iP(x + p.x, y + p.y); }
  iP operator-(iP p) { return iP(x - p.x, y - p.y); }
  iP operator*(long long k) { return iP(x * k, y * k); }
  long long det(iP p) { return x * p.y - y * p.x; }
  long long dot(iP p) { return x * p.x + y * p.y; }
  long long dist() { return x * x + y * y; }
  bool operator<(const iP &p) const {
    if (x != p.x) return x < p.x;
    return y < p.y;
  }
};
struct dP {
  double x, y;
  dP(double _x, double _y) { x = _x, y = _y; }
  dP() { x = y = 0.0; }
  dP operator+(dP p) { return dP(x + p.x, y + p.y); }
  dP operator-(dP p) { return dP(x - p.x, y - p.y); }
  dP operator*(double k) { return dP(x * k, y * k); }
  double det(dP p) { return x * p.y - y * p.x; }
  double dot(dP p) { return x * p.x + y * p.y; }
  double dist() { return x * x + y * y; }
  bool operator<(const dP &p) const {
    if (x != p.x) return x < p.x;
    return y < p.y;
  }
};
vector<iP> convex_hull(iP X[], int l) {
  vector<iP> ret;
  sort(X + 1, X + 1 + l);
  ret.push_back(X[1]);
  for (int i = 2; i <= l; i++) {
    while (ret.size() >= 2 &&
           (ret[ret.size() - 2] - X[i]).det(ret[ret.size() - 1] - X[i]) >= 0) {
      ret.pop_back();
    }
    ret.push_back(X[i]);
  }
  int rs = ret.size() + 1;
  for (int i = l - 1; i >= 1; i--) {
    while (ret.size() >= rs &&
           (ret[ret.size() - 2] - X[i]).det(ret[ret.size() - 1] - X[i]) >= 0) {
      ret.pop_back();
    }
    ret.push_back(X[i]);
  }
  return ret;
}
};  // namespace Geometry
using namespace Mymath;
const int Maxn = 100005;
const long long mod = 1e9 + 7;
char tmp[Maxn];
long long p10[Maxn * 2], S[Maxn], S_2[Maxn];
int n;
struct lucky {
  int val[Maxn];
  lucky() { ; }
  void Plus() {
    for (int i = n - 1; i >= 0; i--) {
      if (val[i] == 4) {
        val[i] = 7;
        return;
      }
      val[i] = 4;
    }
  }
  void Minus() {
    for (int i = n - 1; i >= 0; i--) {
      if (val[i] == 7) {
        val[i] = 4;
        return;
      }
      val[i] = 7;
    }
  }
} L, R;
void _init() {
  p10[0] = 1;
  for (int i = 1; i < Maxn * 2; i++) {
    p10[i] = p10[i - 1] * 10 % mod;
  }
  S[0] = 0;
  for (int i = 1; i < Maxn; i++) {
    S[i] = S[i - 1] * 2 + p10[i - 1] * 11 % mod * qp(2, i - 1, mod) % mod;
    S[i] %= mod;
  }
  S_2[0] = 0;
  for (int i = 1; i < Maxn; i++) {
    S_2[i] = S_2[i - 1] * 2 + p10[2 * (i - 1)] * 65 % mod * qp(2, i - 1, mod) +
             22LL * p10[i - 1] % mod * S[i - 1];
    S_2[i] %= mod;
  }
}
long long Sqr(long long x) { return x * x % mod; }
long long sqrsum(lucky X) {
  long long ret = 0;
  long long pre = 0;
  bool flag = false;
  for (int i = 0; i < n; i++) {
    if (X.val[i] == 4) {
      pre += 4 * p10[n - i - 1];
      pre %= mod;
      flag = true;
    } else {
      pre += 4 * p10[n - i - 1];
      pre %= mod;
      ret += Sqr(pre) * qp(2, n - i - 1, mod);
      ret %= mod;
      ret += S_2[n - i - 1];
      ret += pre * 2 * S[n - i - 1];
      ret %= mod;
      pre += 3 * p10[n - i - 1];
      pre %= mod;
    }
  }
  if (!flag) return 0;
  ret += pre * pre;
  ret %= mod;
  return ret;
}
long long rangesum[Maxn][2][2], rangecnt[Maxn];
bool issg[Maxn];
int main() {
  _init();
  scanf("%s", tmp);
  n = strlen(tmp);
  for (int i = 0; i < n; i++) {
    L.val[i] = tmp[i] - '0';
  }
  scanf("%s", tmp);
  for (int i = 0; i < n; i++) {
    R.val[i] = tmp[i] - '0';
  }
  R.Minus();
  L.Minus();
  long long ans = sqrsum(R) - sqrsum(L);
  ans = (ans % mod + mod) % mod;
  L.Plus();
  long long nowL = 0, nowR = 0;
  rangecnt[0] = 1;
  bool Sig = true;
  for (int i = 1; i <= n; i++) {
    long long ini =
        rangesum[i - 1][0][0] * 2 + 11 * rangecnt[i - 1] % mod * p10[n - i];
    rangecnt[i] = rangecnt[i - 1] * 2;
    rangecnt[i] %= mod;
    ini %= mod;
    nowL = nowL + p10[n - i] * L.val[i - 1];
    nowL %= mod;
    nowR = nowR + p10[n - i] * R.val[i - 1];
    nowR %= mod;
    if (L.val[i - 1] == 7) {
      ini -= nowL - 3 * p10[n - i];
      rangecnt[i]--;
    }
    if (R.val[i - 1] == 4) {
      ini -= nowR + 3 * p10[n - i];
      rangecnt[i]--;
    }
    if (rangecnt[i] != 1) Sig = false;
    ini = (ini % mod + mod) % mod;
    for (int j = 0; j < 2; j++) {
      for (int k = 0; k < 2; k++) {
        rangesum[i][j][k] = ini - ((j == 0) ? 0 : nowL) - ((k == 0) ? 0 : nowR);
        rangesum[i][j][k] = (rangesum[i][j][k] % mod + mod) % mod;
        if (Sig && j == 1 && k == 1) rangesum[i][j][k] = 0;
      }
    }
    issg[i] = Sig;
  }
  long long dlt = 0;
  int l = 0, r = 0;
  long long Delta = 3;
  long long nowval = 4;
  for (int i = n - 1; i >= 0; i--) {
    int curl = l, curr = r;
    if (L.val[i] == 7) {
      curl = 1;
    }
    if (R.val[i] == 7) {
      curr = 0;
    }
    long long fuck = rangecnt[i];
    if (curl || curr) {
      if (issg[i]) {
        fuck = 0;
      } else {
        fuck = fuck - curl - curr;
        if (fuck < 0) fuck += mod;
      }
    }
    dlt += Delta * (rangesum[i][curl][curr] + fuck * nowval % mod);
    dlt %= mod;
    if (L.val[i] == 4) {
      l = 0;
    }
    if (R.val[i] == 4) {
      r = 1;
    }
    Delta = Delta * 10 - 3;
    Delta = (Delta % mod + mod) % mod;
    nowval = nowval * 10 + 7;
    nowval %= mod;
  }
  ans += dlt;
  ans %= mod;
  printf("%lld\n", ans);
  return ~~(0 ^ 0 ^ 0);
}
