#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using vint = vector<int>;
using vvint = vector<vector<int>>;
using pint = pair<int, int>;
#define repi(n) for (int i = 0; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define repr(i, a, b) for (int i = a; i < b; i++)
#define repv(itr) for (auto&& v : itr)

const int dx[] = {-1, 0, 0, 1, -1, -1, 1, 1};
const int dy[] = {0, -1, 1, 0, -1, 1, -1, 1};
template <typename T>
T minptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i < *re) re = i;
  }
  return re;
}
template <typename T>
T maxptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i > *re) re = i;
  }
  return re;
}
int __vmax(int x) {
  return INT_MAX;
}
double __vmax(double x) {
  return 1e+300;
}
ll __vmax(ll x) {
  return LLONG_MAX;
}
int __vmin(int x) {
  return INT_MIN;
}
double __vmin(double x) {
  return -1e+300;
}
ll __vmin(ll x) {
  return LLONG_MIN;
}
template <typename T>
vector<T> lis(T begin, T end, bool allowequal = false, bool lds = false) {
  using V = typename iterator_traits<T>::value_type;
  int n = end - begin;
  vector<V> a(n, lds ? __vmin(*begin) : __vmax(*begin));
  vector<int> id(n);
  if (lds && allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (lower_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (lds) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (upper_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = upper_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  } else {
    for (int i = 0; i < n; i++) {
      id[i] = lower_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  }
  int m = *maxptr(id.begin(), id.end());
  vector<T> re(m + 1);
  for (int i = n - 1; i >= 0; i--) {
    if (id[i] == m) re[m--] = begin + i;
  }
  return re;
}
// class segtree {
//  private:
//   int n;
//   bool maxmode;
//   vint* data;
//   void update(int i) {
//     (*data)[i] = maxmode ? max((*data)[i * 2 + 1], (*data)[i * 2 + 2])
//                          : min((*data)[i * 2 + 1], (*data)[i * 2 + 2]);
//     if (i) update((i - 1) / 2);
//   }

//  public:
//   segtree(int n_, bool maxmode_ = false) {
//     n = pow(2, ceil(log2(n_)));
//     cout << n << endl;
//     maxmode = maxmode_;
//     data = new vint(n * 2 - 1, maxmode ? INT_MIN : INT_MAX);
//   }
//   ~segtree() { delete data; }
//   void set(int i, int v) {
//     (*data)[n - 1 + i] = v;
//     if (n) update((n + i - 2) / 2);
//   }
//   int calc(int a, int b) {
//     // TODO
//     return 0;
//   }
// };

ll dp[100001][13];
const ll ww = 1e9 + 7;
int main() {
  string s;
  cin >> s;
  int n = s.length();
  dp[0][0] = 1;
  int m13 = 1;
  rep(i, n) {
    char c = s[n - 1 - i];
    if (c == '?') {
      rep(j, 13) {
        rep(k, 10) {
          dp[i + 1][(j + k * m13) % 13] += dp[i][j];
          dp[i + 1][(j + k * m13) % 13] %= ww;
        }
      }
    } else {
      ll v = c - '0';
      rep(j, 13) dp[i + 1][(j + v * m13) % 13] = dp[i][j];
    }
    m13 = (m13 * 10) % 13;
  }
  cout << dp[n][5] << endl;
  // vint emp;
  // int mod13 = 1, xx = 0;
  // repi(n) {
  //   char c = s[n - i - 1];
  //   if (c == '?')
  //     emp.push_back(i);
  //   else
  //     xx = (xx + mod13 * (c - '0')) % 13;
  //   mod13 = (mod13 * 10) % 13;
  // }
  // repv(emp)cout<<v<<" ";
  // cout << endl;
  // cout << xx << endl;
}


Measured memory_bytes: 10624