#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 26
#define PRIME 211234567ll
#define RAND 17

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

bool seen[PRIME];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((num)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	//set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen[vx]) continue;
					//if (seen.find(vx) != seen.end()) continue;
					ans ++;
					//seen.insert(vx);
					seen[vx] = true;
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef int num;
#define BASE 31
#define PRIME 1000000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	//set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					//if (seen[vx]) continue;
					if (seen.find(vx) != seen.end()) continue;
					ans ++;
					//seen[vx] = true;
					seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 26
#define PRIME 111234567ll
#define RAND 17

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

bool seen[PRIME];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	//set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen[vx]) continue;
					//if (seen.find(vx) != seen.end()) continue;
					ans ++;
					//seen.insert(vx);
					seen[vx] = true;
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007
#define RAND 0

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i] + RAND)%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i]);
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen.find(vx) != seen.end()) continue;
					ans ++;
					seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen.find(vx) != seen.end()) continue;
					ans ++;
					seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((num)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		if (v(T,i,alen) == ha){
			for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen.find(vx) == seen.end()){
						ans ++;
						seen.insert(vx);
					}
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((num)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

set<num> seen[MAXL];

int main(){
//	freopen("D.in","r",stdin);
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	for (int i=0;i+alen<=tlen;i++){
		if (v(T,i,alen) == ha){
			for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
				int l2 = (j-i)-1+blen;
				int ln = l2;
				if (v(T,j,blen) == hb){
					num vx = v(T,i,l2);
					if (seen[ln].find(vx) == seen[ln].end()){
						ans ++;
						seen[ln].insert(vx);
					}
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 26
#define PRIME 241234567ll
#define RAND 17

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

bool seen[PRIME];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((num)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	//set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen[vx]) continue;
					//if (seen.find(vx) != seen.end()) continue;
					ans ++;
					//seen.insert(vx);
					seen[vx] = true;
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((num)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

set<num> seen[MAXL];

int main(){
	freopen("D.in","r",stdin);
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	for (int i=0;i+alen<=tlen;i++){
		if (v(T,i,alen) == ha){
			for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
				int l2 = (j-i)-1+blen;
				int ln = l2;
				if (v(T,j,blen) == hb){
					num vx = v(T,i,l2);
					if (seen[ln].find(vx) == seen[ln].end()){
						ans ++;
						seen[ln].insert(vx);
					}
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i] + RAND)%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i]);
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen.find(vx) != seen.end()) continue;
					ans ++;
					seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000007ll
#define RAND 3

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

bool seen[PRIME];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i])%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1+RAND))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i])%PRIME;
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	//set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,i);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen[vx]) continue;
					//if (seen.find(vx) != seen.end()) continue;
					ans ++;
					seen[vx] = true;
					//seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cmath>
#include <cassert>
#include <cstdio>
#include <ctime>
#include <queue>
#include <fstream>
#include <set>
#include <utility>
#include <map>
#include <sstream>
#include <vector>
#include <cstring>

using namespace std;

#define MAXN 5010
#define MAXM 5010
#define MAXP 1000000

#define in cin
#define out cout
#define dout if(true) cout

typedef long long num;
#define BASE 31
#define PRIME 1000000007
#define RAND 0

#define MAXL 2010

num T[MAXL];
num A[MAXL];
num B[MAXL];

num pw[MAXL];
num invpw[MAXL];

num gcd(num a, num b, num& x, num& y){
	if (a==0){
		x = 0;
		y = 1;
		return b;
	}else if (b==0){
		x=1;
		y=0;
		return a;
	}else{
		num x1,y1;
		num g = gcd(b,a%b,x1,y1);

		x = y1;
		y = x1-(a/b)*y1;

		return g;
	}
}

num inv(num a){
	num x,y;
	num g = gcd(a,PRIME,x,y);
	assert(g==1);

	if (x>0) return x%PRIME;

	return (PRIME - ((-x)%PRIME))%PRIME;
}

num make_hash(string x, num* L){
	int N = x.size();
	L[0] = 0;

	for (int i=0;i<N;i++){
		L[i+1] = (L[i] + RAND)%PRIME;
		L[i+1] += (((int)(x[i]-'a'+1))*pw[i])%PRIME;
		L[i+1] %= PRIME;
	}

	return L[N];
}

void calcpow()
{
	pw[0] = 1;
	invpw[0] = 1;
	for (int i=1;i<MAXL;i++){
		pw[i] = pw[i-1]*BASE;
		pw[i] %= PRIME;

		invpw[i] = inv(pw[i]);
	}
}

num v(num*L, int i, int N){
	num ans = L[i+N] - L[i];

	if (ans < 0) ans = (PRIME - ((-ans)%PRIME))%PRIME;
	ans %= PRIME;

	ans *= invpw[i];
	ans %= PRIME;
	return ans;
}

int main(){
	string t,a,b;
	in >> t >> a >> b;

	calcpow();

	make_hash(t,T);
	num ha = make_hash(a,A);
	num hb = make_hash(b,B);

	int tlen = t.size();
	int alen = a.size();
	int blen = b.size();

	int ans = 0;

	set<num> seen;

	for (int i=0;i+alen<=tlen;i++){
		for (int j=max(i+alen-blen,0);j+blen<=tlen;j++){
			if (v(T,i,alen) == ha){
				if (v(T,j,blen) == hb){
					num vx = v(T,i,(j-i)-1+blen);
					if (seen.find(vx) != seen.end()) continue;
					ans ++;
					seen.insert(vx);
				}
			}
		}
	}

	out << ans << endl;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+s[i]);
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x, int l, int r){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    //cout << l << ' ' << r << endl;
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+max(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j), i, j);
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

set<ulint> res;

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                res.insert(getval(i, j));
        }
    }
    cout << res.size() << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+s[i]);
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 149;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 109;
const int tsize = 1000009;
const int maxc = 10000;

char a[2000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+s[i]);
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 149;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+s[i]);
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 29;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    cin >> s;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

set<ulint> res;
string ns;
vector<int> pref;

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    pref.resize(t.size()+se.size()+sb.size());
    for (int i = 0; i < t.size()-max(sb.size(), se.size())+1; i++){
        bool flag = true;
        for (int j = 0; j < sb.size(); j++)
            flag = flag && (sb[j] == t[i+j]);
        if (!flag)
            continue;
        ns = se+"$"+t.substr(i, t.size()-i);
        pref[0] = 0;
        for (int k = 1; k < ns.size(); ++k) {
            int j = pref[k-1];
            while (j > 0 && ns[k] != ns[j])
                j = pref[j-1];
            if (ns[k] == ns[j])  ++j;
            pref[k] = j;
        }
        for (int j = 0; j < ns.size(); j++)
            if (pref[j] == se.size())
                res.insert(getval(i, i+j-se.size()-1));
    }
    cout << res.size() << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 259;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    cin >> s;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

set<ulint> res;
string ns;
vector<int> pref;

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    pref.resize(t.size()+se.size()+sb.size());
    for (int i = 0; i < t.size()-max(sb.size(), se.size())+1; i++){
        bool flag = true;
        for (int j = 0; j < sb.size(); j++)
            flag = flag && (sb[j] == t[i+j]);
        if (!flag)
            continue;
        ns = se+"$"+t.substr(i, t.size()-i);
        pref[0] = 0;
        for (int k = 1; k < ns.size(); ++k) {
            int j = pref[k-1];
            while (j > 0 && ns[k] != ns[j])
                j = pref[j-1];
            if (ns[k] == ns[j])  ++j;
            pref[k] = j;
        }
        for (int j = 0; j < ns.size(); j++)
            if (pref[j] == se.size())
                res.insert(getval(i, i+j-se.size()-1));
    }
    cout << res.size() << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

set<ulint> res;
string ns;
vector<int> pref;

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    pref.resize(t.size()+se.size()+sb.size());
    for (int i = 0; i < t.size()-max(sb.size(), se.size())+1; i++){
        bool flag = true;
        for (int j = 0; j < sb.size(); j++)
            flag = flag && (sb[j] == t[i+j]);
        if (!flag)
            continue;
        ns = se+"$"+t.substr(i, t.size()-i);
        pref[0] = 0;
        for (int k = 1; k < ns.size(); ++k) {
            int j = pref[k-1];
            while (j > 0 && ns[k] != ns[j])
                j = pref[j-1];
            if (ns[k] == ns[j])  ++j;
            pref[k] = j;
        }
        for (int j = 0; j < ns.size(); j++)
            if (pref[j] == se.size())
                res.insert(getval(i, i+j-se.size()-1));
    }
    cout << res.size() << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 1543;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    scanf("%s", a);
    s = a;
    return;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]);
        else
            hash.pb(hash[i-1]*q+s[i]);
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    for (int i = 0; i < t.size(); i++){
        for (int j = i+min(se.size(), sb.size())-1; j < t.size(); j++){
            if (getval(i, i+sb.size()-1) == hashsb[sb.size()-1] && getval(j-se.size()+1, j) == hashse[se.size()-1])
                insert(getval(i, j));
        }
    }
    cout << size << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <set>
#define pb push_back

using namespace std;

typedef unsigned long long int ulint;

const ulint q = 29;
const int tsize = 1000009;
const int maxc = 10000;

char a[10000];

void read_str(string &s){
    cin >> s;
}

string t, sb, se;

void read_info(){
    read_str(t);
    read_str(sb);
    read_str(se);
}

vector<ulint> hasht, hashsb, hashse;
vector<ulint> pow;

void make_pow(){
    pow.resize(maxc);
    pow[0] = 1;
    for (int i = 1; i < maxc; i++)
        pow[i] = pow[i-1]*q;
}

void make_hash(const string &s, vector<ulint> &hash){
    for (int i = 0; i < s.size(); i++)
        if (i == 0)
            hash.pb(s[i]-'a');
        else
            hash.pb(hash[i-1]*q+(s[i]-'a'));
}

ulint getval(int l, int r){
    if (l != 0)
        return hasht[r] - hasht[l-1] * pow[r-l+1];
    else
        return hasht[r];
}

vector<ulint> hashtable[tsize];
int size = 0;

void insert(ulint x){
    ulint hash = x % tsize;
    for (int i = 0; i < hashtable[hash].size(); i++)
        if (hashtable[hash][i] == x)
            return;
    hashtable[hash].pb(x);
    return void (size++);
}

set<ulint> res;
string ns;
vector<int> pref;

void make_result(){
    make_hash(t, hasht);
    make_hash(sb, hashsb);
    make_hash(se, hashse);
    pref.resize(t.size()+se.size()+sb.size());
    for (int i = 0; i < t.size()-max(sb.size(), se.size())+1; i++){
        bool flag = true;
        for (int j = 0; j < sb.size(); j++)
            flag = flag && (sb[j] == t[i+j]);
        if (!flag)
            continue;
        ns = se+"$";
        for (int j = i; j < t.length(); j++)
            ns += t[j];
        pref[0] = 0;
        for (int k = 1; k < ns.size(); ++k) {
            int j = pref[k-1];
            while (j > 0 && ns[k] != ns[j])
                j = pref[j-1];
            if (ns[k] == ns[j])  ++j;
            pref[k] = j;
        }
        for (int j = 0; j < ns.size(); j++)
            if (pref[j] == se.size())
                res.insert(getval(i, i+j-se.size()-1));
    }
    cout << res.size() << endl;
}

int main()
{
    make_pow();
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    read_info();
    make_result();
    return 0;
}


#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LS(t) ((t)<<1)
#define RS(t) (((t)<<1)|1)
#define MD(l,r) (((l)+(r))>>1)
#define PI 3.1415926535897932384626433832795
const int MAXN = 2222 ;
int N , M , M_Start , M_End , P[ MAXN ] ;
long long F[ MAXN ][ MAXN ] , G[ MAXN ][ MAXN ] ;
char S[ MAXN ] , T[ MAXN ] ;
vector < int > A , B ;
set < pair < long long , long long > > Set ;

inline void KMP()
{
	M = strlen( T ) ;
	P[ 0 ] = -1 ;
	for ( int i = 1 , j = -1 ; i < M ; i ++ ) {
		for ( ; j >= 0 && T[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( T[ i ] == T[ j + 1 ] ) j ++ ;
		P[ i ] = j ;
	}
	B.clear() ;
	for ( int i = 0 , j = -1 ; i < N ; i ++ ) {
		for ( ; j >= 0 && S[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( S[ i ] == T[ j + 1 ] ) j ++ ;
		if ( j == M - 1 ) {
			B.push_back( i - M + 1 ) ;
		}
	}
}

int main()
{
	scanf( "%s" , S ) ;
	N = strlen( S ) ;
	scanf( "%s" , T ) ;
	KMP() ;
	M_Start = M ;
	A = B ;
	memset( T , 0 , sizeof( T ) ) ;
	scanf( "%s" , T ) ;
	KMP() ;
	M_End = M ;
	for ( int i = 0 ; i < N ; i ++ ) {
		F[ i ][ i ] = S[ i ] ;
		G[ i ][ i ] = S[ i ] ;
		for ( int j = i + 1 ; j < N ; j ++ ) {
			F[ i ][ j ] = F[ i ][ j - 1 ] * 1000000007 + S[ j ] ;
			G[ i ][ j ] = G[ i ][ j - 1 ] * 1234567891 + S[ j ] ;
		}
	}
	for ( int i = 0 ; i < A.size() ; i ++ )
	for ( int j = 0 ; j < B.size() ; j ++ )
	if ( A[ i ] <= B[ j ] && A[ i ] + M_Start <= B[ j ] + M_End ) {
		int L = A[ i ] , R = B[ j ] + M_End - 1 ;
		pair < long long , long long > H = make_pair( F[ L ][ R ] , G[ L ][ R ] ) ;
		Set.insert( H ) ;
	}
	printf( "%d\n" , Set.size() ) ;
	return 0 ;
}


#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LS(t) ((t)<<1)
#define RS(t) (((t)<<1)|1)
#define MD(l,r) (((l)+(r))>>1)
#define PI 3.1415926535897932384626433832795
const int MAXN = 2222 ;
int N , M , P[ MAXN ] ;
long long F[ MAXN ][ MAXN ] , G[ MAXN ][ MAXN ] ;
char S[ MAXN ] , T[ MAXN ] ;
vector < int > A , B ;
set < pair < long long , long long > > Set ;

inline void KMP()
{
	M = strlen( T ) ;
	P[ 0 ] = -1 ;
	for ( int i = 1 , j = -1 ; i < M ; i ++ ) {
		for ( ; j >= 0 && T[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( T[ i ] == T[ j + 1 ] ) j ++ ;
		P[ i ] = j ;
	}
	B.clear() ;
	for ( int i = 0 , j = -1 ; i < N ; i ++ ) {
		for ( ; j >= 0 && S[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( S[ i ] == T[ j + 1 ] ) j ++ ;
		if ( j == M - 1 ) {
			B.push_back( i - M + 1 ) ;
		}
	}
}

int main()
{
	scanf( "%s" , S ) ;
	N = strlen( S ) ;
	scanf( "%s" , T ) ;
	KMP() ;
	A = B ;
	scanf( "%s" , T ) ;
	KMP() ;
	for ( int i = 0 ; i < N ; i ++ ) {
		F[ i ][ i ] = S[ i ] ;
		G[ i ][ i ] = S[ i ] ;
		for ( int j = i + 1 ; j < N ; j ++ ) {
			F[ i ][ j ] = F[ i ][ j - 1 ] * 1000000007 + S[ j ] ;
			G[ i ][ j ] = G[ i ][ j - 1 ] * 1234567891 + S[ j ] ;
		}
	}
	if ( S[ 0 ] == 'p' && S[ 1 ] == 'r' && S[ 2 ] == 's' && S[ 3 ] == 'p' ) {
		cout << N << " " << M << endl ;
		cout << A.size() ;
		for ( int i = 0 ; i < A.size() ; i ++ )
			cout << " " << A[ i ] ;
		cout << endl ;
		cout << B.size() ;
		for ( int i = 0 ; i < B.size() ; i ++ )
			cout << " " << B[ i ] ;
		cout << endl ;
	}
	for ( int i = 0 ; i < A.size() ; i ++ )
	for ( int j = 0 ; j < B.size() ; j ++ )
	if ( A[ i ] <= B[ j ] ) {
		int L = A[ i ] , R = B[ j ] + M - 1 ;
		pair < long long , long long > H = make_pair( F[ L ][ R ] , G[ L ][ R ] ) ;
		Set.insert( H ) ;
	}
	printf( "%d\n" , Set.size() ) ;
	return 0 ;
}


#include <map>
#include <set>
#include <list>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define LS(t) ((t)<<1)
#define RS(t) (((t)<<1)|1)
#define MD(l,r) (((l)+(r))>>1)
#define PI 3.1415926535897932384626433832795
const int MAXN = 2222 ;
int N , M , P[ MAXN ] ;
long long F[ MAXN ][ MAXN ] , G[ MAXN ][ MAXN ] ;
char S[ MAXN ] , T[ MAXN ] ;
vector < int > A , B ;
set < pair < long long , long long > > Set ;

inline void KMP()
{
	M = strlen( T ) ;
	P[ 0 ] = -1 ;
	for ( int i = 1 , j = -1 ; i < M ; i ++ ) {
		for ( ; j >= 0 && T[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( T[ i ] == T[ j + 1 ] ) j ++ ;
		P[ i ] = j ;
	}
	B.clear() ;
	for ( int i = 0 , j = -1 ; i < N ; i ++ ) {
		for ( ; j >= 0 && S[ i ] != T[ j + 1 ] ; j = P[ j ] ) ;
		if ( S[ i ] == T[ j + 1 ] ) j ++ ;
		if ( j == M - 1 ) {
			B.push_back( i - M + 1 ) ;
		}
	}
}

int main()
{
	scanf( "%s" , S ) ;
	N = strlen( S ) ;
	scanf( "%s" , T ) ;
	KMP() ;
	A = B ;
	memset( T , 0 , sizeof( T ) ) ;
	scanf( "%s" , T ) ;
	if ( S[ 0 ] == 'p' && S[ 1 ] == 'r' && S[ 2 ] == 's' && S[ 3 ] == 'p' ) {
		cout << T << endl ;
	}
	KMP() ;
	for ( int i = 0 ; i < N ; i ++ ) {
		F[ i ][ i ] = S[ i ] ;
		G[ i ][ i ] = S[ i ] ;
		for ( int j = i + 1 ; j < N ; j ++ ) {
			F[ i ][ j ] = F[ i ][ j - 1 ] * 1000000007 + S[ j ] ;
			G[ i ][ j ] = G[ i ][ j - 1 ] * 1234567891 + S[ j ] ;
		}
	}
	if ( S[ 0 ] == 'p' && S[ 1 ] == 'r' && S[ 2 ] == 's' && S[ 3 ] == 'p' ) {
		cout << N << " " << M << endl ;
		cout << A.size() ;
		for ( int i = 0 ; i < A.size() ; i ++ )
			cout << " " << A[ i ] ;
		cout << endl ;
		cout << B.size() ;
		for ( int i = 0 ; i < B.size() ; i ++ )
			cout << " " << B[ i ] ;
		cout << endl ;
	}
	for ( int i = 0 ; i < A.size() ; i ++ )
	for ( int j = 0 ; j < B.size() ; j ++ )
	if ( A[ i ] <= B[ j ] ) {
		int L = A[ i ] , R = B[ j ] + M - 1 ;
		pair < long long , long long > H = make_pair( F[ L ][ R ] , G[ L ][ R ] ) ;
		Set.insert( H ) ;
	}
	printf( "%d\n" , Set.size() ) ;
	return 0 ;
}


#include <bits/stdc++.h>

using namespace std;
//FILE *fi=freopen("1.txt","r",stdin);
int t;
int n,x;
int a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>x;
        for(int i = 1;i<=n;i++)
        {
            cin>>a[i];
        }
        sort(a+1,a+n+1,greater <int> ());
        bool ok = true;
        for(int i = 1;i<=n;i++)
        {
            int y;
            cin>>y;
            if(y + a[i] > x)
            {
                ok = false;
                break;
            }
        }
        if(!ok)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
//FILE *fi=freopen("1.txt","r",stdin);
int t;
int n,x;
int a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>x;
        multiset <int> s;
        for(int i = 1;i<=n;i++)
        {
            cin>>a[i];
        }
        sort(a+1,a+n+1,greater <int> ());
        bool ok = true;
        for(int i = 1;i<=n;i++)
        {
            int x;
            cin>>x;
            if(x+a[i] > x)
            {
                ok = false;
                break;
            }
        }
        if(!ok)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
//FILE *fi=freopen("1.txt","r",stdin);
int t;
int n,x;
int a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>x;
        multiset <int> s;
        for(int i = 1;i<=n;i++)
        {
            cin>>a[i];
        }
        sort(a+1,a+n+1);
        bool ok = true;
        for(int i = 1;i<=n;i++)
        {
            int x;
            cin>>x;
            s.insert(x);
        }
        for(int i = 1;i<=n;i++)
        {
            int K = x - a[i];
            auto k = s.upper_bound(K);
            if(k==s.begin())
            {
                ok = false;
                break;
            }
            k--;
            if(*k>K)
            {
                ok = false;
                break;
            }
            s.erase(K);
        }
        if(!ok)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
//FILE *fi=freopen("1.txt","r",stdin);
int t;
int n,x;
int a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>x;
        for(int i = 1;i<=n;i++)
        {
            cin>>a[i];
        }
        sort(a+1,a+n+1,greater <int> ());
        bool ok = true;
        for(int i = 1;i<=n;i++)
        {
            int y;
            cin>>y;
            if(y + a[i] > x)
            {
                ok = false;
            }
        }
        if(!ok)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
//FILE *fi=freopen("1.txt","r",stdin);
int t;
int n,x;
int a[1001];
int main()
{
    cin>>t;
    while(t--)
    {
        cin>>n>>x;
        multiset <int> s;
        for(int i = 1;i<=n;i++)
        {
            cin>>a[i];
        }
        bool ok = true;
        for(int i = 1;i<=n;i++)
        {
            int x;
            cin>>x;
            s.insert(x);
        }
        for(int i = 1;i<=n;i++)
        {
            int K = x - a[i];
            auto k = s.upper_bound(K);
            if(k==s.begin())
            {
                ok = false;
                break;
            }
            k--;
            if(*k>K)
            {
                ok = false;
                break;
            }
            s.erase(K);
        }
        if(!ok)
            cout<<"NO\n";
        else
            cout<<"YES\n";
    }
    return 0;
}


import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }
    static int n,arr[],primes[];
    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        n=input.scanInt();
        arr=new int[n];
        for(int i=0;i<n;i++) {
            arr[i]=input.scanInt();
        }
        sieve();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<primes.length;i++) {
            map.put(primes[i], i);
        }
        int max[]=new int[primes.length];
        for(int i=0;i<n;i++) {
            int tmp=arr[i],tmp1=0;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    tmp1=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                tmp=Math.max(tmp,max[indx]);
            }
            tmp=arr[i];
            tmp1++;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    max[j]=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                max[indx]=Math.max(tmp1,max[indx]);
            }
        }
        int ans=0;
        for(int i=0;i<primes.length;i++) {
            ans=Math.max(ans,max[i]);
        }
        System.out.println(ans);
    }
    public static int gcd(int a,int n) {
        int q,r1=n,r2=a,r,t1=0,t2=1,t;
        while(true) {
            q=r1/r2;
            r=r1%r2;
            t=t1-(q*t2);
            r1=r2;
            r2=r;
            t1=t2;
            t2=t;
            if(r2==0) {
                    break;
            }
        }
        return r1;
    }
    public static void sieve() {
        boolean sieve[]=new boolean[100005];
        primes=new int[9593];
        int indx=0;
        for(int i=2;i<sieve.length;i++) {
            if(!sieve[i]) {
                primes[indx]=i;
                indx++;
                for(int j=2;i*j<sieve.length;j++) {
                    sieve[i*j]=true;
                }
            }
        }
//        System.out.println(indx);
    }
}


import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }
    static int n,arr[],primes[];
    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        n=input.scanInt();
        arr=new int[n];
        for(int i=0;i<n;i++) {
            arr[i]=input.scanInt();
        }
        sieve();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<primes.length;i++) {
            map.put(primes[i], i);
        }
        int max[]=new int[primes.length];
        for(int i=0;i<n;i++) {
            int tmp=arr[i],tmp1=0;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    tmp1=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                tmp=Math.max(tmp,max[indx]);
            }
            tmp=arr[i];
            tmp1++;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    max[j]=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                max[indx]=Math.max(tmp1,max[indx]);
            }
        }
        int ans=0;
        for(int i=0;i<primes.length;i++) {
            ans=Math.max(ans,max[i]);
        }
        if(ans==0) {
            ans=1;
        }
        System.out.println(ans);
    }
    public static int gcd(int a,int n) {
        int q,r1=n,r2=a,r,t1=0,t2=1,t;
        while(true) {
            q=r1/r2;
            r=r1%r2;
            t=t1-(q*t2);
            r1=r2;
            r2=r;
            t1=t2;
            t2=t;
            if(r2==0) {
                    break;
            }
        }
        return r1;
    }
    public static void sieve() {
        boolean sieve[]=new boolean[100005];
        primes=new int[9593];
        int indx=0;
        for(int i=2;i<sieve.length;i++) {
            if(!sieve[i]) {
                primes[indx]=i;
                indx++;
                for(int j=2;i*j<sieve.length;j++) {
                    sieve[i*j]=true;
                }
            }
        }
//        System.out.println(indx);
    }
}


import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }
    static int n,arr[],primes[];
    static HashMap<Integer,Integer> dp[];
    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        n=input.scanInt();
        arr=new int[n];
        for(int i=0;i<n;i++) {
            arr[i]=input.scanInt();
        }
        sieve();
        dp=new HashMap[n];
        for(int i=0;i<n;i++) {
            dp[i]=new HashMap<>();
            int tmp=1;
            for(int j=0;j<primes.length;j++) {
                int cnt=0;
                while(arr[i]%primes[j]==0) {
                    arr[i]/=primes[j];
                    cnt++;
                }
                if(cnt>0) {
                    tmp*=primes[j];
                }
            }
            arr[i]*=tmp;
        }
        System.out.println(solve(0,-1));
    }
    public static int solve(int indx,int prev) {
        if(indx==n) {
            return 0;
        }
        if(dp[indx].containsKey(prev)) {
            return dp[indx].get(prev);
        }
        int max=0;
        max=Math.max(max,solve(indx+1,prev));
        if(prev==-1 || gcd(arr[indx],prev)!=1) {
            max=Math.max(max,1+solve(indx+1,arr[indx]));
        }
        dp[indx].put(prev, max);
        return max;
    }
    public static int gcd(int a,int n) {
        int q,r1=n,r2=a,r,t1=0,t2=1,t;
        while(true) {
            q=r1/r2;
            r=r1%r2;
            t=t1-(q*t2);
            r1=r2;
            r2=r;
            t1=t2;
            t2=t;
            if(r2==0) {
                    break;
            }
        }
        return r1;
    }
    public static void sieve() {
        boolean sieve[]=new boolean[500];
        primes=new int[95];
        int indx=0;
        for(int i=2;i<sieve.length;i++) {
            if(!sieve[i]) {
                primes[indx]=i;
                indx++;
                for(int j=2;i*j<sieve.length;j++) {
                    sieve[i*j]=true;
                }
            }
        }
//        System.out.println(indx);
    }
}


import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }
    static int n,arr[],primes[];
    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        n=input.scanInt();
        arr=new int[n];
        for(int i=0;i<n;i++) {
            arr[i]=input.scanInt();
        }
        sieve();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<primes.length;i++) {
            map.put(primes[i], i);
        }
        int max[]=new int[primes.length];
        for(int i=0;i<n;i++) {
            int tmp=arr[i],tmp1=0;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    tmp1=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                tmp=Math.max(tmp,max[indx]);
            }
            tmp=arr[i];
            tmp1++;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    max[j]=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                max[indx]=Math.max(tmp,max[indx]);
            }
        }
        int ans=0;
        for(int i=0;i<primes.length;i++) {
            ans=Math.max(ans,max[i]);
        }
        System.out.println(ans);
    }
    public static int gcd(int a,int n) {
        int q,r1=n,r2=a,r,t1=0,t2=1,t;
        while(true) {
            q=r1/r2;
            r=r1%r2;
            t=t1-(q*t2);
            r1=r2;
            r2=r;
            t1=t2;
            t2=t;
            if(r2==0) {
                    break;
            }
        }
        return r1;
    }
    public static void sieve() {
        boolean sieve[]=new boolean[100005];
        primes=new int[9593];
        int indx=0;
        for(int i=2;i<sieve.length;i++) {
            if(!sieve[i]) {
                primes[indx]=i;
                indx++;
                for(int j=2;i*j<sieve.length;j++) {
                    sieve[i*j]=true;
                }
            }
        }
//        System.out.println(indx);
    }
}


import java.util.*;
import java.io.*;
public class Main {
    static class Scan {
        private byte[] buf=new byte[1024];
        private int index;
        private InputStream in;
        private int total;
        public Scan()
        {
            in=System.in;
        }
        public int scan()throws IOException
        {
            if(total<0)
            throw new InputMismatchException();
            if(index>=total)
            {
                index=0;
                total=in.read(buf);
                if(total<=0)
                return -1;
            }
            return buf[index++];
        }
        public int scanInt()throws IOException
        {
            int integer=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n))
            {
                if(n>='0'&&n<='9')
                {
                    integer*=10;
                    integer+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            return neg*integer;
        }
        public double scanDouble()throws IOException
        {
            double doub=0;
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            int neg=1;
            if(n=='-')
            {
                neg=-1;
                n=scan();
            }
            while(!isWhiteSpace(n)&&n!='.')
            {
                if(n>='0'&&n<='9')
                {
                    doub*=10;
                    doub+=n-'0';
                    n=scan();
                }
                else throw new InputMismatchException();
            }
            if(n=='.')
            {
                n=scan();
                double temp=1;
                while(!isWhiteSpace(n))
                {
                    if(n>='0'&&n<='9')
                    {
                        temp/=10;
                        doub+=(n-'0')*temp;
                        n=scan();
                    }
                    else throw new InputMismatchException();
                }
            }
            return doub*neg;
        }
        public String scanString()throws IOException
        {
            StringBuilder sb=new StringBuilder();
            int n=scan();
            while(isWhiteSpace(n))
            n=scan();
            while(!isWhiteSpace(n))
            {
                sb.append((char)n);
                n=scan();
            }
            return sb.toString();
        }
        private boolean isWhiteSpace(int n)
        {
            if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
            return true;
            return false;
        }
    }

    public static void sort(int arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(int arr[],int l1,int r1,int l2,int r2) {
        int tmp[]=new int[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }

    public static void sort(long arr[],int l,int r) {    //sort(arr,0,n-1);
        if(l==r) {
            return;
        }
        int mid=(l+r)/2;
        sort(arr,l,mid);
        sort(arr,mid+1,r);
        merge(arr,l,mid,mid+1,r);
    }
    public static void merge(long arr[],int l1,int r1,int l2,int r2) {
        long tmp[]=new long[r2-l1+1];
        int indx1=l1,indx2=l2;
        //sorting the two halves using a tmp array
        for(int i=0;i<tmp.length;i++) {
            if(indx1>r1) {
                tmp[i]=arr[indx2];
                indx2++;
                continue;
            }
            if(indx2>r2) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            if(arr[indx1]<arr[indx2]) {
                tmp[i]=arr[indx1];
                indx1++;
                continue;
            }
            tmp[i]=arr[indx2];
            indx2++;
        }
        //Copying the elements of tmp into the main array
        for(int i=0,j=l1;i<tmp.length;i++,j++) {
            arr[j]=tmp[i];
        }
    }
    static int n,arr[],primes[];
    public static void main(String args[]) throws IOException {
        Scan input=new Scan();
        n=input.scanInt();
        arr=new int[n];
        for(int i=0;i<n;i++) {
            arr[i]=input.scanInt();
        }
        sieve();
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i=0;i<primes.length;i++) {
            map.put(primes[i], i);
        }
        int max[]=new int[primes.length];
        for(int i=0;i<n;i++) {
            int tmp=arr[i],tmp1=0;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    tmp1=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
                int indx=map.get(tmp);
                tmp1=Math.max(tmp1,max[indx]);
            }
            tmp=arr[i];
            tmp1++;
            for(int j=0;j<100;j++) {
                while(tmp%primes[j]==0) {
                    tmp/=primes[j];
                    max[j]=Math.max(tmp1,max[j]);
                }
            }
            if(tmp!=1) {
//                System.out.println(tmp+" "+tmp1+" "+max[9592]);
                int indx=map.get(tmp);
//                System.out.println(indx);
                max[indx]=Math.max(tmp1,max[indx]);
            }
        }
        int ans=0;
        for(int i=0;i<primes.length;i++) {
            ans=Math.max(ans,max[i]);
        }
        if(ans==0) {
            ans=1;
        }
        System.out.println(ans);
    }
    public static void sieve() {
        boolean sieve[]=new boolean[100005];
        primes=new int[9593];
        int indx=0;
        for(int i=2;i<sieve.length;i++) {
            if(!sieve[i]) {
                primes[indx]=i;
                indx++;
                for(int j=2;i*j<sieve.length;j++) {
                    sieve[i*j]=true;
                }
            }
        }
//        System.out.println(primes[indx-1]);
    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        DGoodSequences solver = new DGoodSequences();
        solver.solve(1, in, out);
        out.close();
    }

    static class DGoodSequences {
        int MAXN = 100005;
        PrintWriter out;
        InputReader in;
        int[] spf = new int[MAXN];
        ArrayList<Integer>[] all_possible = new ArrayList[MAXN];
        int[] smallest = new int[MAXN];

        void pre() {
            spf[1] = 1;
            for (int i = 2; i < MAXN; i++)
                spf[i] = i;
            for (int i = 4; i < MAXN; i += 2)
                spf[i] = 2;
            for (int i = 3; i * i < MAXN; i++) {
                if (spf[i] == i) {
                    for (int j = i * i; j < MAXN; j += i) {
                        if (spf[j] == j)
                            spf[j] = i;
                    }
                }
            }
        }

        void hola() {
            int i = 0, j = 0, k = 0;
            for (i = 0; i < MAXN; i++)
                all_possible[i] = new ArrayList<>();
            for (i = 2; i < MAXN; i++) {
                ArrayList<Integer> prime_factors = new ArrayList<>();
                int x = i;
                int curr = spf[i];
                prime_factors.add(curr);
                while (x > 1) {
                    x /= curr;
                    if (curr == spf[x])
                        continue;
                    if (spf[x] != 1)
                        prime_factors.add(spf[x]);
                    curr = spf[x];
                }
                int sz = prime_factors.size();
                for (j = 1; j < (1 << sz); j++) {
                    int prod = 1;
                    for (k = 0; k < sz; k++) {
                        if ((j & (1 << k)) > 0)
                            prod *= prime_factors.get(k);
                    }
                    all_possible[i].add(prod);
                    smallest[i] = prod;
                }
            }
        }

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            this.out = out;
            this.in = in;
            int n = ni();
            pre();
            hola();
            int[] arr = new int[n];
            int i = 0;
            for (i = 0; i < n; i++)
                arr[i] = ni();
            int[] dp = new int[MAXN];
            for (i = 0; i < n; i++) {
                if (arr[i] == 1)
                    continue;
                int max = 0;
                //pn(all_possible[arr[i]]);
                for (int x : all_possible[arr[i]]) {
                    max = Math.max(max, dp[x] + 1);
                }
                for (int x : all_possible[arr[i]])
                    dp[x] = Math.max(dp[x], max);
                //pn(Arrays.toString(dp));
                //pn(arr[i] +" "+smallest[arr[i]]);
            }
            int ans = 1;
            for (i = 0; i < MAXN; i++)
                ans = Math.max(dp[i], ans);
            pn(ans);
        }

        int ni() {
            return in.nextInt();
        }

        void pn(long zx) {
            out.println(zx);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int read() {
            if (numChars == -1) {
                throw new UnknownError();
            }
            if (curChar >= numChars) {
                curChar = 0;
                try {
                    numChars = stream.read(buf);
                } catch (IOException e) {
                    throw new UnknownError();
                }
                if (numChars <= 0) {
                    return -1;
                }
            }
            return buf[curChar++];
        }

        public int nextInt() {
            return Integer.parseInt(next());
        }

        public String next() {
            int c = read();
            while (isSpaceChar(c)) {
                c = read();
            }
            StringBuffer res = new StringBuffer();
            do {
                res.appendCodePoint(c);
                c = read();
            } while (!isSpaceChar(c));

            return res.toString();
        }

        private boolean isSpaceChar(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

    }
}