#include<bits/stdc++.h>
using namespace std;
using ll = long long;

// #undef DEBUG
// #define DEBUG
// DEBUG {{{
// clang-format off
#ifdef DEBUG
#if !defined(DEBUG_OUT)
#define DEBUG_OUT cerr
#endif
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { o << "{"; for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? ", " : ""); o << "}"; return o; }
#define dump(...) [&](){auto __debug_tap=make_tuple(__VA_ARGS__);DEBUG_OUT<<"["<<__LINE__<< "] "<<#__VA_ARGS__<<" = "<<__debug_tap<<"\n";}()
template<class T> inline void dump2D(T &d, size_t sizey, size_t sizex) {
  for(size_t i = 0; i < sizey; i++) { for(size_t j = 0; j < sizex; j++) DEBUG_OUT << d[i][j] << " "; DEBUG_OUT << endl; }
}
#else
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) { for(size_t i = 0; i < v.size(); i++) o << v[i] << (i + 1 != v.size() ? " " : ""); return o; }
#define dump(...) (42)
#define dump2D(...) (42)
#endif
template<int n, class...T> typename enable_if<(n>=sizeof...(T))>::type _ot(ostream &, tuple<T...> const &){}
template<int n, class...T> typename enable_if<(n< sizeof...(T))>::type _ot(ostream & os, tuple<T...> const & t){ os << (n==0?"":", ") << get<n>(t); _ot<n+1>(os, t); }
template<class...T> ostream & operator<<(ostream &o, tuple<T...> const &t){ o << "("; _ot<0>(o, t); o << ")"; return o; }
template<class T, class U> ostream & operator<<(ostream &o, pair<T, U> const &p) { o << "(" << p.first << ", " << p.second << ")"; return o; }
// clang-format on
// }}}


// never fail to call build() !!
// constructor()
// add(string)
// match(string) : [left, right], vec<tuple<int left, int right, int key>> in right-order
/// --- AhoCorasick Library {{{ ///

const int inf = 1e9;
struct AhoCorasick {
  struct Trie {
    unordered_map< char, Trie* > child;
    Trie* failure = nullptr;
    int shortestWord = inf;
    Trie* add(char c) {
      if(child.count(c)) {
        return child[c];
      } else {
        return child[c] = new Trie;
      }
    }
    Trie* go(char c) {
      if(child.count(c)) {
        return child[c];
      } else {
        if(failure == nullptr) {
          return this;
        } else {
          return failure->go(c);
        }
      }
    }
  };
  Trie* top = new Trie;
  vector< string > dict;
  void add(string word) {
    Trie* now = top;
    for(size_t i = 0; i < word.size(); i++) {
      now = now->add(word[i]);
    }
    now->shortestWord = min(now->shortestWord, (int) word.size());
  }
  void build() {
    queue< Trie* > q;
    q.emplace(top);
    while(q.size()) {
      Trie* now = q.front();
      q.pop();
      for(pair< char, Trie* > ch : now->child) {
        q.emplace(ch.second);
        Trie* failure = ch.second->failure = now == top ? top : now->failure->go(ch.first);
        /// only from failure!!
        // vector< int >& words = ch.second->words;
        ch.second->shortestWord = min(ch.second->shortestWord, failure->shortestWord);
        // words.insert(end(words), begin(failure->words), end(failure->words));
      }
    }
  }
  vector< tuple< int, int, int > > match(string s) {
    Trie* now = top;
    vector< tuple< int, int, int > > res;
    for(size_t i = 0; i < s.size(); i++) {
      now = now->go(s[i]);
      if(now->shortestWord != inf) res.emplace_back(i - now->shortestWord + 1, i, 0);
    }
    return res;
  }
};

/// }}}--- ///

int main() {
  std::ios::sync_with_stdio(false), std::cin.tie(0);
  string s; cin >> s;
  int m; cin >> m;
  vector<string> t(m);
  AhoCorasick ecasd;
  for(int i = 0; i < m ; i++) {
    cin >> t[i];
    ecasd.add(t[i]);
  }
  ecasd.build();
  auto v = ecasd.match(s);
  int last = -1;
  ll ans = 0;
  dump(v);
  // あとは区間スケジューリング問題
  for(int i = 0; i < v.size(); i++) {
    int le, ri, key; tie(le, ri, key) = v[i];
    if(last >= le) continue;
    last = ri;
    ans++;
  }
  cout << ans << endl;
  return 0;
}



Measured memory_bytes: 15168