Problem:
不運なイクタ君は持っていた大事な文字列Tをウィルスによって異なる文字列T'に書き換えられてしまった。そのウィルスがTの１文字を異なる文字に書き換えてしまったことがわかっている。すなわちTとT'はちょうど１文字のみ異なっている。イクタ君はTを復元するために、Tが出現していると思われる文書Sを用意した。Tを復元するための下準備としてSの部分文字列でTと一致している可能性があるものの個数を調べたい。

文字列T'と文書Sが与えられる。
S = a1 a2 a3 . . . a|S|の長さ|T'|の部分文字列ak ak+1 . . . ak+|T'|−1(1 ≤ k ≤ |S| − |T'| + 1)
でT'と比較して1文字だけ異なるものの数を求めよ。

Input

入力は以下の形式で与えられる。

S
T'

１行目でSが与えられる。

２行目でT'が与えられる。

S, T'はそれぞれ大文字、小文字のアルファベットのみからなる。

Constraints

入力中の各変数は以下の制約を満たす。

1 ≤ |S| ≤ 300,000

1 ≤ |T'| ≤ |S|

Output

条件を満たす部分文字列の数を1行に出力せよ。

Sample Input 1

abcbcdbc
abc

Output for the Sample Input 1

2

Sの3番目の文字から始まるcbc, Sの6番目の文字から始まるdbcが条件を満たす。

Sample Input 2

aaaaaa
aaaaaa

Output for the Sample Input 2

0

完全に一致する文字列は数えてはならない。

Sample Input 3

baaaaaaaa
b

Output for the Sample Input 3

8

Solution in C++ (judge verdict: Accepted)

//Daily Lunch Special Tanoshii !!
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
typedef long long ll;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 2000000000
#define rep(i,x) for(int i=0;i<x;i++)
int NN,k;
int ran[600005];
int tmp[600005];
int sa[600005];
bool compare_sa(int i,int j)
{
	if(ran[i] != ran[j]) return ran[i] < ran[j];
	else
	{
		int ri = i+k<=NN ? ran[i+k]: -1;
		int rj = j+k<=NN ? ran[j+k]: -1;
		
		return ri < rj;
	}
}

void construct_sa(string S)
{
	NN = S.size();
	for(int i=0;i<=NN;i++)
	{
		sa[i] = i;
		ran[i] = i<NN?S[i]:-1;
	}
	
	for(k=1;k<=NN;k*=2)
	{
		sort(sa,sa+NN+1,compare_sa);
		
		tmp[sa[0]] = 0;
		for(int i=1;i<=NN;i++)
		{
			tmp[sa[i]] = tmp[sa[i-1]] + compare_sa(sa[i-1],sa[i]);
		}
		for(int i=0;i<=NN;i++)
		{
			ran[i] = tmp[i];
		}
	}
}
int lcp[600005];
void construct_lcp(string S)
{
	int n = S.size();
	for(int i=0;i<=n;i++) ran[sa[i]] = i;
	
	int h = 0;
	lcp[0] = 0;
	
	for(int i=0;i<n;i++)
	{
		int j = sa[ran[i]-1];
		
		if(h) h--;
		for(;j+h<n && i+h<n;h++)
		{
			if(S[j+h] != S[i+h]) break;
		}
		lcp[ran[i]-1] = h;
	}
}

int seg[(1<<21)+5];
void update(int k,int a){
	k+=(1<<20)-1; seg[k] = a;
	while(k>0){
		k=(k-1)/2;
		seg[k]=min(seg[k*2+1],seg[k*2+2]);
	}
}
int query(int a,int b,int k,int l,int r){
	if(r<a || b<l) return INF;
	if(a<=l && r<=b) return seg[k];
	else{
		int vl=query(a,b,k*2+1,l,(l+r)/2);
		int vr=query(a,b,k*2+2,(l+r)/2+1,r);
		return min(vl,vr);
	}
}

string s,t;
int n,b;
int main(){
	cin >> s >> t;
	n = s.size(); b = s.size()+1;
	s += "$"; s += t;
	construct_sa(s);
	construct_lcp(s);
	for(int i=0;i<s.size();i++){
		update(i,lcp[i]);
	}
	int ret = 0;
	for(int i=0;i<n;i++){
		if(i+t.size() > n) break;
		int P = ran[i], Q = ran[b];
		int L = query(min(P,Q),max(P,Q)-1,0,0,(1<<20)-1);
		if(L == t.size()){
			continue;
		}
		if(L == t.size()-1){
			ret++; continue;
		}
		P = ran[i+L+1],Q = ran[b+L+1];
		int L2 = query(min(P,Q),max(P,Q)-1,0,0,(1<<20)-1);
		ret += (L+L2 == t.size()-1);
	}
	cout << ret << endl;
}