// g++ -std=c++17 in.cpp -o test
#include <bits/stdc++.h>
using namespace std;

//defs
using ll = long long;
using uint = unsigned int;
#define rep(i,n) for(int i=0;i<int(n);i++)
#define per(i,n) for(int i=int(n)-1;i>=0;i--)
#define all(c) c.begin(),c.end()
#define si(x) int(x.size())
#define pb emplace_back
#define fs first
#define sc second


//helper
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
template<class T,class U> void chmax(T& x, U y){if(x<y) x=y;}
template<class T,class U> void chmin(T& x, U y){if(y<x) x=y;}
template<class T> void mkuni(V<T>& v){sort(all(v));v.erase(unique(all(v)),v.end());}

//debug print
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}

template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}

const ll mod = 1e9+7;
 
ll gcd (ll a, ll b) {
    return b ? gcd (b, a % b) : a;
}

ll binpow(ll a, ll b, ll m) {
    a %= m;
    ll res = 1;
    while (b > 0) {
        if (b & 1)
            res = res * a % m;
        a = a * a % m;
        b >>= 1;
    }
    return res;
}

const int MAXN = 2e5+1;

vector<bool> a_p((1<<10),false), b_p((1<<10),false), f_p((1<<10),false);

long long dp[20][(1<<10)][2];

void getDigits(long long x, vector <int> &digit)
{
    while (x)
    {
        digit.push_back(x%10);
        x /= 10;
    }
}

long long digitSum(int idx, int cur, int tight,vector <int> &digit, bool non_zero)
{
    // base case
    if (idx == -1){
        // if( cur % 2 == 0)
        if( f_p[cur] ){
            return 1;
        }else
            return 0;
    }
 
    // checking if already calculated this state
    if (dp[idx][cur][tight] != -1 and tight != 1)
        return dp[idx][cur][tight];
 
    long long ret = 0;
 
    // calculating range value
    int k = (tight)? digit[idx] : 9;
 
    for (int i = 0; i <= k ; i++)
    {
        // calculating newTight value for next state
        int newTight = (digit[idx] == i)? tight : 0;
        // fetching answer from next state
        if( non_zero ){
            ret += digitSum(idx-1, cur|(1<<i), newTight, digit, true);
        }else{
            if( i ){
                ret += digitSum(idx-1, cur|(1<<i), newTight, digit, true);
            }else{
               ret += digitSum(idx-1, cur, newTight, digit, false); 
            }
        }
        ret %= mod;
    }
 
    if (!tight)
      dp[idx][cur][tight] = ret;
 
    return ret;
}

int main(){
	cout<<fixed<<setprecision(9);
	int test =  1;
	cin>>test;
	for(int t=1; t<=test; t++){
        int n, m;
        cin>>n>>m;
        vector<ll> a(n) , b(m);

        for(int i=0;i<(1<<10);i++){
            a_p[i] = b_p[i] = f_p[i] = false;
        }

        for(int i=0;i<n;i++){
            cin>>a[i];
            int cur = 0;
            while( a[i] > 0){
                cur |= (1<<(a[i]%10));
                a[i] /= 10;
            }
            a_p[cur] = true;
            if( cur % 2)
                a_p[cur-1] = true;
        }

        for(int i=0;i<m;i++){
            cin>>b[i];
            int cur = 0;
            while( b[i] > 0){
                cur |= (1<<(b[i]%10));
                b[i] /= 10;
            }
            b_p[cur] = true;
            if( cur % 2)
                b_p[cur-1] = true;
        }

        for(int i=0;i<(1<<10);i++){
            for(int j=0;j<(1<<10);j++){
                f_p[(i|j)] = f_p[(i|j)] or (a_p[i] and b_p[j]);
            }
        }

        ll l , r;
        cin>> l >> r;
        --l;
        vector<int> digitA;
        memset(dp, -1, sizeof(dp));
        getDigits(l, digitA);
        long long ans1 = digitSum(digitA.size()-1, 0, 1, digitA, false);
        vector<int> digitB;
        memset(dp, -1, sizeof(dp));
        getDigits(r, digitB);
        long long ans2 = digitSum(digitB.size()-1, 0, 1, digitB, false);
        ll num = ( ans2 - ans1 + mod ) %mod;
        cout<<num<<"\n";  
	}
	return 0;
}