// Liviu Ciortea, Bucuresti, Romania (TopCoder handle: _efer_)
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <list>
#include <queue>
#include <utility>
#include <string>
#include <ctime>
using namespace std;
#define REP(i, N) for (int i = 0; i < (N); ++i)
#define REPV(i, a, b) for (int i = (a); i <= (b); ++i)
#define REPD(i, N) for (int i = (N)-1; i >= 0; --i)
#define REPVD(i, b, a) for (int i = (b); i >= (a); --i)
#define REPIT(it, v) for (it = (v).begin(); it != (v).end(); ++it)
#define SZ(a) ((int)(a).size())
#define MP make_pair
#define PB push_back
#define X first
#define Y second
#define ALL(a) (a).begin(), (a).end()
#define CLR(a) memset((a), 0, sizeof(a))
#define MSET(a, v) memset((a), v, sizeof(a))
#define CPY(dest, source) memcpy(dest, source, sizeof(dest))
typedef long long LL;
typedef vector<int> VI;
typedef vector<string> VS;
typedef pair<int, int> PII;
const int MAXL = 32;
const int MAX_TOTAL = 576000;
const int MAXS = 10240000;
const int NUM_LETTERS = 3;
char word[MAXL];
char text[MAXS];
// radacina este in nodul 0
int adj[MAX_TOTAL][3], C;
int go[MAX_TOTAL], paps[MAX_TOTAL], ch[MAX_TOTAL], memo_go[MAX_TOTAL][3];
char terminal[MAX_TOTAL];
void put_tree(int node, char* word) {
while (*word != '\n') {
//if (*word) {
int nxt = word[0] - 'a';
if (adj[node][nxt] == -1) {
ch[++C] = nxt;
adj[node][nxt] = C;
paps[C] = node;
//memo_go[node][nxt] = C;
}
//put_tree(adj[node][nxt], word+1, depth+1);
//} else {
node = adj[node][nxt];
word++;
}
terminal[node] = 1;
}
int Q[MAX_TOTAL];
void build_automaton() {
//deque<int> Q;
paps[0] = go[0] = -1;
int lo = 0, hi = 0;
REP(i, NUM_LETTERS) {
if (adj[0][i] != -1) {
//paps[adj[0][i]] = 0;
//Q.PB(adj[0][i]);
Q[hi++] = adj[0][i];
}
}
//while (!Q.empty()) {
while (lo < hi) {
//int r = Q.front(); Q.pop_front();
int r = Q[lo++];
int n = paps[r];
while (n && adj[go[n]][ch[r]] == -1) n = go[n];
if (n) go[r] = adj[go[n]][ch[r]];
else go[r] = 0;
//memo_go[paps[r]][ch[r]] = adj[paps[r]][ch[r]] == -1 ? adj[go[r]][ch[r]] : r;
//REP(i, NUM_LETTERS) {
// if (adj[r][i] != -1) {
// //paps[adj[r][i]] = r;
// //Q.PB(adj[r][i]);
// Q[hi++] = adj[r][i];
// }
// //int n = r;
// //while (n && adj[n][i] == -1) n = go[n];
// //if (adj[n][i] != -1) n = adj[n][i];
// //memo_go[r][i] = n;
//}
if (adj[r][0] != -1) Q[hi++] = adj[r][0];
if (adj[r][1] != -1) Q[hi++] = adj[r][1];
if (adj[r][2] != -1) Q[hi++] = adj[r][2];
}
REP(r, C+1) {
//REP(nxt, 3) {
// int n = r;
// while (n && adj[n][nxt] == -1) n = go[n];
// if (n || adj[n][nxt] != -1) n = adj[n][nxt];
// memo_go[r][nxt] = n;
//}
int n = r;
while (n && adj[n][0] == -1) n = go[n];
if (n || adj[n][0] != -1) n = adj[n][0];
memo_go[r][0] = n;
n = r;
while (n && adj[n][1] == -1) n = go[n];
if (n || adj[n][1] != -1) n = adj[n][1];
memo_go[r][1] = n;
n = r;
while (n && adj[n][2] == -1) n = go[n];
if (n || adj[n][2] != -1) n = adj[n][2];
memo_go[r][2] = n;
}
}
void solve1() {
//int tmr = 0;
//time_t start = clock();
freopen("abc2.in", "rt", stdin);
freopen("abc2.out", "wt", stdout);
//scanf("%s", text);
fgets(text, MAXS, stdin);
MSET(adj, -1);
MSET(memo_go, -1);
//while (scanf("%s", word) == 1) put_tree(0, word);
for (;;) {
if (fgets(word, MAXL, stdin) == NULL) break;
put_tree(0, word);
}
build_automaton();
//fprintf(stderr, "%lf\n", (double)(clock() - start) / CLK_TCK);
int S = strlen(text) - 1, n = 0, res = 0;
REP(i, S) {
n = memo_go[n][text[i] - 'a'];
if (terminal[n]) res++;
}
printf("%d\n", res);
//int clicks = clock() - start;
//fprintf(stderr, "%d, clicks = %d, tmr = %d, %lf\n", C, clicks, tmr, (double)(clicks) / CLK_TCK);
}
const int MAXH = 1<<20;
const int MAXN = 51200;
const int MAXHM = MAXH - 1;
int N, M;
char buff[MAXL];
//LL * hash[MAXH];
int first[MAXH], next[MAXN];
LL val[MAXN];
int hashcode(LL num) {
//unsigned int h = 0;
//int i;
//REP(i, M) {
// h = ((h << 5) + h) + (num & 3);
// num >>= 2;
//}
return num & MAXHM;
//return h % MAXH;
//return num % MAXH;
}
int find(LL num) {
int ind = hashcode(num), r = first[ind];
//vector<LL>& h = hash[ind];
//REP(i, SZ(h)) if (h[i] == num) return 1;
//REP(i, size[ind]) if (hash[ind][i] == num) return 1;
while (r != -1) {
if (val[r] == num) return 1;
r = next[r];
}
return 0;
}
void puthash(LL num) {
int ind = hashcode(num);
if (!find(num)) {
//if (!size[ind]) hash[ind] = new LL[MAXSLOTS];
//assert(size[ind]+1 < MAXSLOTS);
//hash[ind][size[ind]++] = num;
//hash[ind].PB(num);
next[C] = first[ind];
first[ind] = C;
val[C] = num;
C++;
}
}
LL encode() {
M = strlen(buff) - 1;
LL res = 0;
//REP(i, M) res = (res << 2) | (buff[i] - 'a');
REP(i, M) res += (res<<1) + buff[i] - 'a';
return res;
}
//int putend() {
// int p = 0, start = max(M-10, 0), i;
// REPV(i, start, M-1) p += (p<<1) + buff[i] - 'a';
// have[p] = true;
// return p;
//}
void parsewords() {
//scanf("%s", str);
fgets(text, MAXS, stdin);
for (;;) {
if (!fgets(buff, MAXL, stdin)) break;
puthash(encode());
//putend();
N++;
}
}
void solve2() {
//time_t start = clock();
freopen("abc2.in", "rt", stdin);
freopen("abc2.out", "wt", stdout);
MSET(first, -1);
MSET(next, -1);
//random_shuffle(primes, primes + (sizeof(primes) / sizeof(primes[0])));
parsewords();
//fprintf(stderr, "%lf\n", 1.0 * (clock() - start) / CLK_TCK);
int S = strlen(text) - 1;
if (S < M) {
printf("0\n");
return;
}
//REP(i, MAXH) if (size[i] > 4) fprintf(stderr, "%d ", size[i]);
//LL mask = 0;
//REP(i, M) mask = (mask << 2) | 3;
strncpy(buff, text, M);
LL curr = encode();
//int end = putend();
LL pw = 1;
REP(i, M-1) pw *= 3;
//int endpw = 1, h = min(M, 10);
//REP(i, h-1) endpw *= 3;
int res = find(curr);
REPV(i, M, S-1) {
//curr = (curr << 2) | (str[i] - 'a');
//curr &= mask;
if (text[i-M] == 'b') curr -= pw;
else if (text[i-M] == 'c') curr -= pw<<1;
curr += (curr<<1) + text[i] - 'a';
//if (str[i-h] == 'b') end -= endpw;
//else if (str[i-h] == 'c') end -= endpw<<1;
//end += (end<<1) + str[i] - 'a';
//if (have[end]) res += find(curr);
if (find(curr)) res++;
}
printf("%d\n", res);
//fprintf(stderr, "%lf\n", 1.0 * (clock() - start) / CLK_TCK);
}
int main() {
srand(time(NULL));
if (rand() & 1) solve1();
else solve2();
return 0;
}