#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 30;
const int MAXS = 200005;
const int MAXN = 200005;
string S, T;
int n, m, K;
struct Node {
  int v;
  Node *fail, *trans[26];
  Node() {
    v = 0, fail = 0;
    memset(trans, 0, sizeof(trans));
  }
};
Node *root, *sroot, pool[MAXS];
int tot = 1;
inline Node *newnode() { return &pool[++tot]; }
void insert(Node *p, int ptr) {
  if (ptr == T.size()) return;
  int x = T[ptr] - 'a';
  if (!p->trans[x]) p->trans[x] = newnode();
  insert(p->trans[x], ptr + 1);
}
void init() {
  static queue<Node *> q;
  sroot = &pool[0], root = &pool[1];
  root->fail = sroot->fail = sroot;
  for (int i = 0; i < 26; i++) sroot->trans[i] = root;
  insert(root, 0);
  q.push(root);
  while (!q.empty()) {
    Node *p = q.front();
    q.pop();
    for (int i = 0; i < 26; i++) {
      if (p->trans[i]) {
        p->trans[i]->fail = p->fail->trans[i];
        q.push(p->trans[i]);
      } else
        p->trans[i] = p->fail->trans[i];
    }
  }
}
int f[2][100005];
int main() {
  ios::sync_with_stdio(false);
  memset(f, -1, sizeof(f));
  cin >> S >> T;
  init();
  f[0][1] = 0;
  for (int i = 0; i < S.size(); i++) {
    int x = (S[i] == '?' ? -1 : S[i] - 'a');
    for (int j = 1; j <= tot; j++) {
      if (f[0][j] != -1) {
        Node *tmp = pool + j;
        if (x == -1) {
          for (int y = 0; y < 26; y++) {
            int v = tmp->trans[y] - pool;
            f[1][v] = max(f[1][v], f[0][j] + (v == tot ? 1 : 0));
          }
        } else {
          int v = tmp->trans[x] - pool;
          f[1][v] = max(f[1][v], f[0][j] + (v == tot ? 1 : 0));
        }
      }
    }
    for (int j = 1; j <= tot; j++) f[0][j] = f[1][j], f[1][j] = -1;
  }
  int res = 0;
  for (int j = 1; j <= tot; j++) res = max(res, f[0][j]);
  cout << res << endl;
  return 0;
}
