#include using namespace std; typedef unsigned long long hash_type; struct RollingHash { hash_type base1; vector< hash_type > hash1, pow1; RollingHash() : base1(29LL) { } void init(const string& s) { int n = s.size(); hash1.assign(n + 1, 0); pow1.assign(n + 1, 1); for(int i = 0; i < n; i++) { hash1[i + 1] = (hash1[i] + s[i] - 'A') * base1; pow1[i + 1] = pow1[i] * base1; } } hash_type get(int l, int r) { if(r >= hash1.size()) return (~0); return ((hash1[r] - hash1[l] * pow1[r - l])); } }; RollingHash hashed; int N, M; string S; bool compare(const int& a, const int& b) { int low = 0, high = min(N - a, N - b) + 1; while(high - low > 1) { int mid = (low + high) >> 1; if(hashed.get(a, a + mid) == hashed.get(b, b + mid)) low = mid; else high = mid; } if(low == min(N - a, N - b)) return (low == N - a); return (S[a + low] < S[b + low]); } string T; bool comp(RollingHash& hashed1, const int& b) { int mm = hashed1.hash1.size() - 1; int low = 0, high = min(mm, N - b) + 1; while(high - low > 1) { int mid = (low + high) >> 1; if(hashed1.get(0, mid) == hashed.get(b, b + mid)) low = mid; else high = mid; } if(low == min(mm, N - b)) return (low == mm); return (T[low] < S[b + low]); } int main() { cin >> S; N = S.size(); hashed.init(S); vector< int > idx(S.size()); iota(idx.begin(), idx.end(), 0); sort(idx.begin(), idx.end(), compare); int M; cin >> M; long long ret = 0; while(M--) { cin >> T; RollingHash buff; buff.init(T); hash_type val = buff.get(0, T.size()); int low1 = -1, high1 = S.size() - 1; while(high1 - low1 > 1) { int mid = (low1 + high1) >> 1; if(comp(buff, idx[mid])) high1 = mid; else low1 = mid; } if(val != hashed.get(idx[high1], idx[high1] + T.size())) continue; int low2 = high1, high2 = S.size(); while(high2 - low2 > 1) { int mid = (low2 + high2) >> 1; if(val == hashed.get(idx[mid], idx[mid] + T.size())) low2 = mid; else high2 = mid; } ret += low2 - high1 + 1; } cout << ret << endl; }