#include <bits/stdc++.h>
using namespace std;
template <typename T, typename V>
ostream &operator<<(ostream &os, const pair<T, V> pai) {
  return os << pai.first << ' ' << pai.second;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> v) {
  for (int i = 0, _i = (((int)(v).size())); i < _i; i++) cout << v[i] << ' ';
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const set<T> s) {
  for (T p : s) cout << p << ' ';
  return os;
}
template <typename T, typename V>
ostream &operator<<(ostream &os, const map<T, V> s) {
  for (auto p : s) cout << '(' << p << ") ";
  return os;
}
template <typename T, typename V>
istream &operator>>(istream &is, pair<T, V> &pai) {
  is >> pai.first >> pai.second;
  return is;
}
template <typename T>
void umax(T &a, T b) {
  a = max(a, b);
}
template <typename T>
void umin(T &a, T b) {
  a = min(a, b);
}
struct line {
  pair<int, int> pt, dif;
};
pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
  return make_pair(a.first + b.first, a.second + b.second);
}
pair<int, int> operator-(pair<int, int> a, pair<int, int> b) {
  return make_pair(a.first - b.first, a.second - b.second);
}
bool operator<(pair<int, int> a, pair<int, int> b) {
  if ((a.second > 0) ^ (b.second > 0)) return a.second > b.second;
  return a.second * b.first < b.second * a.first;
}
int gcd(int a, int b) {
  if (a > b) return gcd(b, a);
  if (a == 0) return b;
  return gcd(b % a, a);
}
line nor(line t) {
  if (t.dif.first < 0 or (t.dif.first == 0 and t.dif.second < 0)) {
    t.dif.first *= -1;
    t.dif.second *= -1;
  }
  int g = gcd(t.dif.first, abs(t.dif.second));
  t.dif.first /= g;
  t.dif.second /= g;
  return t;
}
int trans1[50][26];
int trans2[50][26];
int f1[51], f2[52];
int dp[1001][50][50];
string s1, s2, s3;
void kmp(string pat, int *pi) {
  int n = ((int)(pat).size());
  int i = -1, j = 0;
  pi[j] = i;
  while (j < n) {
    if (i == -1 || (i >= 0 && pat[i] == pat[j])) {
      i++;
      j++;
      pi[j] = i;
    } else
      i = pi[i];
  }
}
void gentr(string t, int fa[], int trans[][26]) {
  for (int i = 0, _i = (((int)(t).size())); i < _i; i++) {
    for (int j = 0, _j = (26); j < _j; j++) {
      int c = i;
      while (!(c == -1 or t[c] == j + 'a')) c = fa[c];
      trans[i][j] = c + 1;
      if (trans[i][j] == ((int)(t).size())) {
        trans[i][j] = 100 + fa[trans[i][j]];
      }
    }
  }
}
int main(void) {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr), cout.tie(nullptr);
  cin >> s1 >> s2 >> s3;
  int N = ((int)(s1).size()), M = ((int)(s2).size()), K = ((int)(s3).size());
  kmp(s2, f1);
  kmp(s3, f2);
  gentr(s2, f1, trans1);
  gentr(s3, f2, trans2);
  for (int i = 0, _i = (N + 1); i < _i; i++)
    for (int j = 0, _j = (M); j < _j; j++)
      for (int k = 0, _k = (K); k < _k; k++) {
        dp[i][j][k] = -(1 << 30);
      }
  for (int i = 0, _i = (1); i < _i; i++)
    for (int j = 0, _j = (3); j < _j; j++) {
      ;
    }
  dp[0][0][0] = 0;
  for (int i = 0, _i = (N); i < _i; i++) {
    if (s1[i] != '*') {
      for (int j = 0, _j = (M); j < _j; j++)
        for (int k = 0, _k = (K); k < _k; k++)
          if (dp[i][j][k] > -(1 << 30)) {
            ;
            int dif = 0;
            int tr1 = trans1[j][s1[i] - 'a'];
            int tr2 = trans2[k][s1[i] - 'a'];
            if (tr1 >= 100) dif++, tr1 -= 100;
            if (tr2 >= 100) dif--, tr2 -= 100;
            umax(dp[i + 1][tr1][tr2], dp[i][j][k] + dif);
            ;
          }
    } else {
      for (int j = 0, _j = (M); j < _j; j++)
        for (int k = 0, _k = (K); k < _k; k++)
          if (dp[i][j][k] > -(1 << 30)) {
            ;
            for (int l = 0, _l = (26); l < _l; l++) {
              int dif = 0;
              int tr1 = trans1[j][l];
              int tr2 = trans2[k][l];
              if (tr1 >= 100) dif++, tr1 -= 100;
              if (tr2 >= 100) dif--, tr2 -= 100;
              umax(dp[i + 1][tr1][tr2], dp[i][j][k] + dif);
            }
          }
    }
  }
  int mv = -(1 << 30);
  for (int i = 0, _i = (M); i < _i; i++)
    for (int j = 0, _j = (K); j < _j; j++) umax(mv, dp[N][i][j]);
  cout << mv << '\n';
}
