#include <bits/stdc++.h>
using namespace std;
char S[100010], T[100010];
int N, M;
int fail[100010];
int nxt[100010][26];
void get_fail() {
  fail[0] = fail[1] = 0;
  for (int i = 2; i <= M; i++) {
    int j = fail[i - 1];
    while (j && T[i] != T[j + 1]) j = fail[j];
    if (T[i] == T[j + 1]) j++;
    fail[i] = j;
  }
}
int f[2][100010], now = 1, pre = 0;
int main() {
  scanf("%s%s", S + 1, T + 1);
  N = strlen(S + 1);
  M = strlen(T + 1);
  get_fail();
  for (int i = 0; i <= M; i++) {
    for (int j = 0; j < 26; j++) {
      if (i == 0)
        nxt[i][j] = (T[i + 1] == 'a' + j ? 1 : 0);
      else if (T[i + 1] == 'a' + j)
        nxt[i][j] = i + 1;
      else
        nxt[i][j] = nxt[fail[i]][j];
    }
  }
  memset(f, 0xc0, sizeof(f));
  f[pre][0] = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < M; j++) {
      int start, end;
      if (S[i + 1] == '?')
        start = 0, end = 25;
      else
        start = end = S[i + 1] - 'a';
      for (int ch = start; ch <= end; ch++) {
        char tmp = 'a' + ch;
        if (T[j + 1] == tmp) {
          if (j + 1 < M) {
            f[now][j + 1] = max(f[now][j + 1], f[pre][j]);
          } else {
            f[now][fail[M]] = max(f[now][fail[M]], f[pre][j] + 1);
          }
        } else {
          int t = nxt[j][ch];
          f[now][t] = max(f[now][t], f[pre][j]);
        }
      }
    }
    swap(now, pre);
    memset(f[now], 0xc0, sizeof(f[now]));
  }
  int ans = 0;
  for (int i = 0; i < M; i++) ans = max(ans, f[pre][i]);
  printf("%d\n", ans);
  return 0;
}
