#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int mod = 1000000007;

int cntq(char a, char b, char c) {
  int ret = 0;
  if (a == '?') ret++;
  if (b == '?') ret++;
  if (c == '?') ret++;
  return ret;
}

int main() {
  string a, b, c;
  while (cin >> a, cin >> b, cin >> c, a != "0") {
    int l = a.length();

    // その桁で繰り上がりが生じない場合/生じる場合を分ける
    vector<vector<long long>> dp(l + 1, vector<long long>(2, 0));

    dp[l] = {1, 0};  // 一番下の桁に0 0 0があるとみなす

    for (int i = l - 1; i >= 0; i--) {
      int an = a[i] - '0';
      int bn = b[i] - '0';
      int cn = c[i] - '0';
      if (i > 0) {
        switch (cntq(a[i], b[i], c[i])) {
          case 0: {
            int carry = int(an + bn > cn);
            int diff = (cn - (an + bn) + 10) % 10;
            if (diff == 0 || diff == 1) {
              dp[i][carry] = dp[i + 1][diff];
            }
          } break;
          case 1: {
            if (a[i] == '?') {
              // その桁で繰り上がりが発生するかしないかは定まる
              dp[i][cn - bn >= 0 ? 0 : 1] +=
                  dp[i + 1][0];  // 下の桁で繰り上がりが発生しなかった場合
              dp[i][cn - bn >= 1 ? 0 : 1] +=
                  dp[i + 1][1];  // 下の桁で繰り上がりが発生した場合
            } else if (b[i] == '?') {
              dp[i][cn - an >= 0 ? 0 : 1] += dp[i + 1][0];
              dp[i][cn - an >= 1 ? 0 : 1] += dp[i + 1][1];
            } else {
              dp[i][an + bn < 10 ? 0 : 1] += dp[i + 1][0];
              dp[i][an + bn + 1 < 10 ? 0 : 1] += dp[i + 1][1];
            }
          } break;
          case 2: {
            if (a[i] != '?') {
              // ?の埋め方は（下の繰り上がりの有無それぞれ）10通りあるので、繰り上がりのあるなしで配分
              dp[i][0] =
                  (10 - an) * dp[i + 1][0] + (10 - an - 1) * dp[i + 1][1];
              dp[i][1] = an * dp[i + 1][0] + (an + 1) * dp[i + 1][1];
            } else if (b[i] != '?') {
              dp[i][0] =
                  (10 - bn) * dp[i + 1][0] + (10 - bn - 1) * dp[i + 1][1];
              dp[i][1] = bn * dp[i + 1][0] + (bn + 1) * dp[i + 1][1];
            } else {
              dp[i][0] = (cn + 1) * dp[i + 1][0] + cn * dp[i + 1][1];
              dp[i][1] =
                  (10 - cn - 1) * dp[i + 1][0] + (10 - cn) * dp[i + 1][1];
            }
          } break;
          case 3: {
            dp[i][0] = 55 * dp[i + 1][0] + 45 * dp[i + 1][1];
            dp[i][1] = 45 * dp[i + 1][0] + 55 * dp[i + 1][1];
          }
        }
      } else {
        // 最上位のみ、0が使えないので分ける
        switch (cntq(a[i], b[i], c[i])) {
          case 0: {
            int carry = int(an + bn > cn);
            int diff = cn - (an + bn) % 10;
            if (diff == 0 || diff == 1) {
              dp[i][carry] = dp[i + 1][diff];
            }
          } break;
          case 1: {
            if (a[i] == '?') {
              // ?=0になるやつはdp[0][1]に押し込んでしまう
              dp[i][cn - bn > 0 ? 0 : 1] += dp[i + 1][0];
              dp[i][cn - bn > 1 ? 0 : 1] += dp[i + 1][1];
            } else if (b[i] == '?') {
              dp[i][cn - an > 0 ? 0 : 1] += dp[i + 1][0];
              dp[i][cn - an > 1 ? 0 : 1] += dp[i + 1][1];
            } else {
              dp[i][an + bn < 10 ? 0 : 1] += dp[i + 1][0];
              dp[i][an + bn + 1 < 10 ? 0 : 1] += dp[i + 1][1];
            }
          } break;
          case 2: {
            if (a[i] != '?') {
              // dp[0][0]だけ更新する
              dp[i][0] =
                  (9 - an) * dp[i + 1][0] + max(0, 9 - an - 1) * dp[i + 1][1];
            } else if (b[i] != '?') {
              dp[i][0] =
                  (9 - bn) * dp[i + 1][0] + max(0, 9 - bn - 1) * dp[i + 1][1];
            } else {
              dp[i][0] =
                  (cn - 1) * dp[i + 1][0] + max(0, cn - 2) * dp[i + 1][1];
            }
          } break;
          case 3: {
            // dp[0][0]だけ更新する
            dp[i][0] = 36 * dp[i + 1][0] + 28 * dp[i + 1][1];
          }
        }
      }
      dp[i][0] %= mod;
      dp[i][1] %= mod;
    }
    /*
    for (int i = 0; i <= l; i++) cerr << dp[i][0] << ' ';
    cerr << endl;
    for (int i = 0; i <= l; i++) cerr << dp[i][1] << ' ';
    cerr << endl;
    */

    cout << dp[0][0] << endl;  //文字数固定なので繰り上がりはなし
  }
}


Measured memory_bytes: 3148