#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <queue> #include <string> #include <string.h> #include <map> #include <vector> typedef long long LL ; const int nodeSize = 2008 ; const int alphaSize = 2 ; const LL mod = 1000000009LL ; void Mod(LL &res){ if(res < 0) res = (res + mod) % mod ; while(res >= mod) res -= mod ; } struct AC{ int next[nodeSize][alphaSize] ; int cnt[nodeSize] ; int fail[nodeSize] ; int root ; int totel ; void clear(){ totel = 0 ; root = newNode() ; memset(dp , -1 , sizeof(dp)) ; } int newNode(){ cnt[totel] = 0 ; memset(next[totel] , 0 , sizeof(next[totel])) ; return totel++ ; } void add(char *s){ int now = root ; for(int i = 0 ; s[i] ; i++){ int son = s[i] - '0' ; if(! next[now][son]) next[now][son] = newNode() ; now = next[now][son] ; } cnt[now] = 1 ; } void buildAC(){ std::queue<int> q ; fail[root] = root ; for(int son = 0 ; son < alphaSize ; son++){ if(! next[root][son]) next[root][son] = root ; else{ q.push(next[root][son]) ; fail[next[root][son]] = root; } } while(! q.empty()){ int now = q.front() ; q.pop() ; if(cnt[fail[now]]) cnt[now] = 1 ; for(int son = 0 ; son < alphaSize ; son++){ if(! next[now][son]) next[now][son] = next[fail[now]][son] ; else{ fail[next[now][son]] = next[fail[now]][son] ; q.push(next[now][son]) ; } } } } int query(char *s){ int now = root ; for(int i = 0 ; s[i] ; i++){ int d = s[i] - '0' ; for(int j = 3 ; j >= 0 ; j--){ now = next[now][(d>>j) & 1] ; int u = now ; while(u != root){ if(cnt[u]) return 0 ; u = fail[u] ; } } } return 1 ; } int state[nodeSize][10] ; int getState(int s , int k){ if(cnt[s]) return -1 ; for(int i = 3 ; i >= 0 ; i--){ if(cnt[next[s][(k>>i) & 1]]) return -1 ; s = next[s][(k>>i) & 1] ; } return s ; } void preState(){ for(int s = 0 ; s < totel ; s++){ for(int k = 0 ; k <= 9 ; k++){ state[s][k] = getState(s , k) ; } } } int bit[208] ; LL answer(char *s){ int len = strlen(s) ; int pos = 0 ; for(int i = len-1 ; i >= 0 ; i--) bit[pos++] = s[i] - '0' ; return dfs(pos-1 , 1 , 0 , 1) ; } LL dp[208][2][2008] ; LL dfs(int pos , int isLeadZore , int nowState , int isEnd){ if(pos == -1) return 1 ; if(!isEnd && dp[pos][isLeadZore][nowState] != -1) return dp[pos][isLeadZore][nowState] ; LL res = 0 ; if(isLeadZore) res += dfs(pos-1 , 1 , nowState , isEnd && bit[pos] == 0) ; else if(state[nowState][0] != -1) res += dfs(pos-1 , 0 , state[nowState][0] , isEnd && bit[pos] == 0) ; Mod(res) ; int d = isEnd ? bit[pos] : 9 ; for(int i = 1 ; i <= d ; i++){ if(state[nowState][i] != -1){ res += dfs(pos-1 , 0 , state[nowState][i] , isEnd && i == d) ; Mod(res) ; } } if(! isEnd) dp[pos][isLeadZore][nowState] = res ; return res ; } }; AC ac ; char word[208] , Lf[208] , Rt[208] ; int main(){ int t , n ; scanf("%d" , &t) ; while(t--){ scanf("%d" , &n) ; ac.clear() ; while(n--){ scanf("%s" , word) ; ac.add(word) ; } ac.buildAC() ; ac.preState() ; scanf("%s%s" , Lf , Rt) ; LL res = ac.answer(Rt) - ac.answer(Lf) + ac.query(Lf) ; Mod(res) ; printf("%lld\n" , res) ; } return 0; }