Problem: There have recently been elections in the zoo. Overall there were 7 main political parties: one of them is the Little Elephant Political Party, 6 other parties have less catchy names.

Political parties find their number in the ballot highly important. Overall there are m possible numbers: 1, 2, ..., m. Each of these 7 parties is going to be assigned in some way to exactly one number, at that, two distinct parties cannot receive the same number.

The Little Elephant Political Party members believe in the lucky digits 4 and 7. They want to evaluate their chances in the elections. For that, they need to find out, how many correct assignments are there, such that the number of lucky digits in the Little Elephant Political Party ballot number is strictly larger than the total number of lucky digits in the ballot numbers of 6 other parties. 

Help the Little Elephant Political Party, calculate this number. As the answer can be rather large, print the remainder from dividing it by 1000000007 (109 + 7).

Input

A single line contains a single positive integer m (7 ≤ m ≤ 109) — the number of possible numbers in the ballot.

Output

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

Examples

Input

7


Output

0


Input

8


Output

1440

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using std::cin;
using std::cout;
const int64_t MOD = 1000000007;
typedef int64_t Table[10][11][11];
typedef int64_t Table2[11][11];
int64_t fact(int n, int64_t f[]) {
  if (n == 0) {
    return 1;
  }
  if (f[n] != -1) {
    return f[n];
  }
  return f[n] = n * fact(n - 1, f);
}
inline bool isLucky(int digit) { return digit == 4 || digit == 7; }
int64_t Dp(int digit, int count, int lucky, Table& table) {
  if (table[digit][count][lucky] != -1) {
    return table[digit][count][lucky];
  }
  int64_t& result = table[digit][count][lucky] = 0;
  if (count == 1) {
    if (isLucky(digit)) {
      if (lucky == 1) {
        result = 1;
      }
    } else {
      if (lucky == 0) {
        result = 1;
      }
    }
  } else {
    int extra = isLucky(digit) ? 1 : 0;
    for (int i = 0; i < 10; ++i) {
      result = (result + Dp(i, count - 1, lucky - extra, table)) % MOD;
    }
  }
  return result;
}
int64_t Dp2(int index, int lucky, const std::string& limitStr, Table& dpTable,
            Table2& table) {
  if (index == static_cast<int>(limitStr.size())) {
    return 0;
  }
  if (table[index][lucky] != -1) {
    return table[index][lucky];
  }
  int64_t& result = table[index][lucky] = 0;
  int maxDigit = limitStr[index] - '0';
  for (int digit = (index == 0) ? 1 : 0; digit < maxDigit; ++digit) {
    result =
        (result + Dp(digit, limitStr.size() - index, lucky, dpTable)) % MOD;
  }
  int extra = isLucky(maxDigit) ? 1 : 0;
  result =
      (result + Dp2(index + 1, lucky - extra, limitStr, dpTable, table)) % MOD;
  return result;
}
std::string getNumberStr(int64_t number) {
  std::stringstream ss;
  ss << number;
  return ss.str();
}
int64_t calcNumbers(int luckyDigits, const std::string& limitStr,
                    Table& table) {
  int64_t result = 0;
  int limitLength = limitStr.size();
  for (int count = std::max(1, luckyDigits); count < limitLength; ++count) {
    for (int digit = 1; digit < 10; ++digit) {
      result = (result + Dp(digit, count, luckyDigits, table)) % MOD;
    }
  }
  Table2 dpTable;
  std::memset(dpTable, -1, sizeof(dpTable));
  result = (result + Dp2(0, luckyDigits, limitStr, table, dpTable)) % MOD;
  return result;
}
int64_t findCount(const std::map<int, int>& counts, const std::string& limitStr,
                  Table& table, int64_t fTable[]) {
  int allCount = 0;
  int64_t result = 1;
  int64_t deci = 1;
  for (std::map<int, int>::const_iterator it = counts.begin();
       it != counts.end(); ++it) {
    int lucky = it->first;
    int cnt = it->second;
    int64_t numbersCnt = calcNumbers(lucky, limitStr, table);
    for (int i = 0; i < cnt; ++i) {
      result = (result * numbersCnt) % MOD;
      numbersCnt = (numbersCnt - 1 + MOD) % MOD;
    }
    deci *= fact(cnt, fTable);
    allCount += cnt;
  }
  int64_t extra = fact(allCount, fTable) / deci;
  result = (result * extra) % MOD;
  return result;
}
int64_t findCount(int64_t limit) {
  int64_t result = 0;
  Table table;
  std::memset(table, -1, sizeof(table));
  int64_t fTable[12];
  std::memset(fTable, -1, sizeof(fTable));
  std::string limitStr = getNumberStr(limit);
  int maxLuckyDigits = limitStr.size() + 1;
  std::map<int, int> counts;
  for (int a = 0; a < maxLuckyDigits; ++a) {
    for (int b = a; b < maxLuckyDigits; ++b) {
      for (int c = b; c < maxLuckyDigits; ++c) {
        for (int d = c; d < maxLuckyDigits; ++d) {
          for (int e = d; e < maxLuckyDigits; ++e) {
            for (int f = e; f < maxLuckyDigits; ++f) {
              if (a + b + c + d + e + f > maxLuckyDigits) {
                continue;
              }
              counts.clear();
              counts[a]++;
              counts[b]++;
              counts[c]++;
              counts[d]++;
              counts[e]++;
              counts[f]++;
              int64_t wayResult = findCount(counts, limitStr, table, fTable);
              for (int sum = a + b + c + d + e + f + 1; sum < maxLuckyDigits;
                   ++sum) {
                int64_t r = calcNumbers(sum, limitStr, table);
                r = (r * wayResult) % MOD;
                result = (result + r) % MOD;
              }
            }
          }
        }
      }
    }
  }
  return result;
}
int input() {
  int result;
  cin >> result;
  return result + 1;
}
void output(int64_t result) { cout << result << '\n'; }
int main() {
  std::ios_base::sync_with_stdio(false);
  output(findCount(input()));
  return 0;
}