/**
 * code generated by JHelper
 * More info: https://github.com/AlexeyDmitriev/JHelper
 * @author edamat
 */

#include <bits/stdc++.h>

using namespace std;
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for(int i = int(a), i##_len = (b); i < i##_len; ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, )(__VA_ARGS__)
#define _repr(i, n) repri(i, n, 0)
/* loop in [n,m] step -1 */
#define repri(i, a, b) for(int i = int(a), i##_len = (b); i >= i##_len; --i)
/* loop in [n,0] step -1 or [n,m] step -1 */
#define repr(...) _overload3(__VA_ARGS__, repri, _repr, )(__VA_ARGS__)
#define all(x) (x).begin(), (x).end()
#define debug(x) cerr << #x << ": " << (x) << '\n'
#define pb push_back
#define eb emplace_back
#define endl '\n'
typedef long long lint;
// #define int lint
const int INF = (int) (1 << 30) - 1;
int MOD = (int) 1e9 + 7;
//const double EPS = 1e-9;
const lint LINF = (lint) (1LL << 62) - 1;
typedef vector<int> vint;
typedef pair<int, int> pint;

struct IoSetup {
    IoSetup() {
        cin.tie(nullptr);
        ios::sync_with_stdio(false);
//        cout << fixed << setprecision(20);
//        cerr << fixed << setprecision(20);
    }
} iosetup;

using std::to_string;

auto to_string(std::string s) -> std::string {
    return '"' + s + '"';
}

auto to_string(char c) -> std::string {
    return "'" + std::string{c} + "'";
}

auto to_string(const char *s) -> std::string {
    return to_string((std::string) s);
}

auto to_string(bool b) -> std::string {
    return (b ? "true" : "false");
}

template<typename T, typename U>
auto to_string(std::pair<T, U> p) -> std::string {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template<size_t N>
auto to_string(std::bitset<N> bs) -> std::string {
    std::string res{};
    for (size_t i = 0; i < N; i++)
        res.insert(res.begin(), bs.test(i) ? '1' : '0');
    return res;
}

template<typename T>
auto to_string(T v) -> std::string {
    bool flg = false;
    std::string res = "[";
    for (auto const &x : v) {
        if (flg) res += ", ";
        else flg = true;
        res += to_string(x);
    }
    res += "]";
    return res;
}

#define UNIQUE(v) v.erase(unique(v.begin(), v.end()), v.end());
#define SZ(x) ((int)(x).size())

/* range macro. usage: for(int i:range(n)) */
class range {
private:
    struct I {
        int x;

        int operator*() { return x; }

        bool operator!=(I &lhs) { return x < lhs.x; }

        void operator++() { ++x; }
    };

    I i, n;

public:
    range(int n) : i({0}), n({n}) {}

    range(int i, int n) : i({i}), n({n}) {}

    I &begin() { return i; }

    I &end() { return n; }
};

/* keep a max,min */
template<class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}

template<class T>
bool chmin(T &a, const T &b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}

/* input,output operator for pair and vector */
template<typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &p) {
    os  << p.first << " " << p.second;
    return os;
}

template<typename T1, typename T2>
istream &operator>>(istream &is, pair<T1, T2> &p) {
    is >> p.first >> p.second;
    return is;
}

template<typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    for (int i = 0; i < (int) v.size(); i++) {
        os << v[i] << (i + 1 != v.size() ? ", " : "");
    }
    return os;
}

template<typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (T &in : v) is >> in;
    return is;
}

template<typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &mp) {
    for (auto x = mp.begin(); x != mp.end(); ++x) {
        os << x->first << ": " << x->second
           << (x != prev(mp.end()) ? "\n" : "");
    }
    return os;
}

/* initialize vector. usage: auto v = male_v<int>(N,0); */
template<typename T>
vector<T> make_v(size_t a) {
    return vector<T>(a);
}

template<typename T, typename... Ts>
auto make_v(size_t a, Ts... ts) {
    return vector<decltype(make_v<T>(ts...))>(a, make_v<T>(ts...));
}

/* fill vector. usage: fill_v(v,0); */
template<typename T, typename V>
typename enable_if<is_class<T>::value == 0>::type fill_v(T &t, const V &v) {
    t = v;
}

template<typename T, typename V>
typename enable_if<is_class<T>::value != 0>::type fill_v(T &t, const V &v) {
    for (auto &e : t) fill_v(e, v);
}

/* sum */
template<typename T>
T sum(vector<T> &v) {
    T ret = 0;
    for (T x : v) {
        ret += x;
    }
    return ret;
}

template<typename T>
auto sum(const T &a) {
    return a;
}

template<typename T, typename... A>
auto sum(const T &first, const A &... rest) {
    return sum(first) + sum(rest...);
}

/* mod */
lint intpow(lint a, lint n, lint mod) {
    lint res = 1;
    while (n > 0) {
        if (n & 1) res = res * a % mod;
        a = a * a % mod;
        n >>= 1;
    }
    return res;
}

template<typename T>
T intpow(T a, lint n) {
    T res = 1;
    while (n > 0) {
        if (n & 1) res = res * a;
        a = a * a;
        n >>= 1;
    }
    return res;
}

long long modinv(long long a, long long m) {
    long long b = m, u = 1, v = 0;
    while (b) {
        long long t = a / b;
        a -= t * b;
        swap(a, b);
        u -= t * v;
        swap(u, v);
    }
    u %= m;
    if (u < 0) u += m;
    return u;
}

/* print */
template<typename T>
void print(const T &first) {
    cout << first << endl;
}

template<typename T, typename... A>
void print(const T &first, const A &... rest) {
    cout << first << " ";
    print(rest...);
}

template<typename... A>
void print(const A &... rest) {
    print(rest...);
}
struct RandomNumberGenerator {
    mt19937 mt;
    
    RandomNumberGenerator() : mt(chrono::steady_clock::now().time_since_epoch().count()) {}
    
    int operator()(int a, int b) { // [a, b)
        uniform_int_distribution<int> dist(a, b - 1);
        return dist(mt);
    }
    
    int operator()(int b) { // [0, b)
        return (*this)(0, b);
    }
};

template< int mod >
struct ModInt {
  int x;

  ModInt() : x(0) {}

  ModInt(int64_t y) : x(y >= 0 ? y % mod : (mod - (-y) % mod) % mod) {}

  ModInt &operator+=(const ModInt &p) {
    if((x += p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator-=(const ModInt &p) {
    if((x += mod - p.x) >= mod) x -= mod;
    return *this;
  }

  ModInt &operator*=(const ModInt &p) {
    x = (int) (1LL * x * p.x % mod);
    return *this;
  }

  ModInt &operator/=(const ModInt &p) {
    *this *= p.inverse();
    return *this;
  }

  ModInt operator-() const { return ModInt(-x); }

  ModInt operator+(const ModInt &p) const { return ModInt(*this) += p; }

  ModInt operator-(const ModInt &p) const { return ModInt(*this) -= p; }

  ModInt operator*(const ModInt &p) const { return ModInt(*this) *= p; }

  ModInt operator/(const ModInt &p) const { return ModInt(*this) /= p; }

  bool operator==(const ModInt &p) const { return x == p.x; }

  bool operator!=(const ModInt &p) const { return x != p.x; }

  ModInt inverse() const {
    int a = x, b = mod, u = 1, v = 0, t;
    while(b > 0) {
      t = a / b;
      swap(a -= t * b, b);
      swap(u -= t * v, v);
    }
    return ModInt(u);
  }

  ModInt pow(int64_t n) const {
    ModInt ret(1), mul(x);
    while(n > 0) {
      if(n & 1) ret *= mul;
      mul *= mul;
      n >>= 1;
    }
    return ret;
  }

  friend ostream &operator<<(ostream &os, const ModInt &p) {
    return os << p.x;
  }

  friend istream &operator>>(istream &is, ModInt &a) {
    int64_t t;
    is >> t;
    a = ModInt< mod >(t);
    return (is);
  }
};



class DDigitsParade {
public:
    static constexpr int kStressIterations = 1;
    
    static void generateTest(int cnt, std::ostream &test) {
        RandomNumberGenerator rng;
        string s;
        for(int i=0;i<100000;++i){
            s += '?';
        }
        test << s << endl;
    }
    
    int ctoi(char s) {
        return s - '0';
    }
    
    using modint = ModInt<(int) 1e9 + 7>;
    
    void solve(std::istream &cin, std::ostream &cout) {
        string S;
        cin >> S;
        vint lis{1, 10, 9, 12, 3, 4};
        set<int> ss;
        rep(i, S.length()){
            if(S[i] == '?'){
                ss.emplace(i);
            }
        }
        auto dp = make_v<modint>(110000, 13);
        if(S[S.size() - 1] != '?') dp[0][ctoi(S[S.size() - 1])] = 1;
        else {
            for(int i = 0; i < 10; ++i){
                dp[0][i] += 1;
            }
        }
        for(int i = 1; i < S.size(); ++i){
//            cout << S[S.size() - i - 1] << endl;
            if(S[S.size() - i - 1] != '?'){
                int n = ctoi(S[S.size() - i - 1]);
                for(int j = 0; j < 13; ++j){
                    dp[i][(j + n * lis[(i) % 6]) % 13] += dp[i - 1][j];
                }
            } else {
                for(int j = 0; j < 13; ++j){
                    for(int k = 0; k < 10; ++k){
                        dp[i][(j + k * lis[(i) % 6]) % 13] += dp[i - 1][j];
                    }
                }
            }
//            cout << S[S.size() - i - 1] << ", " << dp[i] << endl;
        }
        cout << dp[S.size()-1][5] << endl;
    }
};


signed main() {
	DDigitsParade solver;
	std::istream& in(std::cin);
	std::ostream& out(std::cout);
	solver.solve(in, out);
	return 0;
}


Measured memory_bytes: 14544