class in {struct my_iterator{int it;const bool rev;explicit constexpr my_iterator(int it_, bool rev=false):it(it_),rev(rev){}int operator*(){return it;}bool operator!=(my_iterator& r){return it!=r.it;}void operator++(){rev?--it:++it;}};const my_iterator i,n;public:explicit constexpr in(int n):i(0),n(n){}explicit constexpr in(int i,int n):i(i,n using namespace std; template struct Node_ { Node_* next[Code]; Node_* fail; int num; explicit Node_() : fail(nullptr), num(0) { fill_n(next, Code, nullptr);} }; typedef Node_<26> node_t; void constructAC(vector& nodes, const vector& patterns) { node_t* root = &nodes[0]; //Phase 1 (trie) int count = 0; for(const auto& s : patterns) { node_t* cur = root; for(const char& c : s) { int k = c - 'A'; if(cur->next[k] == nullptr) cur->next[k] = &nodes[++count]; cur = cur->next[k]; } cur->num = 1; } //Phase 2 (failue link) queue que; for(int i : in(26)) { if(root->next[i] != nullptr) { root->next[i]->fail = root; que.emplace(root->next[i]); } else root->next[i] = root; } while(!que.empty()) { node_t* cur = que.front(); que.pop(); for(int i : in(26)) { if(cur->next[i] == nullptr) continue; que.emplace(cur->next[i]); node_t* f = cur->fail; while(f->next[i] == nullptr) f = f->fail; cur->next[i]->fail = f->next[i]; } } } bool used[50010]; int getNum(node_t* cur, node_t* root) { if(cur == root) return 0; int id = cur - root; if(used[id]) return cur->num; used[id] = true; cur->num += getNum(cur->fail, root); return cur->num; } int main() { cin.tie(0); ios::sync_with_stdio(false); string s; cin >> s; int m; cin >> m; vector patterns(m); for(auto& x : patterns) cin >> x; vector nodes(m * 10 + 1); constructAC(nodes, patterns); node_t* cur = &nodes[0]; int ans = 0; memset(used, 0, sizeof(used)); for(int i : in(s.size())) { int k = s[i] - 'A'; while(cur->next[k] == nullptr) cur = cur->fail; cur = cur->next[k]; ans += getNum(cur, &nodes[0]); } cout << ans << endl; return 0; }