#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }
template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a){
  out<<'('<<a.first<<','<<a.second<<')';
  return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
  out<<'[';
  REP(i, a.size()) {out<<a[i];if(i!=a.size()-1)out<<',';}
  out<<']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

// 文字の種類数をtemplate引数で渡す
template <int types = 26>
struct AhoCorasick {
  // trie木のnode
  struct node {
    node *fail;
    vector<node*> next;
    VI matched;
    node() : fail(nullptr), next(types, nullptr) {}
  };

  // 辞書のサイズ
  int sz;
  // trie木の根
  node *root;
  // vectorを結合
  VI unite(const VI &a, const VI &b) {
    VI ret;
    set_union(ALL(a), ALL(b), back_inserter(ret));
    return ret;
  }
  // 文字と数字の対応付けをする関数
  function<int(char)> trans;
  // 初期化
  AhoCorasick() {}
  AhoCorasick(vector<string> pattern, function<int(char)> f = [](char c){return c-'a';}) {
    trans = f;
    build(pattern);
  }
  // 文字列集合patternからtrie木っぽいオートマトンを作成
  void build(vector<string> pattern) {
    sz = pattern.size(), root = new node;
    node *now;
    root->fail = root;
    REP(i, sz) {
      now = root;
      for(const auto &c: pattern[i]) {
        if(now->next[trans(c)] == nullptr) {
          now->next[trans(c)] = new node;
        }
        now = now->next[trans(c)];
      }
      now->matched.PB(i);
    }

    queue<node*> que;
    REP(i, types) {
      if(root->next[i] == nullptr) {
        root->next[i] = root;
      } else {
        root->next[i]->fail = root;
        que.push(root->next[i]);
      }
    }
    while(que.size()) {
      now = que.front(); que.pop();
      REP(i, types) {
        if(now->next[i] != nullptr) {
          node *nxt = now->fail;
          while(!nxt->next[i]) nxt = nxt->fail;
          now->next[i]->fail = nxt->next[i];
          now->next[i]->matched = unite(now->next[i]->matched, nxt->next[i]->matched);
          que.push(now->next[i]);
        }
      }
    }
  }
  // 一文字ずつ照合していく
  node* next(node* p, const char c) {
    while(p->next[trans(c)] == nullptr) p = p->fail;
    return p->next[trans(c)];
  }
  // 文字列s中に辞書と一致する部分列がどれだけあるか
  VI match(const string s) {
    VI res(sz);
    node *now = root;
    for(auto c : s) {
      now = next(now, c);
      for(auto i : now->matched) res[i]++;
    }
    return res;
  }
};

signed main(void)
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  string s;
  int n;
  cin >> s >> n;
  vector<string> p(n);
  REP(i, n) cin >> p[i];

  AhoCorasick<26> ac(p);

  int ret = 0;
  auto cur = ac.root;

  for(auto c: s) {
    cur = ac.next(cur, c);
    if(cur->matched.size() > 0) {
      ret++;
      cur = ac.root;
    }
  }

  cout << ret << endl;

  return 0;
}


### Prompt

Construct a cpp code solution to the problem outlined:

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.





Example

Input

brainfuck
1
fuck


Output

1

### Response

```cpp
#define __USE_MINGW_ANSI_STDIO 0
#include <bits/stdc++.h>

using namespace std;
using ll = long long;
#define int ll
using VI = vector<int>;
using VVI = vector<VI>;
using PII = pair<int, int>;

#define FOR(i, a, n) for (ll i = (ll)a; i < (ll)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) x.begin(), x.end()
#define PB push_back

const ll LLINF = (1LL<<60);
const int INF = (1LL<<30);
const int MOD = 1000000007;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> bool IN(T a, T b, T x) { return a<=x&&x<b; }
template<typename T> T ceil(T a, T b) { return a/b + !!(a%b); }
template<class S,class T>
ostream &operator <<(ostream& out,const pair<S,T>& a){
  out<<'('<<a.first<<','<<a.second<<')';
  return out;
}
template<class T>
ostream &operator <<(ostream& out,const vector<T>& a){
  out<<'[';
  REP(i, a.size()) {out<<a[i];if(i!=a.size()-1)out<<',';}
  out<<']';
  return out;
}

int dx[] = {0, 1, 0, -1}, dy[] = {1, 0, -1, 0};

// 文字の種類数をtemplate引数で渡す
template <int types = 26>
struct AhoCorasick {
  // trie木のnode
  struct node {
    node *fail;
    vector<node*> next;
    VI matched;
    node() : fail(nullptr), next(types, nullptr) {}
  };

  // 辞書のサイズ
  int sz;
  // trie木の根
  node *root;
  // vectorを結合
  VI unite(const VI &a, const VI &b) {
    VI ret;
    set_union(ALL(a), ALL(b), back_inserter(ret));
    return ret;
  }
  // 文字と数字の対応付けをする関数
  function<int(char)> trans;
  // 初期化
  AhoCorasick() {}
  AhoCorasick(vector<string> pattern, function<int(char)> f = [](char c){return c-'a';}) {
    trans = f;
    build(pattern);
  }
  // 文字列集合patternからtrie木っぽいオートマトンを作成
  void build(vector<string> pattern) {
    sz = pattern.size(), root = new node;
    node *now;
    root->fail = root;
    REP(i, sz) {
      now = root;
      for(const auto &c: pattern[i]) {
        if(now->next[trans(c)] == nullptr) {
          now->next[trans(c)] = new node;
        }
        now = now->next[trans(c)];
      }
      now->matched.PB(i);
    }

    queue<node*> que;
    REP(i, types) {
      if(root->next[i] == nullptr) {
        root->next[i] = root;
      } else {
        root->next[i]->fail = root;
        que.push(root->next[i]);
      }
    }
    while(que.size()) {
      now = que.front(); que.pop();
      REP(i, types) {
        if(now->next[i] != nullptr) {
          node *nxt = now->fail;
          while(!nxt->next[i]) nxt = nxt->fail;
          now->next[i]->fail = nxt->next[i];
          now->next[i]->matched = unite(now->next[i]->matched, nxt->next[i]->matched);
          que.push(now->next[i]);
        }
      }
    }
  }
  // 一文字ずつ照合していく
  node* next(node* p, const char c) {
    while(p->next[trans(c)] == nullptr) p = p->fail;
    return p->next[trans(c)];
  }
  // 文字列s中に辞書と一致する部分列がどれだけあるか
  VI match(const string s) {
    VI res(sz);
    node *now = root;
    for(auto c : s) {
      now = next(now, c);
      for(auto i : now->matched) res[i]++;
    }
    return res;
  }
};

signed main(void)
{
  cin.tie(0);
  ios::sync_with_stdio(false);

  string s;
  int n;
  cin >> s >> n;
  vector<string> p(n);
  REP(i, n) cin >> p[i];

  AhoCorasick<26> ac(p);

  int ret = 0;
  auto cur = ac.root;

  for(auto c: s) {
    cur = ac.next(cur, c);
    if(cur->matched.size() > 0) {
      ret++;
      cur = ac.root;
    }
  }

  cout << ret << endl;

  return 0;
}


```