Problem:
G： 検閲により置換 (Censored String)

Problem Statement

You are given the string S, and the set of strings \mathcal P whose size is N. Now we consider applying the following operation to S:

Choose exactly one character in S, and replace it with '*'.

Let s_i be a i-th character of S, S_{ij} be a consecutive substring in S such that S = s_i s_{i+1} $\cdots$ s_j, and p_k as the k-th string of P. Your task is to calculate the minimum number of operations for satisfying the following condition.

For all pairs (S_{ij}, p_k), it is satisfied that S_{ij} \neq p_k.

Input

An input is given in the following format.

S
N
p_1
p_2
$\vdots$
p_N

In line 1, you are given the string S.

In line 2, given an integer N. N means the size of P.

From line 3 to the end, given p_i, the i-th string of P.

Constraints

1 \leq |S| \leq 10^5

1 \leq N \leq 10^5

1 \leq |p_1| + |p_2| + $\cdots$ + |p_N| \leq 10^5

If i \neq j, it is guaranteed that p_i \neq p_j

S, and p_i include lowercase letters only

Output

Print the minimum number of operations in one line.

Sample Input 1

brainfuck
1
fuck

Sample Output 1

1

For example, if you change "brainfuck" into "brainf*ck", you can satisfy the condition. You have to perform operation at least once, and it is the minimum value.

Sample Input 2

aaa
1
a

Sample Output 2

3

You have to operate for all characters.

Sample Input 3

hellshakeyano
3
hell
shake
key

Sample Output 3

2

In this case, for example, if you change "hellshakeyano" into "h*llsha*eyano", you can satisfy the condition. Notice if you replace one character, it might happen that several strings in the set P, which appear as the consecutive substring of S, simultaneously disappear.

Solution in C++11 (judge verdict: Wrong Answer)

#include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


#define NUM 100005

struct Node{
	int parent_id,children[26],suffix_link;
	bool finish_FLG;
	string pattern;
};

int index = 1,table[128];
char buf[NUM],P[NUM];
Node nodes[NUM];
map<string,int> MAP;


int main(){

	//ノードを数字化
	for(int i = 0; i < 26; i++){
		table['a'+i] = i;
	}

	scanf("%s",buf);
	int length;
	for(length = 0; buf[length] != '\0'; length++);

	//★ルートの情報を設定★
	int root = 0;
	nodes[root].pattern = "";

	//トライ木のノードを初期化
	for(int i = 0; i < length; i++){
		nodes[i].parent_id = -1;
		nodes[i].finish_FLG = false;
		nodes[i].suffix_link = root; //siffx_link先はとりあえずrootにしておく
		for(int k = 0; k < 26; k++){
			nodes[i].children[k] = -1;
		}
	}

	int N;
	scanf("%d",&N);


	int tmp_ch,tmp_loc,parent_id,tmp_index;
	string tmp_pattern;

	bool FLG;

	//トライ木を構成する
	for(int loop = 0; loop < N; loop++){

		scanf("%s",P);
		tmp_pattern.clear();

		tmp_index = 0;
		tmp_ch = table[P[tmp_index]];
		tmp_pattern += P[tmp_index];

		tmp_loc = root;
		tmp_index = 0;

		while(true){

			parent_id = tmp_loc;
			FLG = false;

			if(nodes[tmp_loc].children[tmp_ch] == -1){
				FLG = true;
				nodes[tmp_loc].children[tmp_ch] = index++; //★新しいノードへ移動する場合★
			}
			//子ノードに移動
			tmp_loc = nodes[tmp_loc].children[tmp_ch];

			if(FLG){
				nodes[tmp_loc].parent_id = parent_id;
				nodes[tmp_loc].pattern = tmp_pattern;

				//MAPに登録
				MAP[tmp_pattern] = tmp_loc;
			}

			tmp_index++;

			if(P[tmp_index] == '\0'){ //今回の数字が最後の文字だった場合
				nodes[tmp_loc].finish_FLG = true;
				break;
			}
			tmp_ch = table[P[tmp_index]];
			tmp_pattern += P[tmp_index];
		}
	}

	//Suffix_linkを構築する
	for(int i = 1; i < index; i++){

		tmp_pattern = nodes[i].pattern.substr(1);

		//1文字ずつ先頭から文字を削っていって、一致するところでsuffix_link(最大一致接尾辞へのリンク)を張る
		while(tmp_pattern.size() > 0){
			auto at = MAP.find(tmp_pattern);
			if(at != MAP.end()){
				nodes[i].suffix_link = MAP[tmp_pattern];
				break;
			}
			tmp_pattern = tmp_pattern.substr(1);
		}
		//suffix_linkが見つからなかった場合でも、元々rootにsuffix_linkを張ってあるので操作は不要
	}

	int ans = 0;
	tmp_loc = root;

	for(int i = 0; i < length; i++){
		tmp_ch = table[buf[i]];

		if(nodes[tmp_loc].children[tmp_ch] != -1){ //tmp_locから次に行ける場合
			tmp_loc = nodes[tmp_loc].children[tmp_ch];

			//suffix_linkをrootまで辿り、finish_FLGがtrueのノードがないか調べる
			if(nodes[tmp_loc].finish_FLG){ //このノード自体が終了地点
				ans++;
				tmp_loc = root; //'*'出力してrootへ
			}else{
				//suffix_linkをたどる
				for(int k = nodes[tmp_loc].suffix_link; k != root; k = nodes[k].suffix_link){
					if(nodes[k].finish_FLG){
						ans++;
						tmp_loc = root;
						break;
					}
				}
			}
		}else{

			if(tmp_loc == root)continue; //rootの場合はSKIP

			//suffix_linkを辿り、tmp_chへ移れるノードがあるか調べる
			for(tmp_loc = nodes[tmp_loc].suffix_link; tmp_loc != root; tmp_loc = nodes[tmp_loc].suffix_link){
				if(nodes[tmp_loc].children[tmp_ch] != -1)break;
			}

			if(tmp_loc == root){ //rootまで戻った場合
				if(nodes[tmp_loc].children[tmp_ch] != -1){ //rootの子にtmp_chがいる場合
					tmp_loc = nodes[tmp_loc].children[tmp_ch];
					if(nodes[tmp_loc].finish_FLG){
						ans++;
						tmp_loc = root;
					}
				}else{
					//Do nothing
				}
			}else{ //途中でtmp_chへ移れるノードが見つかった場合
				tmp_loc = nodes[tmp_loc].children[tmp_ch];

				if(nodes[tmp_loc].finish_FLG){
					ans++;
					tmp_loc = root;
				}else{

					//suffix_linkをたどる
					for(int k = nodes[tmp_loc].suffix_link; k != root; k = nodes[k].suffix_link){
						if(nodes[k].finish_FLG){
							ans++;
							tmp_loc = root;
							break;
						}
					}
				}
			}
		}
	}

	printf("%d\n",ans);

	return 0;
}