CSES - Shared codeLink to this code: https://cses.fi/paste/0063017098a7983f86dcb5/
#include <bits/stdc++.h>
using namespace std;
#ifdef LOCAL
#include "C:/Users/sudhi/OneDrive/Desktop/CP/ac-library/atcoder/debug.hpp"
#else
#define debug(...) 69
#endif

#define rep(i, a, b) for(int i = a; i < (b); ++i)
#define all(x) begin(x), end(x)
#define sz(x) (int)(x).size()
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;

#pragma once

// Arithmetic mod 2^64-1. 2x slower than mod 2^64 and more
// code, but works on evil test data (e.g. Thue-Morse, where
// ABBA... and BAAB... of length 2^10 hash the same mod 2^64).
// "typedef ull H;" instead if you think test data is random,
// or work mod 10^9+7 if the Birthday paradox is not a problem.
typedef uint64_t ull;
struct H {
    // H is a type that uses arithmetic modulo 2^64 - 1 to compute hashes
	ull x; H(ull x=0) : x(x) {}
	H operator+(H o) { return x + o.x + (x + o.x < x); }
	H operator-(H o) { return *this + ~o.x; }
	H operator*(H o) { auto m = (__uint128_t)x * o.x;
		return H((ull)m) + (ull)(m >> 64); }
	ull get() const { return x + !~x; }
	bool operator==(H o) const { return get() == o.get(); }
	bool operator<(H o) const { return get() < o.get(); }
};

//This is the base of the hash 
static const H C = (ll)1e11+3; // (order ~ 3e9; random also ok)


struct HashInterval {
    // Constructs the hashes of all substrings of a string implicitly
    // The hash of the string s[0]s[1] ... s[l - 1] is 
    // C^(l-1)s[0] + C^(l-2) s[1] + C^(l-3)s[2] + ... s[l - 1]
	vector<H> ha, pw;
	HashInterval(string& str) : ha(sz(str)+1), pw(ha) {
		pw[0] = 1;
		rep(i,0,sz(str))
			ha[i+1] = ha[i] * C + str[i],
			pw[i+1] = pw[i] * C;
	}
    // The hash of the substring s[a : b - 1] is constructed as follows:
    // hash(s[0 : b - 1]) = C^(b - 1)s[0] + C^(b - 2)s[1] + ... C^(b - 1 - a)s[a] + C^(b-1-a-1)s[a-1] ... s[b-1]
    // hash(s[0 : a - 1]) = C^(a - 1)s[0] + ... s[a - 1]
    // hash(s[a : b - 1]) = C^(b - 1 - a)s[a] + C^(b-1-a-1)s[a-1] ... + s[b-1]
	H hashInterval(int a, int b) { // hash [a, b)
        return ha[b] - ha[a] * pw[b - a];
	}
};

vector<H> getHashes(string& str, int length) {
	if (sz(str) < length) return {};
	H h = 0, pw = 1;
	rep(i, 0, length)
		h = h * C + str[i], pw = pw * C;
	vector<H> ret = {h};
	rep(i,length,sz(str)) {
		ret.push_back(h = h * C + str[i] - pw * str[i-length]);
	}
	return ret;
}

H hashString(string& s){H h{}; for(char c:s) h=h*C+c;return h;}

const ll MOD = 1e9 + 7;
//The direct comparability of array hashes and string hashes is a concern that I have 

int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin.exceptions(cin.failbit);
    string t;
    cin >> t;
    HashInterval h(t);
    int k;
    cin >> k;
    vector<string> d(k); 
    rep(i, 0, k) cin >> d[i];
    map<int, set<ull>> hashes;
    rep(i, 0, k) hashes[sz(d[i])].insert(hashString(d[i]).x);
    // debug(hashes);
    // for(auto &[l, s] : hashes){
    //     cout << l <<":\n";
    //     for(auto x : s) cout << x << ", ";
    //     cout <<"\n";
    // }
    debug(sz(hashes));
    int n = sz(t);
    vll dp(n + 1);
    dp[0] = 1;
    rep(i, 1, n + 1){
        for(auto& [l, s] : hashes) if(i >= l){
            ull curr = h.hashInterval(i - l, i).x;
            // cerr << i << " " << l << " " << curr << "\n";
            if(s.find(curr) != s.end()) dp[i] = (dp[i] + dp[i - l])%MOD; 
        }
    }
    cout << dp[n];
}