#include using namespace std; using i64 = int64_t; const i64 MOD = (i64)1e9 + 7; const i64 INF = (i64)1e18 + 7; template struct Range{ struct iterator{ T value; const T step, last; const T& operator*(){return value;} iterator(T value, T step, T last) : value(step < static_cast(0) ? max(last, value) : min(last, value)), step(step), last(last) { } iterator operator++(){value = step < static_cast(0) ? max(value + step, last) : min(value + step, last); return *this;} bool operator!=(const iterator& x){return value != x.value;} }; const T start, last, step; Range(const T start, const T last, const T step = static_cast(1)) : start(start), last(last), step(step) { } Range(const T last) : start(0), last(last), step(1) { } iterator begin(){return iterator(start, step, last);} iterator end(){return iterator(last, step, last);} }; template struct FixPoint{ const F _f; FixPoint(F&& f) : _f(forward(f)){} template decltype(auto) operator()(Types&&... args) const{ return _f(*this, forward(args)...); } }; template static decltype(auto) makeRec(F&& f){ return FixPoint(forward(f)); } template vector makeVector(size_t x){ return vector(x, T(Value)); } template auto makeVector(size_t x, Types... args){ return vector(args...))>(x, makeVector(args...)); } template bool chmax(T& a, T b){ if(a < b){ a = b; return true; } return false; } template bool chmin(T& a, T b){ if(a > b){ a = b; return true; } return false; } #ifdef TEST #define dump(x) fprintf(stderr, "line =%4d, name =%7s , ", __LINE__, #x); cout << "value = " << x << endl; #define vecdump(x) fprintf(stderr, "line =%4d, name =%7s\n", __LINE__, #x); _dump_macro(x); #else #define vecdump(x) #define dump(x) #endif void _dump(int, string& x){ #ifdef TEST cout << x << endl; #endif } template void _dump(bool, T& x){ #ifdef TEST cout << x << " "; #endif } template void _dump(int, T& x){ #ifdef TEST for(auto& elm : x) _dump(0, elm); cout << endl; #endif } template void _dump_macro(T& x){ _dump(0, x); } void _input(int, string& x){ cin >> x; } template void _input(bool, T& x){ cin >> x; } template void _input(int, T& x){ for(auto& elm : x) _input(0, elm); } template void input_single(T& x){ _input(0, x); } auto input(){} template void input(T& value, Types&&... args){ input_single(value); input(forward(args)...); }; void _pararell_input(size_t){} template void _pararell_input(size_t index, T& value, Types&&... args){ input(value[index]); _pararell_input(index, forward(args)...); } template void pararell_input(size_t count, Types&&... args){ for(const auto& i : Range<>(count)) _pararell_input(i, forward(args)...); } template struct ModInt{ i64 p; ModInt() : p(0){} ModInt(i64 x){p = x >= 0 ? x % mod : x + (-x + mod - 1) / mod * mod;} ModInt& operator+=(const ModInt& y){p = p + *y - ((p + *y) >= mod ? mod : 0); return *this;} ModInt& operator-=(const ModInt& y){p = p - *y + (p - *y < 0 ? mod : 0); return *this;} ModInt& operator*=(const ModInt& y){p = (p * *y) % mod; return *this;} ModInt& operator%=(const ModInt& y){if(y)p %= *y; return *this;} ModInt operator+(const ModInt& y) const{ModInt x = *this; return x += y;} ModInt operator-(const ModInt& y) const{ModInt x = *this; return x -= y;} ModInt operator*(const ModInt& y) const{ModInt x = *this; return x *= y;} ModInt operator%(const ModInt& y) const{ModInt x = *this; return x %= y;} friend ostream& operator<<(ostream& stream, const ModInt& x){ stream << *x; return stream; } friend ostream& operator>>(ostream& stream, const ModInt& x){ stream >> *x; return stream; } ModInt& operator++(){p = (p + 1) % mod; return *this;} ModInt& operator--(){p = (p - 1 + mod) % mod; return *this;} bool operator==(const ModInt& y) const{return p == *y;} bool operator!=(const ModInt& y) const{return p != *y;} const i64& operator*() const{return p;} i64& operator*(){return p;} }; using mint = ModInt; template function mpow = [](T x, i64 y){ T z = x; T val = y & 1 ? x : T(1); while(z *= z, y >>= 1) if(y & 1) val *= z; return val; }; template struct RollingHash{ using mint1 = ModInt; using mint2 = ModInt; using pair_type = pair; int len; std::vector v; static std::vector power, inv; RollingHash(T s) : len(s.size()) { v.assign(1, make_pair(mint1(0), mint2(0))); for(int i = 0; i < len; ++i){ auto c = s[i]; v.emplace_back(v.back().first + power[i].first * c, v.back().second + power[i].second * c); if(static_cast(power.size()) == i + 1){ power.emplace_back(power.back().first * base, power.back().second * base); inv.emplace_back(mpow(power.back().first, mod1 - 2), mpow(power.back().second, mod2 - 2)); } } }; pair_type get(int l = 0, int r = -1){ if(r == -1) r = len; assert(l <= r); assert(r <= len); auto l_cut = make_pair(v[r].first - v[l].first, v[r].second - v[l].second); return make_pair(l_cut.first * inv[l].first, l_cut.second * inv[r].second); } pair_type connect(pair_type l, pair_type r, int l_len){ return make_pair(l.first + power[l_len].first * r.first, l.second + power[l_len].second * r.second); } }; using RH = RollingHash; template<> vector, ModInt>> RH::power = {make_pair(ModInt(1), ModInt(1))}; template<> vector, ModInt>> RH::inv = {make_pair(ModInt(1), ModInt(1))}; i64 solve(i64 _count){ string s; int m = 0; input(s, m); vector c(m); input(c); if(!static_cast(cin)) return MOD; #ifdef TEST cout << "Case: " << _count << endl; #endif vector> v(11); RH rh(s); for(int i = 0; i < rh.len; ++i) for(int j = 1; j <= 10 && i + j <= rh.len; ++j){ auto res = rh.get(i, i + j); ++v[j][(*res.first << 32) + *res.second]; } i64 ans = 0; for(auto& t : c){ RH rh2(t); auto res = rh2.get(); ans += v[rh2.len][(*res.first << 32) + *res.second]; } cout << ans << endl; return 0; } signed main(){ cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); int t = 0; while(solve(++t) != MOD); }