#include <bits/stdc++.h>
using namespace std;
#define all(c) (c).begin(),(c).end()
#define rrep(i,n) for(int i=(int)(n)-1;i>=0;i--)
#define REP(i,m,n) for(int i=(int)(m);i<(int)(n);i++)
#define rep(i,n) REP(i,0,n)
#define iter(c) __typeof((c).begin())
#define tr(it,c) for(iter(c) it=(c).begin();it!=(c).end();it++)
#define mem(a) memset(a,0,sizeof(a))
#define pb(a) push_back(a)
#define in(a) insert(a)
#define R cin>>
#define F first
#define S second
#define C class
#define ll long long
#define ln cout<<'\n'
#define _(_1,_2,_3,N,...)N
#define pr(...) _(__VA_ARGS__,pr3,pr2,pr1)(__VA_ARGS__)
template<C T>void pr1(T a){cout<<a;ln;}
template<C T,C T2>void pr2(T a,T2 b){cout<<a<<' '<<b;ln;}
template<C T,C T2,C T3>void pr3(T a,T2 b,T3 c){cout<<a<<' '<<b<<' '<<c;ln;}
template<C T>void PR(T a,int n){rep(i,n){if(i)cout<<' ';cout<<a[i];}ln;}
bool check(int n,int m,int x,int y){return x>=0&&x<n&&y>=0&&y<m;}
const ll MAX=1000000007,MAXL=1LL<<60,dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
typedef pair<int,int> P;

class SegmentTree {
private:
  int size;
  vector<int> dat;
  int query(int a,int b,int k,int l,int r) {
    if(r<=a || b<=l) return INT_MAX;
    if(a<=l && r<= b) return dat[k];
    int vl=query(a,b,k*2+1,l,(l+r)/2);
    int vr=query(a,b,k*2+2,(l+r)/2,r);
    return min(vl,vr);
  }
   
public:
  SegmentTree(int n_) {
    size = 1;
    while(size<n_) size*=2;
    dat.resize(2*size-1,INT_MAX);
  }
  int find(int s,int t) {
    return query(s,t,0,0,size);
  }
  void update(int idx,int x) {
    idx+=size-1;
    dat[idx] = x;
    while(idx>0) {
      idx=(idx-1)/2;
      dat[idx]=min(dat[idx*2+1],dat[idx*2+2]);
    }
  }
};

void sa_is_countingAlphabets(const int *s,int n,int size,vector<int> &b,bool f=false) {
  if(f||(int)b.size()/2>=size) {
    vector<int>::iterator a=f?b.begin():b.begin()+size;
    fill(a,a+size,0);
    for(int i=0; i<n; i++) a[(int)s[i]]++;
  }
}

void sa_is_getBucketOffsets(const int *s, int n, bool dir, int size, vector<int> &b) {
  vector<int>::iterator a;
  if((int)b.size()/2<size) {
    sa_is_countingAlphabets(s,n,size,b,true);
    a=b.begin();
  } else a=b.begin()+size;
  int cumsum=1;
  if(dir) {
    for(int i=0; i<size; i++) {
      cumsum+=a[i];
      b[i] = cumsum;
    }
  } else {
    for(int i=0; i<size; i++) {
      int x=a[i];
      b[i]=cumsum;
      cumsum+=x;
    }
  }
}

void sa_is_inducedSort(const int *s,int n,int size,const vector<bool> &types,int *sa, vector<int> &b) {
  sa_is_getBucketOffsets(s,n,false,size,b);
  for(int i=0; i<n; i++) {
    int j=sa[i]-1;
    if(j>=0 && !types[j]) sa[b[(int)s[j]]++]=j;
  }
  sa_is_getBucketOffsets(s,n,true,size,b);
  for(int i=n; i>=1; i--) {
    int j=sa[i]-1;
    if(j>=0 && types[j]) sa[--b[(int)s[j]]]=j;
  }
}

void sa_is_rec(const int *s,int n,int size,int *sa,vector<int> &b) {
  vector<bool> types(n+1);
  types[n-1]=0;types[n]=1;
  for(int i=n-2;i>=0;i--) types[i]=s[i]<s[i+1]||(s[i]==s[i+1]&&types[i+1]);
  sa_is_countingAlphabets(s,n,size,b);
  sa_is_getBucketOffsets(s,n,true,size,b);
  fill(sa,sa+n+1,-1);
  for(int i = 1; i < n; i ++) if(types[i] && !types[i-1]) sa[--b[(int)s[i]]]=i;
  sa[0]=n;
  sa_is_inducedSort(s,n,size,types,sa,b);
  int n1=0;
  for(int i=0; i<=n; i++) {
    int j=sa[i];
    if(j>0 && types[j] && !types[j-1]) sa[n1++]=j;
  }
  int *buffer=sa+n1;
  fill(buffer,sa+n+1,-1);
  int c=0,ppos=-1;
  buffer[sa[0]/2]=c++;
  for(int i=1; i<n1; i++) {
    int pos=sa[i];bool diff=false;
    if(ppos==-1) diff=true;
    else {
      for(int j=pos, k=ppos;; j++,k++) {
	if(s[j]!=s[k] || types[j]!=types[k]) {
	  diff=true;break;
	} else if(j!=pos && ((types[j] && !types[j-1]) || (types[k] && !types[k-1]))) break;
      }
    }
    if(diff) {
      c++;
      ppos=pos;
    }
    buffer[pos/2]=c-1;
  }
  for(int i=n,j=n; i>=n1; i--) if(sa[i]>=0) sa[j--]=sa[i];
  int *sa1=sa,*s1=sa+n+1-n1;
  if(c==n1) for(int i=0; i<n1; i++) sa1[s1[i]]=i;
  else sa_is_rec(s1,n1-1,c,sa1,b);
  sa_is_countingAlphabets(s,n,size,b);
  sa_is_getBucketOffsets(s,n,true,size,b);
  for(int i=1,j=0; i<=n; i++) if(types[i] && !types[i-1]) s1[j++]=i;
  for(int i=0; i<n1; i++) sa1[i]=s1[sa1[i]];
  fill(sa+n1,sa+n+1,-1);
  for(int i=n1-1; i>=1; i--) {
    int j=sa[i];sa[i]=-1;
    sa[--b[(int)s[j]]]=j;
  }
  sa_is_inducedSort(s,n,size,types,sa,b);
}

void buildSuffixArray(const int *s,int n,int size,int *sa) {
  if(n==0) sa[0]=0;
  else {
    vector<int> b(max(size,(n+1)/2)+1);
    sa_is_rec(s,n,size,&sa[0],b);
  }
}

void buildSuffixArray(const string s,int n,int *sa) {
  int a[n];
  for(int i=0; i<n; i++) a[i]=(int)s[i];
  int maxElem=*max_element(a,a+n);
  buildSuffixArray(a,n,maxElem+1,sa);
}

const int MAXN=600010;
int r[MAXN],sa[MAXN],lcp[MAXN];

void construct_lcp(string s,int *sa,int *lcp){
  int n=s.size();
  for(int i=0;i<=n;i++) r[sa[i]]=i;
  int h = 0;
  lcp[0] = 0;
  for(int i=0;i<n;i++){
    int j=sa[r[i]-1];
    if(h>0) h--;
    for(;j+h<n&&i+h<n; h++) if(s[j+h]!=s[i+h]) break;
    lcp[r[i]-1]=h;
  }
}

void Main() {
  string s,t;
  cin >> s >> t;
  string z=s+t;
  int n=z.size();
  buildSuffixArray(z,n,sa);
  construct_lcp(z,sa,lcp);
  SegmentTree st(n+1);
  rep(i,n+1) st.update(r[i],lcp[r[i]]);
  int ans=0,N=t.size();
  rep(i,s.size()-t.size()+1) {
    int x=i,y=z.size()-t.size();
    bool ck=0;
    int m=0;
    rep(j,2) {
      if(r[x]>r[y]) swap(x,y);
      int k=st.find(r[x],r[y]);
      m+=k+1;
      x+=k+1;
      y+=k+1;
      if(m>N) {
	if(!j) ck=0;
	else ck=1;
	break;
      }
    }
    if(ck) ans++;
  }
  pr(ans);
}

int main() {
  ios::sync_with_stdio(0);cin.tie(0);Main();
  return 0;
}


Measured memory_bytes: 14616