#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

int mod;

struct Sum2D {
    int n, m;
    ll** pref;

    Sum2D() {};
    Sum2D(ll** a): n(mod), m(mod) {
        pref = new ll*[n + 1];
        for (int i = 0; i <= n; ++i) {
            pref[i] = new ll[m + 1];
            for (int x = 0; x < mod; ++x)
                pref[i][x] = 0;
        }

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll get_sum(int lx, int rx, int ly, int ry) {
        ++rx; ++ry;
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

int a[66];

vector<pii> split_segment(ll mask) {
    int n = mod;
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        a[i] = (mask >> i) & 1;
        cnt += a[i];
    }

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && !a[l]) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r]) ++r;
        res.push_back({l, r - 1});
        i = r;
    }

    return res;
}

const int D = 20;
const int MOD = 60;
const int N = 30000;
const int LOG = 16;

using Zet = ll*;

int d;
int logn;
int gen[D];
vector<int> big_gen;
ll pwd[66];
ll jump[N][LOG];
pair<vector<pii>, vector<pii>> segments[N * D];

void add(Zet arr, Zet to_add, int shift) {
    for (int i = 0; i + shift < mod; ++i)
        arr[i] += to_add[i + shift];
    for (int i = mod - shift; i < mod; ++i)
        arr[i] += to_add[i + shift - mod];
}

Zet zeroes;
unordered_map<ll, Zet> cnt;

Zet get_cnt(ll r) {
    if (r <= 0)
        return zeroes;
    if (cnt.count(r))
        return cnt[r];

    Zet res = new ll[mod];
    for (int x = 0; x < mod; ++x)
        res[x] = 0;
    int k = mlog(r, d);
    ll dk = mpow(d, k);

    if (dk == r)
        dk /= d;

    int i = 0;
    for (; r >= (i + 1) * dk; ++i)
        add(res, get_cnt(dk), (mod - gen[i]) % mod);
    add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

    cnt[r] = res;
    return res;
};

void inters(ll & mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    mask1 &= ((mask2 >> shift) | (shift_mask << (mod - shift)));
}

ll query(int l, int r, int pos) {
    ll res = (1LL << mod) - 1;
    while(l != r) {
        for (int i = logn; ; --i) {
            if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                inters(res, jump[pos][i], big_gen[l]);
                l += pwd[i];
                pos += pwd[i];
                break;
            }
        }
    }
    return res;
};

unordered_map<ll, Sum2D> solver;

ll get_sum(ll R, int lx, int rx, int ly, int ry) {
    if (!solver.count(R)) {
        Zet* a = new Zet[mod];
        for (int i = 0; i < mod; ++i) {
            a[i] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                a[i][x] = 0;
        }
        for (int i = 0; pwd[i] - 1 <= R; ++i) {
            for (int digit = 0; digit < d - 1; ++digit) {
                if (R < (digit + 1) * pwd[i] - 1)
                    break;
                Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                for (int r = 0; r < mod; ++r)
                    a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
            }
        }
        solver[R] = Sum2D(a);
    }
    return solver[R].get_sum(lx, rx, ly, ry);
};

ll solve(ll R) {
    ll res = 0;
    for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
    }
    return res;
};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    scanf("%d %d", &d, &mod);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    logn = 1;
    for (int i = 0; i < d; ++i)
        big_gen.push_back(gen[i]);
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    int pos = 0;
    pwd[pos] = 1;
    while(pwd[pos] < (ll)4e17) {
        ll x = d * pwd[pos];
        pwd[++pos] = x;
    }

    for (int i = n - 1; i >= 0; --i) {
        jump[i][0] = (1LL << (a[i] + 1)) - 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            jump[i][k] = (1LL << mod) - 1;
            for (int ii = 0; ii < d; ++ii) {
                inters(jump[i][k], jump[i + ii * pwd[k - 1]][k - 1], gen[ii]);
            }
        }
    }

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        ll draw = query(rem, rem + n, 0);
        segments[rem] = {split_segment(draw), {{0, mod - 1}}};
    }

    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        ll draw1 = query(rem, pwd[logn], 0);
        ll draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        segments[rem] = {split_segment(draw1), split_segment(draw2)};
    }

    // init cnt
    //<-------------------------->
    zeroes = new ll[mod];
    for (int x = 0; x < mod; ++x)
        zeroes[x] = 0;
    cnt[0] = zeroes;
    Zet ozero = new ll[mod];
    for (int x = 0; x < mod; ++x)
        ozero[x] = 0;
    ozero[0] = 1;
    cnt[1] = ozero;
    //<-------------------------->

    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));

}

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template <typename T> bool chkmax(T &x,T y){return x<y?x=y,true:false;}
template <typename T> bool chkmin(T &x,T y){return x>y?x=y,true:false;}

ll readint(){
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,d,m; ll l,r;
ll pw[105],a[30],dp[2][65][60][2],bs[65],pr[105],pl[105];

ll shift(ll x,int t){return (x>>t)|((x&((1ll<<t)-1))<<(m-t));}

ll getans(vector<ll> &b,ll dep,ll now){
	if(now>r) return 0;
	ll res=0;
	if(b.size()==1){
		for(int i=0;i<m;i++){
			if(b[0]&(1ll<<i)){
				if(now<=pr[dep]) res+=dp[0][dep][i][0]+dp[0][dep][i][1];
				else res+=dp[0][dep][i][0];
				if(now<=pl[dep]) res-=dp[1][dep][i][0]+dp[1][dep][i][1];
				else res-=dp[1][dep][i][0];
			}
		}
		return res;
	}
	for(int i=0;i<d;i++){
		vector<ll> nb(0);
		int tmp=i; ll mask=(1ll<<m)-1;
		for(int j=0;j<b.size();j++){
			mask&=shift(b[j],a[tmp]);
			tmp++;
			if(tmp==d){
				tmp=0;
				nb.push_back(mask);
				mask=(1ll<<m)-1;
			}
		}
		if(tmp!=0) nb.push_back(mask);
		res+=getans(nb,dep+1,now+pw[dep]*i);
	}
	return res;
}

void getdp(ll x,int t){
	int cnt=0;
	memset(bs,0,sizeof(bs));
	for(;x;x/=d) bs[cnt++]=x%d;
	cnt=60;
	dp[t][cnt][0][1]=1;
	for(int i=cnt;i>=1;i--)
		for(int j=0;j<m;j++)
			for(int c=0;c<=1;c++)
				for(int num=0;num<(c?bs[i-1]+1:d);num++)
					dp[t][i-1][(j+a[num])%m][c&(num==bs[i-1])]+=dp[t][i][j][c];
}

int main(){
	d=readint(); m=readint();
	pw[0]=1;
	for(int i=1;pw[i-1]<=(1e18+10)/d;i++) pw[i]=pw[i-1]*d;
	for(int i=1;i<=100;i++) if(!pw[i]) pw[i]=1e18+10;
	for(int i=0;i<d;i++) a[i]=readint();
	n=readint();
	vector<ll> b(0);
	for(int i=1;i<=n;i++) b.push_back((1ll<<(readint()+1))-1);
	l=readint()-2; r=readint()-n;
	for(int i=0;i<=100;i++) pr[i]=r%pw[i];
	for(int i=0;i<=100;i++) pl[i]=l%pw[i];
	getdp(r,0); if(l>=0) getdp(l,1);
	printf("%lld\n",getans(b,0,0));
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAX=30010;
struct State
{
	bitset<MAX>left;
	bitset<MAX>right;
	long long len=0,res=0;
};
int n;
bitset<MAX>all;
State Unite(const State &a,const State &b)
{
	State c;
	c.len=a.len+b.len;
	c.res=a.res+b.res;
	c.left=a.left;
	c.right=b.right;
	if(a.len<n-1)c.left&=(b.left>>a.len)|(all<<(n-1-a.len));
	if(b.len<n-1)c.right&=(a.right<<b.len)|(all>>(n-1-b.len));
	if(a.len+b.len>=n)
	{
		bitset<MAX>d=a.right&b.left;
		if(a.len<n-1)d&=(all>>(n-1-a.len));
		if(b.len<n-1)d&=(all<<(n-1-b.len));
		c.res+=d.count();
	}
	return c;
}
int main(void)
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	int d,m;
	cin>>d>>m;
	vector<int>gen(d);
	for(int i=0;i<d;i++)cin>>gen[i];
	cin>>n;
	vector<int>b(n);
	for(int i=0;i<n;i++)cin>>b[i];
	long long L,R;
	cin>>L>>R;
	for(int i=1;i<n;i++)all.set(i);
	vector<vector<State>> states(1,vector<State>(m));
	for(int i=0;i<m;i++)
	{
		states[0][i].len=1;
		if(n==1)states[0][i].res=b[0]>=i;
		else
		{
			for(int j=1;j<n;j++)if(b[j]>=i)states[0][i].left.set(j);
			for(int j=1;j<n;j++)if(b[j-1]>=i)states[0][i].right.set(j);
		}
	}
	long long z=1;
	while(z<=R/d)
	{
		int sz=(int)states.size();
		states.resize(sz+1);
		states[sz].resize(m);
		for(int i=0;i<m;i++)
		{
			State cur=states[sz-1][i];
			for(int j=1;j<d;j++)cur=Unite(cur,states[sz-1][(i+gen[j])%m]);
			states[sz][i]=cur;
		}
		z*=d;
	}
	auto calc=[&](long long up)->long long
	{
		State res;
		int shift=0;
		for(int i=(int)states.size()-1;i>=0;i--)
		{
			z=1;
			for(int j=0;j<i;j++)z*=d;
			for(int j=0;j<d;j++)
			if(up>=z)
			{
				res=Unite(res,states[i][(shift+gen[j])%m]);
				up-=z;
			}
			else
			{
				shift=(shift+gen[j])%m;
				break;
			}
		}
		return res.res;
	};
	cout<<calc(R)-calc(L+n-2)<<'\n';
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 3e4 + 5;
const int MAXD = 25;
const int MAXM = 65;
const int MAXLOG = 64;
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
template <typename T> void chkmax(T &x, T y) {x = max(x, y); }
template <typename T> void chkmin(T &x, T y) {x = min(x, y); }
template <typename T> void read(T &x) {
	x = 0; int f = 1;
	char c = getchar();
	for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
	for (; isdigit(c); c = getchar()) x = x * 10 + c - '0';
	x *= f;
}
template <typename T> void write(T x) {
	if (x < 0) x = -x, putchar('-');
	if (x > 9) write(x / 10);
	putchar(x % 10 + '0');
}
template <typename T> void writeln(T x) {
	write(x);
	puts("");
}
struct info {
	ll ans, len;
	bitset <MAXN> pre, suf;
};
bitset <MAXN> all;
int n, d, m, gen[MAXD], b[MAXN];
int tot; ll len[MAXLOG]; info dp[MAXLOG][MAXM];
info operator + (const info &a, const info &b) {
	if (a.len == 0) return b;
	info res;
	res.len = a.len + b.len;
	res.ans = a.ans + b.ans;
	res.pre = a.pre;
	res.suf = b.suf;
	if (a.len <= n - 2) res.pre &= (b.pre >> a.len) | (all << (n - 1 - a.len));
	if (b.len <= n - 2) res.suf &= (a.suf << b.len) | (all >> (n - 1 - b.len));
	if (a.len + b.len >= n) {
		bitset <MAXN> tmp = a.suf & b.pre;
		if (a.len <= n - 2) tmp &= all >> (n - 1 - a.len);
		if (b.len <= n - 2) tmp &= all << (n - 1 - b.len);
		res.ans += tmp.count();
	}
	return res;
}
ll work(ll x) {
	info res;
	res.ans = 0;
	res.len = 0;
	res.pre.reset();
	res.suf.reset();
	int add = 0;
	for (int i = tot; i >= 0; i--) {
		for (int j = 1; j <= d; j++)
			if (x >= len[i]) {
				x -= len[i];
				res = res + dp[i][(add + gen[j]) % m];
			} else {
				add = (add + gen[j]) % m;
				break;
			}
	}
	return res.ans;
}
int main() {
	read(d), read(m);
	for (int i = 1; i <= d; i++)
		read(gen[i]);
	read(n);
	for (int i = 1; i <= n; i++)
		read(b[i]);
	for (int i = 1; i <= n - 1; i++)
		all.set(i);
	tot = 0, len[0] = 1;
	for (int i = 0; i <= m - 1; i++) {
		dp[0][i].len = 1;
		if (n == 1) dp[0][i].ans = i <= b[1];
		else {
			for (int j = 1; j <= n - 1; j++) {
				dp[0][i].pre[j] = i <= b[j + 1];
				dp[0][i].suf[j] = i <= b[j];
			}
		}
	}
	ll ql, qr; read(ql), read(qr);
	while (len[tot] <= qr / d) {
		tot++, len[tot] = len[tot - 1] * d;
		for (int i = 0; i <= m - 1; i++)
		for (int j = 1; j <= d; j++)
			dp[tot][i] = dp[tot][i] + dp[tot - 1][(i + gen[j]) % m];
	}
	writeln(work(qr) - work(ql + n - 2));
	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = last == 0 ? 0 : (num[i - have] >> (64 - last));
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		if (last) ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	int rans = 0;
	for (int i = l; i <= r; i++) {
		rans += get(i);
	}
	for (int i = l >> 6; i << 6 <= r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) {
			a &= ((r & 63) == 63 ? 0 : (1ull << ((r & 63) + 1))) - 1;
		}
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 2ll, other.len - 1));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	if (r == 0) return 0;
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int GetVal(ll no) {
	int ans = 0;
	while(no) {
		ans += multi[no % d];
		no /= d;
	}
	return ans;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
		dp[0][i].len = 1;
		dp[0][i].cnt = n == 1 && orig[0] >= i;
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}

//			vi temp(dp[index][0].len, 0);
//			for (int j = 0; j < dp[index][0].len; j++) {
//				for (int rj = j; rj; rj /= d) temp[j] += multi[rj % d];
//				temp[j] %= m;
//			}
//
//		for (int i = 0; i < m; i++) {
//			for (int j = 0; j < n - 1; j++) {
//				bool can = true;
//				int fail = 0;
//				for (int k = 0; k < min1(dp[index][0].len, n - 1ll, j + 1); k++) {
//					can &= orig[n - 1 - j + k] >= (temp[k] + i) % m;
//					if (can == false) {
//						fail = k;
//						break;
//					}
//				}
//				if (index == 2 && i == 35 && j == 396) {
//					cout << 1 << endl;
//				}
//				if (dp[index][i].prefix.get(j) != can) {
//					cout << index << ' ' << i << ' ' << j << ' ' << fail << endl;
//				}
//			}
//		}

	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;

	return 0;
}

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MN = 30010;

int D, M, N;
int G[66], B[MN];
ll L, R;
unordered_map<ll, vector<int> > cnt;

ll shift(ll bit, int k) {
    return (bit >> k) + (1LL << (M - k)) * (bit & ((1LL << k) - 1));
}

void solve(ll r, vector<ll> &X, int t) {
    if(r + 1 < X.size()) return;

    if(X.size() == 1) {
        if(cnt.find(r) == cnt.end()) {
            cnt[r] = vector<int>(M, 0);
        }
        for(int i = 0; i < M; i++) if(X[0] & (1LL << i)) cnt[r][i] += t;
        return;
    }
    if(r == 0) return;

    int n = X.size();
    for(int i = 0; i < D; i++) {

        vector<ll> x((i + n - 1) / D + 1, (1LL << M) - 1);
        for(int j = 0; j < n; j++) {
            x[ (i + j) / D ] &= shift(X[j], G[ (i + j) % D ]);
        }
        if(r >= (i + n - 1) % D) solve((r - (i + n - 1) % D) / D, x, t);
    }
}

vector<int> A;
ll dp[2][66][2];

void init(ll r) {
    A.clear();
    while(r) {
        A.push_back(r % D);
        r /= D;
    }

    memset(dp[1], 0, sizeof(dp[1]));

    dp[1][0][0] = dp[1][0][1] = 1;
    for(int i = 0; i < A.size(); i++) {
        for(int j = 0; j < M; j++) {
            for(int k = 0; k < 2; k++) {
                int c = i & 1;
                int p = c ^ 1;
                dp[c][j][k] = 0;
                for(int a = 0; a <= (k? A[i] : D - 1); a++) {
                    dp[c][j][k] += dp[p][ (j + M - G[a]) % M ][ k & (a == A[i]) ];
                }
            }
        }
    }
}

int main() {
    scanf("%d %d", &D, &M);

    for(int i = 0; i < D; i++) {
        scanf("%d", &G[i]);
    }

    //*
    scanf("%d", &N);

    for(int i = 0; i < N; i++) {
        scanf("%d", &B[i]);
    }
    //*/

    scanf("%lld %lld", &L, &R);
    L--; R--;

    vector<ll> X(N);
    for(int i = 0; i < N; i++) {
        X[i] = (1LL << (B[i] + 1)) - 1;
    }

    solve(L + N - 2, X, -1);
    solve(R, X, 1);

    ll ans = 0;
    for(auto it = cnt.begin(); it != cnt.end(); it++) {
        ll r = it->first;
        vector<int> X = it->second;

        init(r);
        for(int i = 0; i < M; i++) ans += dp[(int)(A.size() - 1) & 1][i][1] * X[i];
    }
    printf("%lld", ans);
}

#include<bits/stdc++.h>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define sz(a) int(a.size())
#define clr(a) memset(a,0,sizeof(a))
#define all(a) a.begin(),a.end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int,int> pii;
typedef pair<ll,int> pli;
const int inf=1e9;
const ll Inf=1e18;
const int mod=0;
int gi() {
    int x=0,o=1;char ch=getchar();
    while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
    if(ch=='-') o=-1,ch=getchar();
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*o;
}
template<typename T> bool chkmax(T &a,T b) { return a<b?a=b,1:0; };
template<typename T> bool chkmin(T &a,T b) { return a>b?a=b,1:0; };
int add(int a,int b) { return a+b>=mod?a+b-mod:a+b; }
int sub(int a,int b) { return a-b<0?a-b+mod:a-b; }
void inc(int &a,int b) { a=(a+b>=mod?a+b-mod:a+b); }
void dec(int &a,int b) { a=(a-b<0?a-b+mod:a-b); }
string to_string(string s) { return '"'+s+'"'; }
string to_string(const char *s) { return to_string((string)s); }
template<typename A,typename B> string to_string(pair<A,B> p) {
    return "("+to_string(p.fi)+","+to_string(p.se)+")";
}
template<typename T> string to_string(T v) {
    int fst=1;string ret="{";
    for(auto x:v) {
        if(!fst) ret+=",";
        fst=0,ret+=to_string(x);
    }
    ret+="}";return ret;
}
void dbg_out() { cerr<<endl; }
template<typename Head,typename... Tail> void dbg_out(Head H,Tail... T) {
    cerr<<" "<<to_string(H);
    dbg_out(T...);
}
#define dbg(...) cerr<<"{"<<#__VA_ARGS__<<"}:",dbg_out(__VA_ARGS__)

const int N=3e4+10;

int d,m,n,B[N],gen[N];
ll l,r;
bitset<N> all;

struct data {
    ll len=0,ans=0;
    bitset<N> pre,suf;
    data operator+(const data &A) const {
        if(len==0) return A;
        data B;
        B.len=len+A.len;
        B.ans=ans+A.ans;
        B.pre=pre;
        B.suf=A.suf;
        if(len<=n-2) B.pre&=(A.pre>>len)|(all<<(n-1-len));
        if(A.len<=n-2) B.suf&=(suf<<A.len)|(all>>(n-1-A.len));
        if(len+A.len>=n) {
            bitset<N> can=suf&A.pre;
            if(len<=n-2) can&=all>>(n-1-len);
            if(A.len<=n-2) can&=all<<(n-1-A.len);
            B.ans+=can.count();
        }
        return B;
    }
};

data f[70][70];
int dep=0;

ll solve(ll n) {
    int tag=0;
    data ret;
    for(int i=dep;~i;i--) {
        for(int j=1;j<=d;j++) {
            if(n>=f[i][(tag+gen[j])%m].len) ret=ret+f[i][(tag+gen[j])%m],n-=f[i][(tag+gen[j])%m].len;
            else { tag=(tag+gen[j])%m;break; }
        }
    }
    return ret.ans;
}

int main() {
#ifndef ONLINE_JUDGE
    freopen("a.in","r",stdin);
    freopen("a.out","w",stdout);
#endif
    d=gi(),m=gi();
    for(int i=1;i<=d;i++) gen[i]=gi();
    n=gi();
    for(int i=1;i<=n;i++) B[i]=gi();
    for(int i=1;i<=n-1;i++) all[i]=1;
    cin>>l>>r;
    for(int i=0;i<m;i++) {
        f[0][i].len=1;
        if(n==1) f[0][i].ans=(i<=B[1]);
        else for(int j=1;j<=n-1;j++) f[0][i].pre[j]=(i<=B[j+1]),f[0][i].suf[j]=(i<=B[j]);
    }
    while(f[dep][0].len<=r/d) {
        ++dep;
        for(int i=0;i<m;i++) {
            for(int j=1;j<=d;j++) f[dep][i]=f[dep][i]+f[dep-1][(i+gen[j])%m];
        }
    }
    //dbg(solve(r),solve(l+n-2));
    printf("%lld\n",solve(r)-solve(l+n-2));
    return 0;
}

#include<bits/stdc++.h>

typedef long long ll;

const int N = 30010;
const int M = 110;

int gen[N];
ll power[N];
int d, m;
ll dp[M][M];
int digit[M];
ll res[M][M][2];
int n;

void dfs(int now, int max, ll remain, auto vec, ll &ans, ll r){
    if (now == max){
        return;
    }
    if ((int) vec.size() == 1){
        int sit = r % power[now] >= remain;
        for (int i = 0; i < m; ++ i){
            if (vec[0] >> i & 1){
                ans += res[now][i][sit];
            }
        }
        return;
    }
    for (int i = 0; i < d; ++ i){
        ll nremain = remain + power[now] * i;
        std::vector <ll> nvec;
        ll y = (1ll << m) - 1;
        for (int j = i, sz = vec.size(); j < i + sz; ++ j){
            ll x = vec[j - i], rem = gen[j % d];
            x = (x >> rem) | ((x & ((1ll << rem) - 1)) << (m - rem));
            y &= x;
            if (j == i + sz - 1 || j % d == d - 1){
                nvec.push_back(y);
                y = (1ll << m) - 1;
            }
        }
        dfs(now + 1, max, nremain, nvec, ans, r);
    }
}

ll solve(ll r, auto vec){
    if (r < 0) return 0;
    power[0] = 1;
    int max = 0;
    for (int i = 1; i < N; ++ i){
        power[i] = power[i - 1] * d;
        if (power[i - 1] > std::max((ll) n * d, r)){
            max = i;
            break;
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 1; i <= max; ++ i){
        for (int j = 0; j < m; ++ j){
            for (int k = 0; k < d; ++ k){
                dp[i][(j + gen[k]) % m] += dp[i - 1][j];
            }
        }
    }
    auto calc = [&](ll x, int remain){
        int cnt = 0;
        while (x){
            digit[cnt ++] = x % d;
            x /= d;
        }
        std::reverse(digit, digit + cnt);
        int nowremain = 0;
        ll ans = 0;
        for (int i = 0; i < cnt; ++ i){
            for (int j = 0; j < digit[i]; ++ j){
                int x = (nowremain + gen[j]) % m;
                x = (remain - x + m) % m;
                ans += dp[cnt - i - 1][x];
            }
            nowremain = (nowremain + gen[digit[i]]) % m;
        }
        return ans;
    };
    memset(res, 0, sizeof(res));
    for (int i = 0; i <= max; ++ i){
        for (int j = 0; j < m; ++ j){
            res[i][j][0] = calc(r / power[i], j);
            res[i][j][1] = calc(r / power[i] + 1, j);
        }
    }
    ll ans = 0;
    dfs(0, max, 0, vec, ans, r);
    return ans;
}

int main(){
    scanf("%d%d", &d, &m);
    for (int i = 0; i < d; ++ i){
        scanf("%d", &gen[i]);
    }
    scanf("%d", &n);
    std::vector <ll> vec;
    for (int i = 0, x; i < n; ++ i){
        scanf("%d", &x);
        vec.push_back((1ll << (x + 1)) - 1);
    }
    ll l, r;
    scanf("%lld%lld", &l, &r);
    -- l, -- r;
    if (r - l + 1 < n){
        puts("0");
        return 0;
    }
    printf("%lld\n", solve(r - (n - 1), vec) - solve(l - 1, vec));
    return 0;
}

# include <iostream>
# include <sstream>
# include <cstdio>
# include <cstdlib>
# include <algorithm>
# include <string>
# include <cstring>
# include <cmath>
# include <stack>
# include <queue>
# include <vector>
# include <list>
# include <map>
# include <set>
# include <deque>
# include <iterator>
# include <functional>
# include <bitset>
# include <climits>
# include <ctime>
using namespace std;
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define odd(x) ((x)&1)
#define sqr(x) ((x)*(x))
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define mem(a,x) memset(a,x,sizeof(a))
#define rep(i,a,b) for (int i=(a); i<=(b); ++i)
#define per(i,a,b) for (int i=(a); i>=(b); --i)
#define rep_it(it,x) for (__typeof((x).begin()) it=(x).begin(); it!=(x).end(); it++)
#define ____ puts("\n_______________\n\n")
#define debug(x) ____; cout<< #x << " => " << (x) << endl
#define debug_pair(x) cout<<"\n{ "<<(x).fir<<" , "<<(x).sec<<" }\n"
#define debug_arr(x,n) ____; cout<<#x<<":\n"; rep(i,0,n) cout<<#x<<"["<<(i)<<"] => "<<x[i]<<endl
#define debug_arr2(x,n,m) ____; cout<<#x<<":\n"; rep(i,0,n) rep(j,0,m) cout<<#x<<"["<<(i)<<"]["<<(j)<<"]= "<<x[i][j]<<((j==m)?"\n\n":"    ")
#define debug_set(x) ____; cout<<#x<<": \n"; rep_it(it,x) cout<<(*it)<<" "; cout<<endl
#define debug_map(x) ____; cout<<#x<<": \n"; rep_it(it,x) debug_pair(*it)
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
typedef vector<int> vi;
const int oo = /*2 * 1000 * 1000 * 1000*/0x3f3f3f3f;
const ll ooo=9223372036854775807ll;
const int _cnt = 1000 * 1000 + 7;
const int _p = 1000 * 1000 * 1000 + 7;
const int N=30005;
const double PI=acos(-1.0);
const double eps=1e-9;
int o(int x) { return x%_p; }
int gcd(int a, int b) { return b ? gcd(b, a%b) : a; }
int lcm(int a, int b) { return a / gcd(a, b)*b; }

void file_put() {
	string s="/home/jslijin/jslijin/code/";
    freopen((s+"code.in").c_str(), "r", stdin);
    freopen((s+"code.out").c_str(), "w", stdout);
}

int n,m,d,B[N],c=0,gen[25],delta; ll P[65],l,r; bitset<N> one,tmp;

struct node{
	ll num,len; bitset<N> pre,suf;
	node() { num=len=0; pre=suf=0; }
} f[65][60];

inline node operator+ (node &a, node &b) {
	if (!a.len) return b; node ret;
	ret.len=a.len+b.len;
	ret.num=a.num+b.num;
	ret.pre=a.pre,ret.suf=b.suf;
	if (a.len<n-1) ret.pre&=(b.pre>>a.len)|(one<<n-1-a.len);
	if (b.len<n-1) ret.suf&=(a.suf<<b.len)|(one>>n-1-b.len);
	if (ret.len<n) return ret;
	tmp=a.suf&b.pre;
	if (a.len<n-1) tmp&=one>>n-1-a.len;
	if (b.len<n-1) tmp&=one<<n-1-b.len;
	ret.num+=tmp.count();
	return ret;
}

ll solve(ll n) {
	for (c=0,delta=0; P[c+1]<=n; ++c);
	node ret;
	per(i,c,0) rep(k,0,d-1)
		if (n>=P[i]) {
			ret=ret+f[i][(delta+gen[k])%m];
			n-=P[i];
			if (!n) return ret.num;
		} else {
			delta+=gen[k];
			break;
		}
	return ret.num;
}

int main() {
    //file_put();

    scanf("%d%d",&d,&m);
    rep(i,0,d-1) scanf("%d",&gen[i]);
    scanf("%d",&n);
    rep(i,1,n) scanf("%d",&B[i]);
    scanf("%lld%lld",&l,&r);
    P[0]=1; rep(i,1,64) P[i]=P[i-1]*d;
    for (; P[c+1]<=r; ++c);
    rep(i,1,n-1) one[i]=1;
    rep(j,0,m-1) {
    	f[0][j].len=1;
    	if (n==1) f[0][j].num=j<=B[1]; else
    		rep(k,1,n-1) f[0][j].pre[k]=j<=B[k+1],
				f[0][j].suf[k]=j<=B[k];
	}
	rep(i,1,c) rep(j,0,m-1) rep(k,0,d-1)
		f[i][j]=f[i][j]+f[i-1][(j+gen[k])%m];
	printf("%lld\n",solve(r)-solve(l+n-2));

    return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int maxn = 30000;

int d, m, n;
long long l, r;
long long sz = 1;

bitset<maxn> one;

struct info {
  bitset<maxn> prefix;
  bitset<maxn> suffix;
  long long ans = 0;
  long long len = 0;
};

info merge(info &l, info &r) {
    info res;
    res.prefix = l.prefix;
    res.suffix = r.suffix;
    res.ans = l.ans + r.ans;
    res.len = l.len + r.len;
    if (l.len < n - 1) {
    	res.prefix &= r.prefix >> l.len | one << n - 1 - l.len;
    }
    if (r.len < n - 1) {
    	res.suffix &= l.suffix << r.len | one >> n - 1 - r.len;
    }
    if (l.len + r.len >= n) {
    	bitset<maxn> b = l.suffix & r.prefix;
    	if (l.len < n - 1) {
        	b &= one >> n - 1 - l.len;
    	}
    	if (r.len < n - 1) {
        	b &= one << n - 1 - r.len;
    	}
    	res.ans += b.count();
    }
    return res;
}

long long solve(long long k, vector<int> gen, vector<vector<info> > dp) {
    long long cur = sz;
    int diff = 0;
    info res;
    for (int i = dp.size() - 1; ~i; --i, cur /= d) {
    	for (int j = 0; j < d; ++j) {
    		if (k >= cur) {
    			res = merge(res, dp[i][(diff + gen[j]) % m]);
    			k -= cur;
			} else {
    			diff = (diff + gen[j]) % m;
				break;
			}
		}
    }
    return res.ans;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);

	cin >> d >> m;

	vector<int> gen(d);
	for (int i = 0; i < d; ++i) {
    	cin >> gen[i];
	}

	cin >> n;
	vector<int> b(n);
	for (int i = 0; i < n; ++i) {
    	cin >> b[i];
	}

	cin >> l >> r;

	for (int i = 0; i < n - 1; ++i) {
		one[i] = 1;
	}

	vector<vector<info> > dp(1, vector<info>(m));
	for (int i = 0; i < m; ++i) {
    	dp[0][i].len = 1;
    	if (n == 1) {
			dp[0][i].ans = b[0] >= i;
    	} else {
    		for (int j = 0; j < n - 1; ++j) {
        		if (b[j + 1] >= i) {
    				dp[0][i].prefix[j] = true;
    			}
        		if (b[j] >= i) {
    				dp[0][i].suffix[j] = true;
        		}
    		}
    	}
	}

	while (sz <= r / d) {
		int cur = dp.size();
		dp.push_back(dp.back());
		for (int i = 0; i < m; ++i) {
    		for (int j = 1; j < d; ++j) {
				dp[cur][i] = merge(dp[cur][i], dp[cur - 1][(i + gen[j]) % m]);
    		}
		}
		sz *= d;
	}

	cout << solve(r, gen, dp) - solve(l + n - 2, gen, dp) << "\n";
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int MAX = 30000;

struct info {
  bitset<MAX> prefix;
  bitset<MAX> suffix;
  long long ans = 0;
  long long len = 0;
};

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; ++i) {
    cin >> gen[i];
  }
  int n;
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; ++i) {
    cin >> b[i];
  }
  long long l, r;
  cin >> l >> r;
  bitset<MAX> one;
  for (int i = 0; i < n - 1; ++i) {
    one[i] = 1;
  }
  auto merge = [&](const info &l, const info &r) {
    info res;
    res.prefix = l.prefix;
    res.suffix = r.suffix;
    res.ans = l.ans + r.ans;
    res.len = l.len + r.len;
    if (l.len < n - 1) {
      res.prefix &= r.prefix >> l.len | one << n - 1 - l.len;
    }
    if (r.len < n - 1) {
      res.suffix &= l.suffix << r.len | one >> n - 1 - r.len;
    }
    if (l.len + r.len >= n) {
      bitset<MAX> b = l.suffix & r.prefix;
      if (l.len < n - 1) {
        b &= one >> n - 1 - l.len;
      }
      if (r.len < n - 1) {
        b &= one << n - 1 - r.len;
      }
      res.ans += b.count();
    }
    return res;
  };
  vector<vector<info>> dp(1, vector<info>(m));
  for (int i = 0; i < m; ++i) {
    dp[0][i].len = 1;
    if (n == 1) {
      dp[0][i].ans = b[0] >= i;
    } else {
      for (int j = 0; j < n - 1; ++j) {
        if (b[j + 1] >= i) {
          dp[0][i].prefix[j] = true;
        }
        if (b[j] >= i) {
          dp[0][i].suffix[j] = true;
        }
      }
    }
  }
  long long sz = 1;
  while (sz <= r / d) {
    int cur = dp.size();
    dp.push_back(dp.back());
    for (int i = 0; i < m; ++i) {
      for (int j = 1; j < d; ++j) {
        dp[cur][i] = merge(dp[cur][i], dp[cur - 1][(i + gen[j]) % m]);
      }
    }
    sz *= d;
  }
  auto solve = [&](long long k) {
    long long cur = sz;
    int diff = 0;
    info res;
    for (int i = dp.size() - 1; ~i; --i, cur /= d) {
      for (int j = 0; j < d; ++j) {
        if (k >= cur) {
          res = merge(res, dp[i][(diff + gen[j]) % m]);
          k -= cur;
        } else {
          diff = (diff + gen[j]) % m;
          break;
        }
      }
    }
    return res.ans;
  };
  cout << solve(r) - solve(l + n - 2) << "\n";
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[100][100]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>min(a.len,30000ll))^all))|((b.a>>min(a.len,30000ll))&a.a);
	c.b=(b.b&((all<<min(b.len,30000ll))^all))|((a.b<<min(b.len,30000ll))&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<min(a.len,30000ll))^all));
	opt=(opt&((all>>min(b.len+1,30001ll))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
//		if(d==4&&m==2){
//			cout<<f[i][0].sum<<" "; if(i%6==0) cout<<endl;
//		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
//	if(d==4&&m==2) cout<<solve(r)<<","<<solve(l+n-2)<<endl;
	cout<<solve(r)-solve(l+n-2ll)<<endl;
}

/**
 *    author:  tourist
 *    created: 04.01.2019 20:26:25
**/
#include <bits/stdc++.h>

using namespace std;

const int MAX = 30010;

struct State {
  bitset<MAX> left;
  bitset<MAX> right;
  long long len = 0;
  long long res = 0;
};

int n;
bitset<MAX> all;

State Unite(const State& a, const State& b) {
  State c;
  c.len = a.len + b.len;
  c.res = a.res + b.res;
  c.left = a.left;
  c.right = b.right;
  if (a.len < n - 1) {
    c.left &= (b.left >> a.len) | (all << (n - 1 - a.len));
  }
  if (b.len < n - 1) {
    c.right &= (a.right << b.len) | (all >> (n - 1 - b.len));
  }
  if (a.len + b.len >= n) {
    bitset<MAX> d = a.right & b.left;
    if (a.len < n - 1) {
      d &= (all >> (n - 1 - a.len));
    }
    if (b.len < n - 1) {
      d &= (all << (n - 1 - b.len));
    }
    c.res += d.count();
  }
  return c;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; i++) {
    cin >> gen[i];
  }
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; i++) {
    cin >> b[i];
  }
  long long L, R;
  cin >> L >> R;
  for (int i = 1; i < n; i++) {
    all.set(i);
  }
  vector<vector<State>> states(1, vector<State>(m));
  for (int i = 0; i < m; i++) {
    states[0][i].len = 1;
    if (n == 1) {
      states[0][i].res = b[0] >= i;
    } else {
      for (int j = 1; j < n; j++) {
        if (b[j] >= i) {
          states[0][i].left.set(j);
        }
      }
      for (int j = 1; j < n; j++) {
        if (b[j - 1] >= i) {
          states[0][i].right.set(j);
        }
      }
    }
  }
  long long z = 1;
  while (z <= R / d) {
    int sz = (int) states.size();
    states.resize(sz + 1);
    states[sz].resize(m);
    for (int i = 0; i < m; i++) {
      State cur = states[sz - 1][i];
      for (int j = 1; j < d; j++) {
        cur = Unite(cur, states[sz - 1][(i + gen[j]) % m]);
      }
      states[sz][i] = cur;
    }
    z *= d;
  }
  auto calc = [&](long long up) -> long long {
    State res;
    int shift = 0;
    for (int i = (int) states.size() - 1; i >= 0; i--) {
      z = 1;
      for (int j = 0; j < i; j++) {
        z *= d;
      }
      for (int j = 0; j < d; j++) {
        if (up >= z) {
          res = Unite(res, states[i][(shift + gen[j]) % m]);
          up -= z;
        } else {
          shift = (shift + gen[j]) % m;
          break;
        }
      }
    }
    return res.res;
  };
  cout << calc(R) - calc(L + n - 2) << '\n';
  return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30005;
int d,m,n,lm,i,j,b[N],gen[25];
ll L,R;
struct atom{
	bitset<N>pr,sf,all;
	ll ans,l;
	void set(int v){
		if(v<=b[n])pr.set(n);if(v<=b[1])sf.set(1);
		for(int i=1;i<=n;++i)if(v<=b[i])all.set(i);
		ans=n==1 && v<=b[1];l=1;
	}
}a[65][65];
inline atom uni(const atom&a,const atom&b){
	static atom ret;
	ret.l=a.l+b.l;
	ret.pr=a.pr;if(a.l<n)ret.pr|=(a.all<<a.l&b.pr)>>a.l;
	ret.sf=b.sf;if(b.l<n)ret.sf|=(b.all>>1&a.sf)<<b.l;
	if(a.l+b.l<=n)ret.all=b.all>>a.l&a.all;else ret.all.reset();
	ret.ans=a.ans+b.ans+(a.sf<<1&b.pr).count();
	return ret;
}
inline ll calc(ll x){
	ll y=0,pr=0;
	static atom ans;bool fl=0;ans.ans=0;
	for(i=lm-1;i>=0;--i){
		for(j=0;y+a[i][(pr+gen[j])%m].l<=x;++j){
			if(!fl)ans=a[i][(pr+gen[j])%m],fl=1;else ans=uni(ans,a[i][(pr+gen[j])%m]);
			y+=a[i][(pr+gen[j])%m].l;
		}
		pr=(pr+gen[j])%m;
	}
	return ans.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);for(i=0;i<d;++i)scanf("%d",gen+i);
	scanf("%d",&n);for(i=1;i<=n;++i)scanf("%d",b+i);scanf("%lld%lld",&L,&R);
	for(i=0;i<m;++i)a[0][i].set(i);
	for(lm=1;a[lm-1][0].l<=R/d;++lm)for(i=0;i<m;++i){
		a[lm][i]=a[lm-1][(i+gen[0])%m];
		for(j=1;j<d;++j)a[lm][i]=uni(a[lm][i],a[lm-1][(i+gen[j])%m]);
	}
	printf("%lld\n",calc(R)-calc(L+n-2));
	return 0;
}

/**
 *    author:  tourist
 *    created: 04.01.2019 20:26:25
**/
#include <bits/stdc++.h>

using namespace std;

string to_string(string s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; i++) {
    cin >> gen[i];
  }
  int n;
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; i++) {
    cin >> b[i];
  }
  const int MAX = 30010;
  struct State {
    bitset<MAX> left;
    bitset<MAX> right;
    long long len;
    long long res;
  };
  auto dbg = [&](const State& a) {
    for (int i = 1; i < n; i++) cerr << a.left[i];
    cerr << " ";
    for (int i = 1; i < n; i++) cerr << a.right[i];
    cerr << " ";
    cerr << a.len << " " << a.res << '\n';
  };
  bitset<MAX> all;
  for (int i = 1; i < n; i++) all.set(i);
  auto Unite = [&](const State& a, const State& b) -> State {
    State c;
    c.len = a.len + b.len;
    c.res = a.res + b.res;
    c.left = a.left;
    c.right = b.right;
    if (a.len < n - 1) {
      c.left &= (b.left >> a.len) | (all << (n - 1 - a.len));
    }
    if (b.len < n - 1) {
      c.right &= (a.right << b.len) | (all >> (n - 1 - b.len));
    }
    if (a.len + b.len >= n) {
      bitset<MAX> d = a.right & b.left;
      if (a.len < n - 1) {
        d &= (all >> (n - 1 - a.len));
      }
      if (b.len < n - 1) {
        d &= (all << (n - 1 - b.len));
      }
      c.res += d.count();
    }
    return c;
  };
  auto calc = [&](long long up) -> long long {
    if (up < n) {
      return 0;
    }
    vector<vector<State>> states(1, vector<State>(m));
    for (int i = 0; i < m; i++) {
      states[0][i].len = 1;
      if (n == 1) {
        states[0][i].res = b[0] >= i;
      } else {
        for (int j = 1; j < n; j++) {
          if (b[j] >= i) {
            states[0][i].left.set(j);
          }
        }
        for (int j = 1; j < n; j++) {
          if (b[j - 1] >= i) {
            states[0][i].right.set(j);
          }
        }
      }
//      dbg(states[0][i]);
    }
    long long z = 1;
    while (z <= up / d) {
      int sz = (int) states.size();
      states.resize(sz + 1);
      states[sz].resize(m);
      for (int i = 0; i < m; i++) {
        State cur = states[sz - 1][i];
        for (int j = 1; j < d; j++) {
          cur = Unite(cur, states[sz - 1][(i + gen[j]) % m]);
        }
        states[sz][i] = cur;
//        dbg(states[sz][i]);
      }
      z *= d;
    }
    State res;
    int any = 0;
    int shift = 0;
    for (int i = (int) states.size() - 1; i >= 0; i--) {
      z = 1;
      for (int j = 0; j < i; j++) {
        z *= d;
      }
      for (int j = 0; j < d; j++) {
        if (up >= z) {
          if (!any) res = states[i][(shift + gen[j]) % m];
          else res = Unite(res, states[i][(shift + gen[j]) % m]);
          any = 1;
          up -= z;
        } else {
          shift = (shift + gen[j]) % m;
          break;
        }
      }
    }
    return res.res;
  };
  long long L, R;
  cin >> L >> R;
  cout << calc(R) - calc(L + n - 2) << '\n';
  return 0;
}

#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
using ull = uint64_t;
using ll = int64_t;
using ld = long double;

const int D = 22;
const int M = 62;
const int B = 62;
const int N = 30228;

int n, d, m;

ll MASK;

int gen[D];
int b[N];

ll rot(ll x, int y) {
    return ((x >> y) + (x << (m - y))) & MASK;
}

struct LBorder {
    ll g[N];
    ll len;

    LBorder() : g{}, len(0) {
        fill(g, g + n + 1, MASK);
    }

    ll at(ll x) const {
        return (x < n) ? g[x] : MASK;
    }

    LBorder rot(int y) const {
        LBorder ans;
        ans.len = len;

        for (int i = 0; i < n; ++i) {
            ans.g[i] = ::rot(g[i], y);
        }

        return ans;
    }

    friend LBorder operator + (const LBorder& lhs, const LBorder& rhs) {
        LBorder ans;
        ans.len = lhs.len + rhs.len;

        for (int i = 0; i <= n; ++i) {
            ans.g[i] = lhs.at(i) & rhs.at(i + lhs.len);
        }

        return ans;
    }
};

struct RBorder {
    ll g[N];
    ll len;

    RBorder() : g{}, len(0) {
        fill(g, g + n + 1, MASK);
    }

    ll at(ll x) const {
        return (x > 0) ? g[x] : MASK;
    }

    RBorder rot(int y) const {
        RBorder ans;
        ans.len = len;

        for (int i = 0; i < n; ++i) {
            ans.g[i] = ::rot(g[i], y);
        }

        return ans;
    }

    friend RBorder operator + (const RBorder& lhs, const RBorder& rhs) {
        RBorder ans;
        ans.len = lhs.len + rhs.len;

        for (int i = 0; i <= n; ++i) {
            ans.g[i] = rhs.at(i) & lhs.at(i - rhs.len);
        }

        return ans;
    }
};

struct Value {
    LBorder l;
    RBorder r;
    ll a[M];

    Value() : a{} {
    }

    void solo() {
        for (int i = 0; i < n; ++i) {
            l.g[i] = r.g[i + 1] = (1ll << (b[i] + 1)) - 1;
        }

        l.len = r.len = 1;

        if (n == 1) {
            for (int i = 0; i <= b[0]; ++i) {
                ++a[i];
            }
        }
    }

    ll len() const {
        return l.len;
    }

    Value rot(int y) const {
        Value res;
        res.l = l.rot(y);
        res.r = r.rot(y);
        for (int i = 0; i < m; ++i) {
            res.a[i] = a[(i + y) % m];
        }

        return res;
    }

    friend Value operator + (const Value& lhs, const Value &rhs) {
        Value ans;
        ans.l = lhs.l + rhs.l;
        ans.r = lhs.r + rhs.r;
        for (int i = 0; i < m; ++i) {
            ans.a[i] = lhs.a[i] + rhs.a[i];
        }

        for (int i = 1; i < n; ++i) {
            if (i <= lhs.len() && i + rhs.len() >= n) {
                ll cur = lhs.r.at(i) & rhs.l.at(i);
                for (int j = 0; j < m; ++j) {
                    ans.a[j] += (cur >> j) & 1;
                }
            }
        }

        return ans;
    }
};

Value f[B];
ll pw[B];

int k;

void precalc(ll r) {
    f[0].solo();

    pw[0] = 1;
    while (r / pw[k] >= d) {
        ++k;
        f[k] = Value();

        pw[k] = pw[k - 1] * d;
        for (int i = 0; i < d; ++i) {
            f[k] = f[k] + f[k - 1].rot(gen[i]);
        }
    }
}

ll eval(ll x) {
    int y = 0;
    Value cur;

    for (int i = k; i >= 0; --i) {
        int cn = x / pw[i];
        assert(cn < d);
        for (int j = 0; j < cn; ++j) {
            cur = cur + f[i].rot((y + gen[j]) % m);
        }

        y = (y + gen[cn]) % m;
        x %= pw[i];
    }

    return cur.a[0];
}

int main() {
#ifdef BZ
    freopen("input.txt", "r", stdin);
#endif
    ios_base::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); cout.setf(ios::fixed); cout.precision(20);
    cin >> d >> m;
    MASK = (1ll << m) - 1;
    for (int i = 0; i < d; ++i) {
        cin >> gen[i];
    }

    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> b[i];
    }

    ll l, r;
    cin >> l >> r;
    precalc(r);

    ll ar = eval(r);
    ll al = eval(l + n - 2);

    cout << ar - al << "\n";
}

#pragma region
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[30]; short m=0;
	if(x<0) {if(x==-2147483648) {printf("-2147483648"); return;} putchar('-'),x=-x;}
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T>il void prt(T a[],int n) {for(ri i=0; i<n; ++i) out(a[i],' '); enter;}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=1e9+7;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
typedef bitset<30005> B;
int n;
B all;
struct Data
{
	LL len,ans;
	B pre,suf;
	il friend Data operator+(const Data &a,const Data &b)
	{
		Data c; c.len=a.len+b.len,c.ans=a.ans+b.ans;
		c.pre=a.pre,c.suf=b.suf;
		if(a.len<n-1) c.pre&=(b.pre<<a.len)|(all>>(n-a.len-1));
		if(b.len<n-1) c.suf&=(a.suf>>b.len)|(all<<(n-b.len-1));
		if(c.len>=n)
		{
			B t=a.suf&b.pre;
			if(a.len<n-1) t&=(all<<(n-a.len-1));
			if(b.len<n-1) t&=(all>>(n-b.len-1));
			c.ans+=t.count();
		}
		return c;
	}
	il void operator+=(const Data &v)
	{
		if(!len) *this=v;
		else *this=*this+v;
	}
} f[65][65];
int d,m;
int gen[25];
LL len[65]; int tot;
LL query(LL R)
{
	Data res; res.len=0,res.ans=0;
	int tag=0;
	for(ri i=tot; i>=0; --i)
		for(ri j=1; j<=d; ++j)
			if(R>=len[i])
			{
				res+=f[i][(tag+gen[j])%m];
				R-=len[i];
			}
			else {(tag+=gen[j])%=m; break;}
	return res.ans;
}
int b[30005];
LL L,R;
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(d,m);
	for(ri i=1; i<=d; ++i) in(gen[i]);
	in(n);
	for(ri i=1; i<=n; ++i) in(b[i]);
	for(ri i=1; i<n; ++i) all[i]=1;
	len[0]=1;
	for(ri i=0; i<m; ++i)
	{
		f[0][i].len=1;
		if(n==1) f[0][i].ans=(i<=b[1]);
		else
		{
			for(ri j=1; j<n; ++j)
			{
				f[0][i].pre[j]=(i<=b[n-j+1]);
				f[0][i].suf[j]=(i<=b[n-j]);
			}
		}
	}
	in(L,R);
	while(len[tot]<=R/d)
	{
		++tot,len[tot]=len[tot-1]*d;
		for(ri i=0; i<m; ++i)
			for(ri j=1; j<=d; ++j)
				f[tot][i]+=f[tot-1][(i+gen[j])%m];
	}
	LL ans=query(R)-query(L+n-2);
	out(ans);
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];
unordered_map<int64,vector<int64>> htable;

void prepare()
{
	htable.clear();
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}

int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int64>& wcnt=htable[w];
	if (SIZE(wcnt)==0)
	{
		wcnt=vector<int64>(MOD);
		vector<int> digits;
		for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
		int s=0;
		REP(i,SIZE(digits)) s+=gen[digits[i]];
		REP(i,SIZE(digits))
		{
			s-=gen[digits[i]];
			REP(d,digits[i])
			{
				int s0=s+gen[d];
				REP(w,MOD) wcnt[(s0+w)%MOD]+=cnt[i][w];
			}
		}
	}
	int64 ret=0;
	REP(i,MOD) if (contain(mask,i)) ret+=wcnt[i];
	assert(ret<=w+1);
	return ret;
}

int64 solve(vector<int64> a,int64 w)
{
	if (w<0) return 0;
	if (SIZE(a)==1) return calc(w,a[0]);
	vector<int64> b;
	int64 ret=0;
	REP(md,m) if (md<=w)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			for (;at>=SIZE(b);b.push_back(two(MOD)-1));
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok) ret+=solve(b,(w-md)/m);
	}
	assert(ret<=w+1);
	return ret;
}
int64 solve(int64 w)
{
	if (w<0) return 0;
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
#ifdef _MSC_VER
		if (n>10)
			REP(i,n) a[i]=MOD-1;//()%MOD;
		else
			REP(i,n) cin>>a[i];
#else
		REP(i,n) cin>>a[i];
#endif
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(r-n+1)-solve(l-1);
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#include<bits/stdc++.h>
const int N = 3e4 + 10;
typedef std::bitset<N> BI;
long long ri() {
	char c = getchar(); long long x = 0, f = 1; for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct info {
	long long ans, len;
	BI pre, suf;
	info operator + (const info &b) { //Merge this and b
		info c;
		c.ans = ans + b.ans;
		c.len = len + b.len;
		c.pre = pre; c.suf = b.suf;
		if(len < n - 1) c.pre &= (b.pre << len) | (all >> n - 1 - len);
		if(b.len < n - 1) c.suf &= (suf >> b.len) | (all << n - 1 - b.len);
		if(len + b.len >= n) {
			BI res = suf & b.pre;
			if(len < n - 1) res &= (all << n - 1 - len);
			if(b.len < n - 1) res &= (all >> n - 1 - b.len);
			c.ans += res.count();
		}
		return c;
	}
	void operator += (const info &b) {*this = !len ? b : *this + b;}
} f[66][66];
long long Query(long long x) {
	info res; res.ans = res.len = 0;
	int add = 0;
	for(int i = tot; ~i; --i)
		for(int j = 1; j <= d; ++j) {
			if(x >= len[i]) {
				x -= len[i];
				res += f[i][(add + gen[j]) % m];
			}
			else {
				(add += gen[j]) %= m;
				break;
			}
		}
	return res.ans;
}
int main() {
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	d = ri(); m = ri();
	for(int i = 1; i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1; i <= n; ++i)
		b[i] = ri();
	for(int i = 1; i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0; i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1; j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[ n - j + 1];
				f[0][i].suf[j] = i <= b[ n - j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(; len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0; i < m; ++i)
			for(int j = 1; j <= d; ++j)
				f[tot][i] += f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", Query(R) - Query(L + n - 2));
	return 0;
}

#include <bits/stdc++.h>
#ifdef local
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;

const int N = 3e4 + 5;

#define ll long long

typedef class Data {
	public:
		ll ans, len;
		bitset<N> pre, suf;
		// pre_i : first (n - i - 1) characters
		// suf_i : last (i + 1) characters

		Data() : ans(0), len(0) {	}
} Data;

bitset<N> msk;

void debug(const bitset<N>& bs, int lim) {
	for (int i = lim - 1; ~i; i--) {
		putchar('0' + bs.test(i));
	}
}

int n, d, m;
int cnt = 1;
int *gen, *a;
Data f[66][65];
ll len[65], L, R;

ostream& operator << (ostream& os, const bitset<N>& bs) {
	debug(bs, n - 1);
	return os;
}

bitset<N> reserve(const bitset<N>& bs, int l, int r) {
	assert(l <= r);
	r++;
	return ((bs >> l) << (N - (r - l))) >> (N - r);;
}

Data operator + (const Data& a, const Data& b) {
	Data rt;
	rt.pre = a.pre, rt.suf = b.suf;
	rt.ans = a.ans + b.ans, rt.len = a.len + b.len;
	if (a.len < n - 1)
		rt.pre = ((b.pre >> a.len) & a.pre) | reserve(a.pre, n - a.len - 1, n);
	if (b.len < n - 1)
		rt.suf = ((a.suf << b.len) & b.suf) | reserve(b.suf, 0, b.len - 1);
	if (a.len + b.len > n - 1) {
// i <= a.len, n - i <= b.len
// i <= a.len, i >= n - b.len
		int l = max(1ll, n - b.len) - 1, r = min((ll) n, a.len) - 1;
		if (l <= r) {
			rt.ans += (reserve(a.suf, l, r) & b.pre).count();
		}
	}
	return rt;
}

inline void init() {
	scanf("%d%d", &d, &m);
	gen = new int[(d + 1)];
	for (int i = 0; i < d; i++) {
		scanf("%d", gen + i);
	}
	scanf("%d", &n);
	a = new int[(n + 1)];
	for (int i = 0; i < n; i++) {
		scanf("%d", a + i);
	}
	scanf(Auto""Auto, &L, &R);
}

ll Solve(ll L) {
	Data rt;
	rt.pre = msk, rt.suf = msk;
	int add = 0;
	for (int i = cnt; ~i; i--) {
		int dif = 0;
		for (int j = 0; L >= len[i]; j++, L -= len[i]) {
			dif = gen[j + 1];
			rt = rt + f[i][(add + gen[j]) % m];
		}
		add = (add + dif) % m;
	}
	return rt.ans;
}

inline void solve() {
	for (int i = 0; i < n - 1; i++)
		msk.set(i);
	len[0] = 1, len[1] = d;
	for (int i = 0; i < m; i++) {
		f[0][i].len = 1, f[0][i].ans = (n == 1 && i <= a[0]);
		for (int j = 0; j < n - 1; j++) {
			f[0][i].pre[j] = (i <= a[n - j - 1]);
			f[0][i].suf[j] = (i <= a[j]);
		}
	}
	for (int i = 0; i < m; i++) {
		f[1][i].len = d, f[1][i].ans = 0;
		if (d >= n) {
			for (int s = 0; s <= d - n; s++) {
				int dif = 1;
				for (int j = 0; j < n && dif == 1; j++) {
					dif -= (((gen[s + j] + i) % m) > a[j]);
				}
				f[1][i].ans += dif;
			}
		}
		for (int l = 0; l < n - 1; l++) {
			int sgn_pre = 1, sgn_suf = 1;
			for (int j = 0; j < d && j <= l && (sgn_pre + sgn_suf); j++) {
				sgn_suf = sgn_suf && (((gen[d - j - 1] + i) % m) <= a[l - j]);
				sgn_pre = sgn_pre && (((gen[j] + i) % m) <= a[n - l - 1 + j]);
			}
			f[1][i].suf[l] = sgn_suf;
			f[1][i].pre[n - l - 2] = sgn_pre;
		}
//		cerr << "> " << 1 << " " << i << '\n';
//		cerr << ">> ans: " << f[1][i].ans << '\n';
//		cerr << ">> pre: " << f[1][i].pre << '\n';
//		cerr << ">> suf: " << f[1][i].suf << '\n';
	}
	while (len[cnt] < R) {
		len[cnt + 1] = len[cnt] * d, cnt++;
		for (int i = 0; i < m; i++) {
			Data& F = f[cnt][i];
			F.pre = msk, F.suf = msk;
			for (int j = 0; j < d; j++) {
				F = F + f[cnt - 1][(i + gen[j]) % m];
			}
//			cerr << "> " << cnt << " " << i << '\n';
//			cerr << ">> ans: " << F.ans << '\n';
//			cerr << ">> pre: " << F.pre << '\n';
//			cerr << ">> suf: " << F.suf << '\n';
		}
	}
	ll _ = Solve(R);
	ll __ = Solve(L + n - 2);
//	cerr << _ << " " << __ << '\n';
	printf(Auto, _ - __);
}

int main() {
	init();
	solve();
	return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];
unordered_map<int64,vector<int64>> htable;

void prepare()
{
	htable.clear();
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}

int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int64>& wcnt=htable[w];
	if (SIZE(wcnt)==0)
	{
		wcnt=vector<int64>(MOD+1);
		vector<int> digits;
		for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
		int s=0;
		REP(i,SIZE(digits)) s+=gen[digits[i]];
		REP(i,SIZE(digits))
		{
			s-=gen[digits[i]];
			REP(d,digits[i])
			{
				int s0=s+gen[d];
				REP(w,MOD) wcnt[(s0+w)%MOD]+=cnt[i][w];
			}
		}
		REP(i,MOD) wcnt[MOD]+=wcnt[i];
	}
	if (mask==two(MOD)-1) return wcnt[MOD];
	int64 ret=0;
	REP(i,MOD) if (contain(mask,i)) ret+=wcnt[i];
	assert(ret<=w+1);
	return ret;
}

int64 solve(vector<int64> a,int64 w)
{
	if (w<0) return 0;
	if (SIZE(a)==1) return calc(w,a[0]);
	vector<int64> b;
	int64 ret=0;
	REP(md,m) if (md<=w)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			for (;at>=SIZE(b);b.push_back(two(MOD)-1));
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok) ret+=solve(b,(w-md)/m);
	}
	assert(ret<=w+1);
	return ret;
}
int64 solve(int64 w)
{
	if (w<0) return 0;
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
#ifdef _MSC_VER
		if (n>10)
			REP(i,n) a[i]=MOD-1;//()%MOD;
		else
			REP(i,n) cin>>a[i];
#else
		REP(i,n) cin>>a[i];
#endif
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(r-n+1)-solve(l-1);
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef int sign;
typedef long long ll;
#define For(i,a,b) for(register sign i=(sign)(a);i<=(sign)(b);++i)
#define Fordown(i,a,b) for(register sign i=(sign)(a);i>=(sign)(b);--i)
const int N=3e4+5,M=60+5;
template<typename T>bool cmax(T &a,T b){return (a<b)?a=b,1:0;}
template<typename T>bool cmin(T &a,T b){return (a>b)?a=b,1:0;}
template<typename T>T read()
{
	T ans=0,f=1;
	char ch=getchar();
	while(!isdigit(ch)&&ch!='-')ch=getchar();
	if(ch=='-')f=-1,ch=getchar();
	while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch-'0'),ch=getchar();
	return ans*f;
}
template<typename T>void write(T x,char y)
{
	if(x==0)
	{
		putchar('0'),putchar(y);
		return;
	}
	if(x<0)
	{
		putchar('-');
		x=-x;
	}
	static char wr[20];
	int top=0;
	for(;x;x/=10)wr[++top]=x%10+'0';
	while(top)putchar(wr[top--]);
	putchar(y);
}
void file()
{
#ifndef ONLINE_JUDGE
	freopen("H.in","r",stdin);
	freopen("H.out","w",stdout);
#endif
}
int d,m;
int gen[M];
int n,b[N];
ll l,r;
void input()
{
	d=read<int>(),m=read<int>();
	For(i,1,d)gen[i]=read<int>();
	n=read<int>();
	For(i,1,n)b[i]=read<int>();
	l=read<ll>(),r=read<ll>();
}
typedef bitset<N> BIT;
BIT all;
struct DP
{
	ll ans,len;
	BIT pre,suf;
	DP operator + (const DP s)const
	{
		if(!len)return s;
		DP h;
		h.ans=ans+s.ans;
		h.len=len+s.len;
		h.pre=pre;
		h.suf=s.suf;
		if(len<n-1)h.pre&=(s.pre>>len)|(all<<(n-len-1));
		if(s.len<n-1)h.suf&=(suf<<s.len)|(all>>(n-s.len-1));
		if(len+s.len>=n)
		{
			BIT res=suf&s.pre;
			if(len<n-1)res&=(all>>(n-len-1));
			if(s.len<n-1)res&=(all<<(n-s.len-1));
			h.ans+=res.count();
		}
		return h;
	}
}dp[M][M];
ll pw[70];
int top;
void init()
{
	pw[0]=1;
	ll res=1;
	For(i,1,n-1)all.set(i);
	for(;res<=r/d;top++,res=1ll*res*d);
	For(i,1,top)pw[i]=pw[i-1]*d;

	For(i,0,m-1)
	{
		dp[0][i].ans=0;
		dp[0][i].len=1;
		if(n==1)dp[0][i].ans=(i<=b[1]);
		else
		{
			For(j,1,n-1)
			{
				dp[0][i].pre[j]=(i<=b[j+1]);
				dp[0][i].suf[j]=(i<=b[j]);
			}
		}
	}
	For(i,1,top)
	{
		For(j,0,m-1)For(k,1,d)
		{
			dp[i][j]=dp[i][j]+dp[i-1][(j+gen[k])%m];
		}
	}
	//For(i,0,top)For(j,0,m-1)cout<<i<<' '<<j<<' '<<dp[i][j].ans<<' '<<dp[i][j].len<<endl;
}
ll solve(ll pos)
{
	DP res;
	res.ans=res.len=0;
	int add=0;
	Fordown(i,top,0)
	{
		For(j,1,d)
		{
			if(pos>=pw[i])
			{
				pos-=pw[i];
				res=res+dp[i][(add+gen[j])%m];
			}
			else
			{
				add=(add+gen[j])%m;
				break;
			}
		}
	}
	return res.ans;
}
void work()
{
	write(solve(r)-solve(l+n-2),'\n');
}
int main()
{
	file();
	input();
	init();
	work();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30005;
int d,m,n,lm,i,j,b[N],gen[25];
ll L,R;
struct atom{
	bitset<N>pr,sf,all;
	ll ans,l;
	void set(int v){
		if(v<=b[n])pr.set(n);if(v<=b[1])sf.set(1);
		for(int i=1;i<=n;++i)if(v<=b[i])all.set(i);
		ans=n==1 && v<=b[1];l=1;
	}
}a[65][65];
inline atom uni(const atom&a,const atom&b){
	static atom ret;
	ret.l=a.l+b.l;
	ret.pr=a.pr;if(a.l<n)ret.pr|=(a.all<<a.l&b.pr)>>a.l;
	ret.sf=b.sf;if(b.l<n)ret.sf|=(b.all>>1&a.sf)<<b.l;
	if(a.l+b.l<=n)ret.all=b.all>>a.l&a.all;else ret.all.reset();
	ret.ans=a.ans+b.ans+(a.sf<<1&b.pr).count();
	return ret;
}
inline ll calc(ll x){
	ll y=0,pr=0;
	static atom ans;bool fl=0;ans.ans=0;
	for(i=lm-1;i>=0;--i){
		for(j=0;y+a[i][(pr+gen[j])%m].l<=x;++j){
			if(!fl)ans=a[i][(pr+gen[j])%m],fl=1;else ans=uni(ans,a[i][(pr+gen[j])%m]);
			y+=a[i][(pr+gen[j])%m].l;
		}
		pr=(pr+gen[j])%m;
	}
	return ans.ans;
}
int main(){
	scanf("%d%d",&d,&m);for(i=0;i<d;++i)scanf("%d",gen+i);
	scanf("%d",&n);for(i=1;i<=n;++i)scanf("%d",b+i);scanf("%lld%lld",&L,&R);
	for(i=0;i<m;++i)a[0][i].set(i);
	for(lm=1;a[lm-1][0].l<=R/d;++lm)for(i=0;i<m;++i){
		a[lm][i]=a[lm-1][(i+gen[0])%m];
		for(j=1;j<d;++j)a[lm][i]=uni(a[lm][i],a[lm-1][(i+gen[j])%m]);
	}
	printf("%lld\n",calc(R)-calc(L+n-2));
	return 0;
}

//by yjz
#include<bits/stdc++.h>
using namespace std;
#define FF first
#define SS second
#define PB push_back
#define MP make_pair
#define foreach(it,s) for(__typeof((s).begin()) it=(s).begin();it!=(s).end();it++)
#ifndef LOCAL
#define cerr if(0)cout
#endif
typedef long long ll;
const int mod=1e9+7;
//My i/o stream
struct fastio
{
	char s[100000];
	int it, len;
	fastio() {it=len=0;}
	inline char get()
	{
		if (it<len) return s[it++]; it=0;
		len=fread(s, 1, 100000, stdin);
		if (len==0) return EOF; else return s[it++];
	}
	bool notend()
	{
		char c=get();
		while (c==' '||c=='\n') c=get();
		if (it>0) it--;
		return c!=EOF;
	}
}_buff;
#define geti(x) x=getnum()
#define getii(x,y) geti(x),geti(y)
#define getiii(x,y,z) getii(x,y),geti(z)
#define puti(x) putnum(x),putchar(' ')
#define putii(x,y) puti(x),puti(y)
#define putiii(x,y,z) putii(x,y),puti(z)
#define putsi(x) putnum(x),putchar('\n')
#define putsii(x,y) puti(x),putsi(y)
#define putsiii(x,y,z) putii(x,y),putsi(z)
inline ll getnum()
{
	ll r=0; bool ng=0; char c; c=_buff.get();
	while (c!='-'&&(c<'0'||c>'9')) c=_buff.get();
	if (c=='-') ng=1, c=_buff.get();
	while (c>='0'&&c<='9') r=r*10+c-'0', c=_buff.get();
	return ng?-r:r;
}
template <class T> inline void putnum(T x)
{
	if (x<0) putchar('-'), x=-x;
	register short a[20]={}, sz=0;
	while (x) a[sz++]=x%10, x/=10;
	if(sz==0) putchar('0');
	for (int i=sz-1; i>=0; i--) putchar('0'+a[i]);
}
inline char getreal() {char c=_buff.get(); while (c<=32) c=_buff.get(); return c;}
ll qpow(ll x, ll k) {return k==0? 1: 1ll*qpow(1ll*x*x%mod,k>>1)*(k&1?x:1)%mod;}
const int maxn = 30011;
bitset<maxn> all1;
int n, m, b[maxn];
struct data
{
	bitset<maxn> pf[61], sf[61];
	int dlt;
	int gi(int x) const {return (x+dlt)%m;}
	ll len, ans[61];
	data shift(int d)
	{
		data ret = (*this);
		ret.dlt = (ret.dlt+d)%m;
		return ret;
	}
	void init1()
	{
		len = 1; dlt = 0;
		for (int i=0; i<m; i++)
		{
			pf[i].reset();
			for (int j=0; j<n; j++) pf[i][j] = b[j]>=i;
			sf[i].reset();
			sf[i][0] = 1;
			for (int j=0; j<n-1; j++) sf[i][j+1] = b[j]>=i;
			ans[i] = n==1&&b[0]>=i;
		}
	}
	void debug()
	{
		cerr<<"===debug==="<<endl;
		cerr<<"len = "<<len<<" dlt = "<<dlt<<" ans = "<<ans[0]<<endl;
		for (int t=0; t<m; t++)
		{
			for (int i=0; i<n; i++) cerr<<pf[t][i];
			cerr<<",";
		} cerr<<endl;
		for (int t=0; t<m; t++)
		{
			for (int i=0; i<n; i++) cerr<<sf[t][i];
			cerr<<",";
		} cerr<<endl;
	}
};
data merge(const data &l, const data &r)
{
	data ret;
	ret.len=l.len+r.len;
	ret.dlt=0;
	for (int i=0; i<m; i++)
	{
		ret.pf[i] = l.pf[l.gi(i)];
		if (l.len<n) ret.pf[i] &= r.pf[r.gi(i)]>>l.len|all1<<(n-l.len);
		ret.sf[i] = r.sf[r.gi(i)];
		if (r.len<n) ret.sf[i] &= l.sf[l.gi(i)]<<r.len|all1>>(maxn-r.len);
		ret.ans[i] = l.ans[l.gi(i)]+r.ans[r.gi(i)];
		int tmp = min(l.len, (ll)n-1);
		int tmpl = max(1ll, n-r.len);
		if (tmp>=tmpl)
		{
			ret.ans[i] += (((l.sf[l.gi(i)]&(r.pf[r.gi(i)]))>>tmpl)<<(maxn-tmp+tmpl-1)).count();
		}
	}
	return ret;
}
int K;
data A[66];
int d, gen[66];
data solve(ll N)
{
	assert(N>0);
	for (int i=K; i>=0; i--)
	{
		if (N==A[i].len) return A[i];
		if (N>A[i].len)
		{
			data ret = A[i];
			for (int j=1; j<d; j++)
			{
				if (N>A[i].len*(j+1)) ret = merge(ret, A[i].shift(gen[j]));
				else
				{
					ret = merge(ret, solve(N-A[i].len*j).shift(gen[j]));
					return ret;
				}
			}
			assert(false);
		}
	}
}
ll calc(ll N)
{
	if (N<=0) return 0;
	data cur = solve(N);
//	cur.debug();
	return cur.ans[cur.gi(0)];
}
int main()
{
	all1.set();
	getii(d, m);
	for (int i=0; i<d; i++) geti(gen[i]);
	geti(n);
	for (int i=0; i<n; i++) geti(b[i]);
	A[0].init1();
	while (true)
	{
		K++;
		A[K] = A[K-1];
		bool exceed = 0;
		for (int i=1; i<d; i++)
		{
			A[K] = merge(A[K], A[K-1].shift(gen[i]));
			if (A[K].len>2e18)
			{
				exceed = 1;
				break;
			}
		}
		if (exceed)
		{
			K--;
			break;
		}
	}
	ll l, r;
	getii(l, r);
	cout<<calc(r)-calc(l+n-2)<<endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
using ll=long long;
inline ll read()
{
	ll x=0,f=1;char ch=getchar();
	while(!isdigit(ch))
	{
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(isdigit(ch))
	{
		x=(x<<1)+(x<<3)+ch-'0';
		ch=getchar();
	}
	return x*f;
}
const ll M=1e2+10,N=3e4+10;
ll len[M],gen[M],b[N],d,n,m,tot,L,R;
bitset<N>all;
struct info{
	ll ans,len;
	bitset<N>pre,suf;
	inline info operator+(const info&rhs)
	{
		info c;
		c.ans=ans+rhs.ans;
		c.len=len+rhs.len;
		c.pre=pre;
		c.suf=rhs.suf;
		if(len<n-1)c.pre&=(rhs.pre>>len)|(all<<n-1-len);
		if(rhs.len<n-1)c.suf&=(suf<<rhs.len)|(all>>n-1-rhs.len);
		if(len+rhs.len>=n)
		{
			bitset<N>res=suf&rhs.pre;
			if(len<n-1)res&=(all>>n-1-len);
			if(rhs.len<n-1)res&=(all<<n-1-rhs.len);
			c.ans+=res.count();
		}
		return c;
	}
	inline void operator+=(const info&rhs)
	{
		*this=!len?rhs:*this+rhs;
	}
}f[M][M];
inline ll query(ll x)
{
	info res;
	res.ans=res.len=0;
	ll da=0;
	for(ll i=tot;~i;--i)for(ll j=1;j<=d;++j)
	if(x>=len[i])
	{
		x-=len[i];
		res+=f[i][(da+gen[j])%m];
	}
	else
	{
		da=(da+gen[j])%m;
		break;
	}
	return res.ans;
}
int main()
{
//	freopen("1010.cpp","r",stdin);
//	freopen("1.out","w",stdout);
	d=read();
	m=read();
	for(ll i=1;i<=d;++i)gen[i]=read();
	n=read();
	for(ll i=1;i<=n;++i)b[i]=read();
	for(ll i=1;i<n;++i)all.set(i);
	len[0]=1;
	for(ll i=0;i<m;++i)
	{
		f[0][i].len=1;
		if(n==1)f[0][i].ans=i<=b[1];
		else for(ll j=1;j<n;++j)
		{
			f[0][i].pre[j]=i<=b[j+1];
			f[0][i].suf[j]=i<=b[j];
		}
	}
	L=read();
	R=read();
	while(len[tot]<=R/d)
	{
		tot++;
		len[tot]=len[tot-1]*d;
		for(ll i=0;i<m;++i)for(ll j=1;j<=d;++j)f[tot][i]+=f[tot-1][(i+gen[j])%m];
	}
	printf("%lld\n",query(R)-query(L+n-2));
	return 0;
}
/*
*/

//这个数位DP和普通的不一样
#include<bits/stdc++.h>
#define ll long long
#define BI bitset<N>

using namespace std;
const int N=3e4+10;
int n,m,d,tot,gen[30],b[N];
ll len[70],l,r;
BI full;

template<typename T>inline void read(T &x){
    x=0; bool f=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    if(f) x=-x;
}

struct node{
    ll ans,len;
    BI pre,suf;
    node operator + (const node &a){
        node b;
        b.ans=ans+a.ans;
        b.len=len+a.len;
        b.pre=pre; b.suf=a.suf;
        if(len<n-1) b.pre&=(a.pre>>len)|(full<<n-1-len);
        if(a.len<n-1) b.suf&=(suf<<a.len)|(full>>n-1-a.len);
        if(len+a.len>=n){
            BI res=suf&a.pre;
            if(len<n-1) res&=(full>>n-1-len);
            if(a.len<n-1) res&=(full<<n-1-a.len);
            b.ans+=res.count();
        }
        return b;
    }
    void operator += (const node &a){*this=!len?a:*this+a;}
}f[70][70];

ll query(ll x){
    node res;
    res.ans=res.len=0;
    int tmp=0;
    for(int i=tot;~i;--i)
        for(int j=1;j<=d;j++){
            if(x>=len[i]){
                x-=len[i];
                res+=f[i][(tmp+gen[j])%m];
            }
            else{
                tmp=(tmp+gen[j])%m;
                break;
            }
        }
    return res.ans;
}

int main(){
    read(d); read(m);
    for(int i=1;i<=d;i++) read(gen[i]);
    read(n);
    for(int i=1;i<=n;i++) read(b[i]);
    for(int i=1;i<n;i++) full.set(i);
    len[tot]=1;
    for(int i=0;i<m;i++){
        f[0][i].len=1;
        if(n==1) f[0][i].ans= i<=b[1];
        else{
            for(int j=1;j<=n-1;j++){
                f[0][i].pre[j]= i<=b[j+1];
                f[0][i].suf[j]= i<=b[j];
            }
        }
    }
    read(l); read(r);
    for(;len[tot]<=r/d;){
        ++tot; len[tot]=len[tot-1]*d;
        for(int i=0;i<m;i++)
            for(int j=1;j<=d;j++)
                f[tot][i]+=f[tot-1][(i+gen[j])%m];
    }
    printf("%lld\n",query(r)-query(l+n-2));
    return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

const int MAXBASE=20;
const int MAXB=30000;
const int MAXLG=100;
const int MAXMOD=60;

int base,MOD;
int gen[MAXBASE];
int nb;
int b[MAXB];
ll ql,qr;

int bfcalc(int na) {
	vector<int> a(na,0); REP(i,na) { int x=i; while(x!=0) a[i]+=gen[x%base],x/=base; a[i]%=MOD; }
	printf("a:"); REPSZ(i,a) printf(" %d",a[i]); puts("");
	int ret=0; REPE(i,SZ(a)-nb) { bool ok=true; REP(j,nb) if(b[j]<a[i+j]) { ok=false; break; } if(ok) ++ret; } return ret;
}

int d[MAXLG],nd;
ll dp[MAXLG+1][MAXMOD]; // with i freedigits, make j
ll dpsum[MAXLG+1][MAXMOD][MAXMOD]; // with i free digits and one less than k, make j

void dbuild(ll len) {
	nd=0; for(ll x=len;x!=0;x/=base) d[nd++]=x%base; reverse(d,d+nd);
}

ll calc(ll len,int want) {
	//printf("len:%lld want:%d, d:",len,want); REP(i,nd) printf(" %d",d[i]); puts("");
	int have=0; REP(i,nd) have+=gen[d[i]]; have%=MOD;
	ll ret=0;
	for(int i=nd-1;i>=0;--i) {
		have-=gen[d[i]]; if(have<0) have+=MOD;
		/*REP(j,d[i]) {
			int cur=have+gen[j]; if(cur>=MOD) cur-=MOD;
			int need=want-cur; if(need<0) need+=MOD;
			//printf("\tneed %d with %d free digits\n",need,nd-i-1);
			ret+=dp[nd-i-1][need];
		}*/
		int need=want-have; if(need<0) need+=MOD; ret+=dpsum[nd-i-1][need][d[i]];
	}
	//printf("=>%lld\n",ret);
	return ret;
}

map<ll,int> mem2;
vector<vector<ll>> memvals;

ll calcmask(ll len,ll mask) {
	if(!mem2.count(len)) {
		dbuild(len); vector<ll> vals(MOD); REP(i,MOD) vals[i]=calc(len,i);
		memvals.PB(vals); mem2[len]=SZ(memvals)-1;
	}
	int idx=mem2[len]; ll ret=0; REP(i,MOD) if((mask&(1LL<<i))!=0) ret+=memvals[idx][i]; return ret;
}

map<pair<ll,vector<ll>>,ll> mem;

ll rec(ll len,vector<ll> mask,int dep=0) {
	//if(dep!=0&&dep<=2) { REP(rep,dep) printf("  "); printf("len=%lld mask:",len); REPSZ(i,mask) { printf(" ["); int last=-2; REP(j,MOD) if(mask[i]&(1LL<<j)) { if(last>=0&&j!=last+1) { printf("..%d",last); last=-1; } if(last==-1) printf(","); if(last<0||j!=last+1) printf("%d",j); last=j; } if(last>=0) printf("..%d",last); printf("]"); } puts(""); }
	if(SZ(mask)>len) return 0;
	assert(SZ(mask)>0);
	//if(len==1) return SZ(mask)==1&&((mask[0]&1)!=0)?1:0;
	if(SZ(mask)==1) return calcmask(len,mask[0]);
	//if(SZ(mask)==2) { dbuild(len); ll ret=0; REP(i,MOD) if((mask[0]&(1LL<<i))!=0) REP(j,MOD) if((mask[1]&(1LL<<j))!=0) ret+=calc(len,i,j); return ret; }
	//if(len>2) { REP(rep,dep) printf("  "); printf("len=%lld SZ(mask)=%d\n",len,SZ(mask)); }
	ll ret=0;
	//pair<ll,vector<ll>> key=MP(len,mask); if(mem.count(key)) return mem[key];
	REP(offset,base) if(offset+SZ(mask)<=len) {
		vector<ll> nmask; bool ok=true;
		REPSZ(i,mask) {
			// l[i]<=a[x*base+offset+i]<=r[i] -> l[i]<=gen[(offset+i)%base]+a[x+(offset+i)/base] mod MOD<=r[i] -> l[i]-gen[(offset+i)%base]+x*MOD<=a[x+(offset+i)/base]<=r[i]-gen[(offset+i)%base]+y*MOD
			// nl[(offset+i)/base]>=l[i]-gen[(offset+i)%base]+x*MOD and nr[(offset+i)/base]<=r[i]-gen[(offset+i)%base]+y*MOD
			int idx=(offset+i)/base,delta=gen[(offset+i)%base];
			ll cmask=(mask[i]>>delta)|((mask[i]&((1LL<<delta)-1))<<(MOD-delta));
			//printf("offset=%d i=%d idx=%d delta=%d omask=%lld cmask=%lld\n",offset,i,idx,delta,mask[i],cmask);
			if(idx>=SZ(nmask)) nmask.PB(cmask); else { nmask[idx]&=cmask; if(nmask[idx]==0) { ok=false; break; } }
		}
		if(!ok) continue;
		//REP(rep,dep) printf("  "); printf("%d:",offset); REPSZ(i,nmask) { printf(" ["); bool fst=true; REP(j,MOD) if(nmask[i]&(1LL<<j)) { if(fst) fst=false; else printf(","); printf("%d",j); } printf("]"); } puts("");
		// x*base+offset+SZ(mask)<=len
		// x+SZ(nmask)<=(len-SZ(mask)-offset)/base+SZ(nmask)
		ll nlen=(len-SZ(mask)-offset)/base+SZ(nmask);
		if(nlen>=len) { REP(rep,dep) printf("  "); printf("len does not decrease (len=%lld nlen=%lld SZ(mask)=%d SZ(nmask)=%d offset\n",len,nlen,SZ(mask),SZ(nmask),offset); continue; }
		ret+=rec(nlen,nmask,dep+1);
	}
	//mem[key]=ret;
	return ret;
}

ll calc(ll na) {
	//int want=na<1000?bfcalc(na):-1;
	vector<ll> smask(nb); REP(i,nb) smask[i]=(2LL<<b[i])-1;
	ll have=rec(na,smask);
	//if(want!=-1&&want!=have) { printf("err: have=%lld want=%d\n",have,want); }
	return have;
}

ll solve() {
	mem.clear(); mem2.clear(); memvals.clear();
	REP(j,MOD) dp[0][j]=j==0?1:0;
	FORE(i,1,MAXLG) REP(j,MOD) { dp[i][j]=0; REP(k,base) dp[i][j]+=dp[i-1][(j+MOD-gen[k])%MOD]; }
	REPE(i,MAXLG) REP(j,MOD) { dpsum[i][j][0]=0; REP(k,base) dpsum[i][j][k+1]=dpsum[i][j][k]+dp[i][(j+MOD-gen[k])%MOD]; }
	ll ret=calc(qr+1)-calc(ql+nb-1);
	return ret;
}

void run() {
	scanf("%d%d",&base,&MOD);
	REP(i,base) scanf("%d",&gen[i]);
	scanf("%d",&nb);
	REP(i,nb) scanf("%d",&b[i]);
	scanf("%lld%lld",&ql,&qr),--ql,--qr;
	printf("%lld\n",solve());
}

void stress() {
	REP(rep,1000) {
		base=20; //rand()%(20-2+1)+2;
		MOD=60; //rand()%(60-2+1)+2;
		gen[0]=0; FOR(i,1,base) gen[i]=rand()%MOD;
		nb=MAXB; REP(i,nb) b[i]=MOD-1; //rand()%MOD;
		REP(i,10) { int idx=rand()%nb; --b[idx]; if(b[idx]<0) b[idx]+=MOD; }
		ql=rand()%1000*1000000000000000LL+rand()%1000*1000000000000LL+rand()%1000*1000000000LL+rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		qr=rand()%1000*1000000000000000LL+rand()%1000*1000000000000LL+rand()%1000*1000000000LL+rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		//ql=rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		//qr=rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		if(ql>qr) swap(ql,qr);
		printf("base=%d MOD=%d ql=%lld qr=%lld\n",base,MOD,ql,qr);
		ll have=solve();
		printf("=%lld\n",have);
	}
}

int main() {
	run();
	//stress();
	return 0;
}

//这个数位DP和普通的不一样
#include<bits/stdc++.h>
#define ll long long
#define BI bitset<N>

using namespace std;
const int N=3e4+10;
int n,m,d,tot,gen[30],b[N];
ll len[70],l,r;
BI full;

template<typename T>inline void read(T &x){
    x=0; bool f=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    if(f) x=-x;
}

struct node{
    ll ans,len;
    BI pre,suf;
    node operator + (const node &a){
        node b;
        b.ans=ans+a.ans;
        b.len=len+a.len;
        b.pre=pre; b.suf=a.suf;
        if(len<n-1) b.pre&=(a.pre>>len)|(full<<n-1-len);
        if(a.len<n-1) b.suf&=(suf<<a.len)|(full>>n-1-a.len);
        if(len+a.len>=n){
            BI res=suf&a.pre;
            if(len<n-1) res&=(full>>n-1-len);
            if(a.len<n-1) res&=(full<<n-1-a.len);
            b.ans+=res.count();
        }
        return b;
    }
    void operator +=(const node &a){*this=!len?a:*this+a;}
}f[70][70];

ll query(ll x){
    node res;
    res.ans=res.len=0;
    int tmp=0;
    for(int i=tot;~i;--i)
        for(int j=1;j<=d;j++){
            if(x>=len[i]){
                x-=len[i];
                res+=f[i][(tmp+gen[j])%m];
            }
            else{
                tmp=(tmp+gen[j])%m;
                break;
            }
        }
    return res.ans;
}

inline void init(){
    for(int i=1;i<n;i++) full.set(i);
    len[tot]=1;
    for(int i=0;i<m;i++){
        f[0][i].len=1;
        if(n==1) f[0][i].ans= i<=b[1];
        else{
            for(int j=1;j<=n-1;j++){
                f[0][i].pre[j]= i<=b[j+1];
                f[0][i].suf[j]= i<=b[j];
            }
        }
    }
    read(l); read(r);
    for(;len[tot]<=r/d;){
        ++tot; len[tot]=len[tot-1]*d;
        for(int i=0;i<m;i++)
            for(int j=1;j<=d;j++)
                f[tot][i]+=f[tot-1][(i+gen[j])%m];
    }
}

int main(){
    read(d); read(m);
    for(int i=1;i<=d;i++) read(gen[i]);
    read(n);
    for(int i=1;i<=n;i++) read(b[i]);
    init();
    printf("%lld\n",query(r)-query(l+n-2));
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int d, m;
vector<int> gen;
vector<int> b;

map<LL, vector<LL> > dp_saved;

LL cnt(LL S, vector<LL> masks){
	assert(masks.size() > 0);
	if(S == 0) return 0;
	if(masks.size() == 1){
		if(!dp_saved.count(S)){
			LL Suse = S;
			vector<LL> digits;
			while(Suse > 0){
				digits.push_back(Suse % d);
				Suse /= d;
			}
			reverse(digits.begin(), digits.end());
			vector<LL> dp(m, 0);

			LL cursum = 0;
			for(LL digit : digits){
				vector<LL> newdp(m, 0);
				for(int i = 0; i < m; i++){
					for(int j = 0; j < d; j++){
						newdp[(i + gen[j]) % m] += dp[i];
					}
				}
				for(int j = 0; j < digit; j++){
					newdp[(cursum + gen[j]) % m] ++;
				}
				dp = newdp;
				cursum += gen[digit];
			}
			dp_saved[S] = dp;
		}

		vector<LL> dp = dp_saved[S];

		LL ret = 0;
		for(int i = 0; i < m; i++){
			if(masks[0] & (1LL << i)){
				ret += dp[i];
			}
		}
		return ret;
	} else {
		LL ret = 0;
		for(int xres = 0; xres < d; xres ++){
			LL len = masks.size();
			LL newlen = (len - 1 + xres) / d + 1;
			vector<LL> newmasks(newlen, (1LL << m) - 1);
			for(LL i = 0; i < len; i++){
				LL newidx = (i + xres) / d;
				LL diff = gen[(i + xres) % d];
				newmasks[newidx] &= (masks[i] >> diff) | (masks[i] << (m - diff));
			}
			LL newS = (S - xres + d - 1) / d;
			ret += cnt(newS, newmasks);
		}
		return ret;
	}
}

LL solve(LL maxs){
	// s in [0, maxs)
	vector<LL> masks;
	for(int r : b){
		LL mask = (1LL << m) - 1;
		for(int z = 0; z < m; z++){
			if(z > r){
				mask &= ~(1LL << z);
			}
		}
		masks.push_back(mask);
	}
	return cnt(maxs, masks);
}
int main(){
	cin >> d >> m;
	gen.resize(d);
	for(int i = 0; i < d; i++){
		cin >> gen[i];
	}
	int n;
	cin >> n;
	b.resize(n);
	for(int i = 0; i < n; i++){
		cin >> b[i];
	}
	LL l, r;
	cin >> l >> r;
	l--; r--;
	LL ans = solve(r-n+2) - solve(l);
	cout << ans << endl;
}

#include<bits/stdc++.h>
using namespace std;

using ll = long long;

const int MAXD = 25;
const int MAXM = 61;
int D, M;
int gen[MAXD];

map<ll, vector<ll>> mem;
vector<ll>& dfs2(ll H) {
	assert(H >= 0);
	if (mem.count(H)) {
		return mem[H];
	}
	auto& res = mem[H] = vector<ll>(size_t(M));
	if (H == 0) {
		res[0]++;
		return res;
	}
	for (int d = 0; d < D && d <= H; d++) {
		vector<ll>& o = dfs2((H-d) / D);
		for (int i = 0; i < M; i++) {
			res[(i+gen[d]) % M] += o[i];
		}
	}
	return res;
}

map<ll, vector<ll>> results;
// maximum starting point (inclusive)
void dfs(const vector<uint64_t> &B, ll H) {
	if (H < 0) {
		return;
	}

	assert(H >= 0);

	const int N = int(B.size());

	if (N == 1) {
		if (!results.count(H)) {
			results[H] = vector<ll>(M);
		}
		vector<ll>& v = results[H];
		for (int m = 0; m < M; m++) {
			v[m] += bool((B[0]) & (1ll << m));
		}
		return;
	}

	// the starting offset
	for (int d = 0; d < D && d <= H; d++) {
		ll nxtH = (H - d) / D;
		vector<uint64_t> nxtB(size_t((d + (N-1)) / D + 1), ((1ll << M)-1));

		for (int i = 0; i < N; i++) {
			uint64_t msk = B[i];
			int off = gen[(i+d) % D];
			assert(0 <= off && off < M);
			msk = (msk >> off) | (msk << (M - off));
			nxtB[(i + d) / D] &= msk;
		}

		dfs(nxtB, nxtH);
	}
}

int main() {
	ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0);
	cin >> D >> M;
	for (int i = 0; i < D; i++) {
		cin >> gen[i];
	}
	assert(gen[0] == 0);

	int N;
	cin >> N;

	vector<uint64_t> B(N);
	for (int i = 0; i < N; i++) {
		int b; cin >> b; b++;
		B[i] = (1ll << b) - 1;
	}
	ll L, R;
	cin >> L >> R;
	// 0-index the things
	L--; R--;

	// half-open interval
	R++;
	assert(R - L >= N);

	assert(R-N > L-1);

	dfs(B, L - 1);
	for (auto& it : results) {
		for (ll& v : it.second) {
			v = -v;
		}
	}
	dfs(B, R - N);

	ll res = 0;

	for (auto& it : results) {
		vector<ll>& v = dfs2(it.first);
		for (int i = 0; i < M; i++) {
			res += v[i] * it.second[i];
		}
	}

	cout << res << '\n';

	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int MAX = 30000;

struct info {
  bitset<MAX> prefix;
  bitset<MAX> suffix;
  long long ans = 0;
  long long len = 0;
};

int main() {
#ifdef wxh010910
  freopen("input.txt", "r", stdin);
#endif
  ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; ++i) {
    cin >> gen[i];
  }
  int n;
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; ++i) {
    cin >> b[i];
  }
  long long l, r;
  cin >> l >> r;
  bitset<MAX> one;
  for (int i = 0; i < n - 1; ++i) {
    one[i] = 1;
  }
  auto merge = [&](const info &l, const info &r) {
    info res;
    res.prefix = l.prefix;
    res.suffix = r.suffix;
    res.ans = l.ans + r.ans;
    res.len = l.len + r.len;
    if (l.len < n - 1) {
      res.prefix &= r.prefix >> l.len | one << n - 1 - l.len;
    }
    if (r.len < n - 1) {
      res.suffix &= l.suffix << r.len | one >> n - 1 - r.len;
    }
    if (l.len + r.len >= n) {
      bitset<MAX> b = l.suffix & r.prefix;
      if (l.len < n - 1) {
        b &= one >> n - 1 - l.len;
      }
      if (r.len < n - 1) {
        b &= one << n - 1 - r.len;
      }
      res.ans += b.count();
    }
    return res;
  };
  vector<vector<info>> dp(1, vector<info>(m));
  for (int i = 0; i < m; ++i) {
    dp[0][i].len = 1;
    if (n == 1) {
      dp[0][i].ans = b[0] >= i;
    } else {
      for (int j = 0; j < n - 1; ++j) {
        if (b[j + 1] >= i) {
          dp[0][i].prefix[j] = true;
        }
        if (b[j] >= i) {
          dp[0][i].suffix[j] = true;
        }
      }
    }
  }
  long long sz = 1;
  while (sz <= r / d) {
    int cur = dp.size();
    dp.push_back(dp.back());
    for (int i = 0; i < m; ++i) {
      for (int j = 1; j < d; ++j) {
        dp[cur][i] = merge(dp[cur][i], dp[cur - 1][(i + gen[j]) % m]);
      }
    }
    sz *= d;
  }
  auto solve = [&](long long k) {
    long long cur = sz;
    int diff = 0;
    info res;
    for (int i = dp.size() - 1; ~i; --i, cur /= d) {
      for (int j = 0; j < d; ++j) {
        if (k >= cur) {
          res = merge(res, dp[i][(diff + gen[j]) % m]);
          k -= cur;
        } else {
          diff = (diff + gen[j]) % m;
          break;
        }
      }
    }
    return res.ans;
  };
  cout << solve(r) - solve(l + n - 2) << "\n";
  return 0;
}

#define DEBUG 0

#include <bits/stdc++.h>
using namespace std;

#if DEBUG
// basic debugging macros
int __i__,__j__;
#define printLine(l) for(__i__=0;__i__<l;__i__++){cout<<"-";}cout<<endl
#define printLine2(l,c) for(__i__=0;__i__<l;__i__++){cout<<c;}cout<<endl
#define printVar(n) cout<<#n<<": "<<n<<endl
#define printArr(a,l) cout<<#a<<": ";for(__i__=0;__i__<l;__i__++){cout<<a[__i__]<<" ";}cout<<endl
#define print2dArr(a,r,c) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<a[__i__][__j__]<<" ";}cout<<endl;}
#define print2dArr2(a,r,c,l) cout<<#a<<":\n";for(__i__=0;__i__<r;__i__++){for(__j__=0;__j__<c;__j__++){cout<<setw(l)<<setfill(' ')<<a[__i__][__j__]<<" ";}cout<<endl;}

// advanced debugging class
// debug 1,2,'A',"test";
class _Debug {
    public:
        template<typename T>
        _Debug& operator,(T val) {
            cout << val << endl;
            return *this;
        }
};
#define debug _Debug(),
#else
#define printLine(l)
#define printLine2(l,c)
#define printVar(n)
#define printArr(a,l)
#define print2dArr(a,r,c)
#define print2dArr2(a,r,c,l)
#define debug
#endif

// define
#define MAX_VAL 999999999
#define MAX_VAL_2 999999999999999999LL
#define EPS 1e-6
#define mp make_pair
#define pb push_back

// typedef
typedef unsigned int UI;
typedef long long int LLI;
typedef unsigned long long int ULLI;
typedef unsigned short int US;
typedef pair<int,int> pii;
typedef pair<LLI,LLI> plli;
typedef vector<int> vi;
typedef vector<LLI> vlli;
typedef vector<pii> vpii;
typedef vector<plli> vplli;

// ---------- END OF TEMPLATE ----------

int d,m;
int gen[20];
vlli B;
LLI dp[100][60];
LLI shift(LLI b,int x) {
    return (b >> x) | ((b & ((1LL << x)-1)) << (m-x));
}
map<LLI,int> M;
int num = 0;
LLI ans[100][60];
int xx[100][60];
LLI solve(vlli v,LLI r,int s) {
    if (r == 0) return 0;
    else if (v.size() == 1) {
        int i = 0;
        if (r == 1) return (v[0] & 1) ? 1:0;
        if (!M.count(r)) {
            int j,k,c = 0,digits[100];
            LLI x = r-1;
            while (x > 0) digits[i++] = x % d,x /= d;
            for (i--; i >= 0; i--) {
                for (j = 0; j < digits[i]; j++) {
                    for (k = 0; k < m; k++) ans[num][k] += dp[i][(((k-c-gen[j]) % m)+m) % m];
                }
                if (i == 0) {
                    for (k = 0; k < m; k++) ans[num][k] += dp[i][(((k-c-gen[j]) % m)+m) % m];
                }
                c += gen[j],c %= m;
            }
            M[r] = num++;
        }
        int p = M[r];
        for (i = 0; i < m; i++) {
            if (v[0] & (1LL << i)) xx[p][i] += s;
        }
        return 0;
    }

    int i,j;
    LLI ans = 0;
    for (i = 0; i < v.size(); i++) {
        if (v[i] == 0) return 0;
    }
    for (i = 0; i < d; i++) {
        vlli v2((i+v.size()-1)/d+1,(1LL << m)-1);
        for (j = 0; j < v.size(); j++) v2[(j+i)/d] &= shift(v[j],gen[(i+j) % d]);
        ans += solve(v2,(r-i+d-1)/d,s);
    }
    return ans;
}
int main() {
    int i;
    int n;
    LLI l,r;
    scanf("%d %d",&d,&m);
    for (i = 0; i < d; i++) scanf("%d",&gen[i]);
    scanf("%d",&n),B.resize(n);
    for (i = 0; i < n; i++) scanf("%I64d",&B[i]),B[i] = (1LL << (B[i]+1))-1;
    scanf("%I64d %I64d",&l,&r);

    int j,k;
    dp[0][0] = 1;
    for (i = 1; i < 100; i++) {
        if (pow(d,i) > 3e18) break;
        for (j = 0; j < m; j++) {
            for (k = 0; k < d; k++) dp[i][j] += dp[i-1][(j-gen[k]+m) % m];
        }
    }
    LLI sum = solve(B,r-n+1,1)-solve(B,l-1,-1);
    for (i = 0; i < num; i++) {
        for (j = 0; j < m; j++) sum += xx[i][j]*ans[i][j];
    }
    printf("%I64d\n",sum);

    return 0;
}

#include<bits/stdc++.h>
using namespace std;

int D , M , N , G[60] , B[30003] , pos; unsigned long long pw[64] , L , R;
struct data{
	bitset < 30003 > pre , suf; long long cnt , len;
	void create(int val){
		len = 1; cnt = 0;
		if(N == 1) cnt = val <= B[0];
		else{for(int i = 0 ; i < N ; ++i) pre[i] = B[i] >= val; suf = pre;}
	}
	friend data operator +(data &p , data q){
		data x; x.len = p.len + q.len; int d1 = max(0ll , 30003 - q.len) , d2 = max(0ll , N - p.len);
		x.suf = (q.suf << d1 >> d1) | ((q.suf >> q.len & p.suf) << q.len);
		x.pre = (p.pre >> d2 << d2) | ((p.pre << p.len & q.pre) >> p.len);
		d1 = max(0ll , 30003 - p.len); d2 = max(0ll , N - q.len);
		x.cnt = p.cnt + q.cnt + ((p.suf << d1 >> d1) << 1 & (q.pre >> d2 << d2)).count();
		return x;
	}
}now[64][60];

void init(){
	pw[0] = 1; for(pos = 1 ; pw[pos - 1] < 1e18 ; ++pos) pw[pos] = pw[pos - 1] * D;
	for(int i = 0 ; i < M ; ++i) now[0][i].create(i);
	for(int i = 1 ; i < pos ; ++i)
		for(int j = 0 ; j < M ; ++j){
			now[i][j] = now[i - 1][j];
			for(int k = 1 ; k < D ; ++k)
				now[i][j] = now[i][j] + now[i - 1][(j + G[k]) % M];
		}
}

data solve(int bit , long long val , int delt){
	if(val < pw[bit]) return solve(bit - 1 , val , delt);
	data cur = now[bit][delt]; val -= pw[bit];
	for(int i = 1 ; val && i < D ; ++i)
		if(val < pw[bit]){cur = cur + solve(bit - 1 , val , (delt + G[i]) % M); val = 0;}
		else{cur = cur + now[bit][(delt + G[i]) % M]; val -= pw[bit];}
	return cur;
}

int main(){
	cin >> D >> M; for(int i = 0 ; i < D ; ++i) cin >> G[i];
	cin >> N; for(int i = 0 ; i < N ; ++i) cin >> B[i];
	cin >> L >> R; init();
	cout << solve(pos - 1 , R , 0).cnt - (L == 1 ? 0 : solve(pos - 1 , L + N - 2 , 0).cnt) << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long s64;
#define rep(i,l,r)for(int i=l;i<=r;++i)
const int N=30000+2;
bitset<N>get(int l,int r)
{
bitset<N>all1;
if(l>r)return all1;
all1.set();
return(all1>>(N-1-r))^(all1>>(N-1-(l-1)));
}
int n,b[N];
struct Data
{
s64 len,ans;
bitset<N>pre,suf;
};
Data init(int v)
{
Data x;
x.len=1;x.ans=(n==1)&&(b[n]>=v);
rep(i,1,n)x.pre[i]=(b[n-i+1]>=v);
rep(i,1,n)x.suf[i]=(b[n-i]>=v);
return x;
}
Data operator+(const Data&l,const Data&r)
{
Data ans;
ans.len=l.len+r.len;
ans.ans=l.ans+r.ans+(l.suf&r.pre&get(max(1LL,n-l.len),min(r.len,n-1LL))).count();
if(l.len>=n)ans.pre=l.pre;
else ans.pre=l.pre&(get(1,l.len)|(r.pre<<l.len));
if(r.len>=n)ans.suf=r.suf;
else ans.suf=r.suf&(get(n-r.len,n)|(l.suf>>r.len));
return ans;
}
const int D=20+2,M=60+2,L=60+2;
int d,m,gen[D];
Data dp[L][M];

s64 F(s64 r)
{
Data ans;
ans.len=ans.ans=0;
ans.pre.set();ans.suf.set();
int v0=0;
while(r)
{
int i=0;
while(dp[i][0].len<=r/d)++i;
int j=0;
while(r>=dp[i][0].len)
{
r-=dp[i][0].len;
ans=ans+dp[i][(v0+gen[j])%m];
++j;
}
(v0+=gen[j])%=m;
}
return ans.ans;
}

int main()
{
#ifdef kcz
freopen("1.in","r",stdin);
#endif
cin>>d>>m;
rep(i,0,d-1)scanf("%d",gen+i);
cin>>n;
rep(i,1,n)scanf("%d",b+i);
s64 l,r;
cin>>l>>r;

rep(v,0,m-1)dp[0][v]=init(v);
int i=0;
while(dp[i][0].len<=r/d)
{
++i;
rep(v,0,m-1)
{
dp[i][v]=dp[i-1][v];
rep(j,1,d-1)dp[i][v]=dp[i][v]+dp[i-1][(v+gen[j])%m];
}
}

cout<<F(r)-F(l+n-2);
}

#include<bits/stdc++.h>
using namespace std;
#define REP(i,st,ed) for(register int i=st,i##end=ed;i<=i##end;++i)
#define DREP(i,st,ed) for(register int i=st,i##end=ed;i>=i##end;--i)
typedef long long ll;
template<typename T>inline bool chkmin(T &x,T y){return (y<x)?(x=y,1):0;}
template<typename T>inline bool chkmax(T &x,T y){return (y>x)?(x=y,1):0;}
inline int read(){
	int x;
	char c;
	int f=1;
	while((c=getchar())!='-' && (c>'9' || c<'0'));
	if(c=='-') f=-1,c=getchar();
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1)+(x<<3)+(c^'0');
	return x*f;
}
inline ll readll(){
	ll x;
	char c;
	int f=1;
	while((c=getchar())!='-' && (c>'9' || c<'0'));
	if(c=='-') f=-1,c=getchar();
	x=c^'0';
	while((c=getchar())>='0' && c<='9') x=(x<<1ll)+(x<<3ll)+(c^'0');
	return x*f;
}
const int maxn=3e4+10;
int M,d,m,n,gen[21],b[maxn];
ll t;
bitset<maxn> All;
struct DP{
	bitset<maxn> pre,suf;
	ll ans,len;
	void merge(const DP &A){
		if(len==0){
			pre=A.pre,suf=A.suf,ans=A.ans,len=A.len;
			return;
		}
		if(len+A.len>=n){
			bitset<maxn> res=(suf&A.pre);
			if(len<n-1) res&=(All>>(n-1-len));
			if(A.len<n-1) res&=(All<<(n-1-A.len));
			ans+=res.count();
		}
		if(len<n-1) pre&=(A.pre>>len)|(All<<(n-len-1));
		if(A.len<n-1) suf=A.suf&((suf<<A.len)|(All>>(n-A.len-1)));
		else suf=A.suf;
		len+=A.len,ans+=A.ans;
	}
}f[60][60];
ll solve(ll x){
	if(x<n) return 0;
	DP res;
	res.len=0;
	int Nw=0;
	ll Pw=t;
	for(int i=M;i>=0;--i,Pw/=d){
		int tot=0;
		while(x>=Pw) x-=Pw,res.merge(f[i][(Nw+gen[tot++])%m]);
		Nw=(Nw+gen[tot])%m;
	}
	return res.ans;
}
int main(){
#ifndef ONLINE_JUDGE
	freopen("h.in","r",stdin);
	freopen("h.out","w",stdout);
#endif
	d=read(),m=read();
	REP(i,0,d-1) gen[i]=read();
	n=read();
	REP(i,1,n-1) All[i]=1;
	REP(i,1,n) b[i]=read();
	ll l=readll(),r=readll();
	for(t=1;t<=r/d;t*=d,++M);
	REP(i,0,m-1){
		f[0][i].len=1,f[0][i].ans=(n==1 && i<=b[1]);
		REP(j,1,n-1){
			f[0][i].pre[j]=(i<=b[j+1]);
			f[0][i].suf[j]=(i<=b[j]);
		}
	}
	REP(i,1,M) REP(j,0,m-1) REP(k,0,d-1) f[i][j].merge(f[i-1][(j+gen[k])%m]);
	printf("%lld\n",solve(r)-solve(l+n-2));
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXD = 25;
const int MAXM = 61;
int D, M;
int gen[MAXD];

map<ll, vector<ll>> mem;
vector<ll>& dfs2(ll H) {
	assert(H >= 0);
	if (mem.count(H)) {
		return mem[H];
	}
	auto& res = mem[H] = vector<ll>(size_t(M));
	if (H == 0) {
		res[0]++;
		return res;
	}
	for (int d = 0; d < D && d <= H; d++) {
		vector<ll>& o = dfs2((H-d) / D);
		for (int i = 0; i < M; i++) {
			res[(i+gen[d]) % M] += o[i];
		}
	}
	return res;
}

map<ll, vector<ll>> results;
void dfs(const vector<uint64_t> &B, ll H) {
	if (H < 0)
		return;
	assert(H >= 0);
	const int N = int(B.size());
	if (N == 1) {
		if (!results.count(H)) {
			results[H] = vector<ll>(M);
		}
		vector<ll>& v = results[H];
		for (int m = 0; m < M; m++) {
			v[m] += bool((B[0]) & (1ll << m));
		}
		return;
	}
	for (int d = 0; d < D && d <= H; d++) {
		ll nxtH = (H - d) / D;
		vector<uint64_t> nxtB(size_t((d + (N-1)) / D + 1), ((1ll << M)-1));
		for (int i = 0; i < N; i++) {
			uint64_t msk = B[i];
			int off = gen[(i+d) % D];
			assert(0 <= off && off < M);
			msk = (msk >> off) | (msk << (M - off));
			nxtB[(i + d) / D] &= msk;
		}
		dfs(nxtB, nxtH);
	}
}

int main(void) {
	ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> D >> M;
	for (int i = 0; i < D; i++) {
		cin >> gen[i];
	}
	assert(gen[0] == 0);
	int N;
	cin >> N;
	vector<uint64_t> B(N);
	for (int i = 0; i < N; i++) {
		int b; cin >> b; b++;
		B[i] = (1ll << b) - 1;
	}
	ll L, R;
	cin >> L >> R;
	L--; R--;
	R++;
	assert(R - L >= N);
	assert(R-N > L-1);
	dfs(B, L - 1);
	for (auto& it : results) {
		for (ll& v : it.second) {
			v = -v;
		}
	}
	dfs(B, R - N);
	ll res = 0;
	for (auto& it : results) {
		vector<ll>& v = dfs2(it.first);
		for (int i = 0; i < M; i++) {
			res += v[i] * it.second[i];
		}
	}
	cout << res << '\n';
}

#include<bits/stdc++.h>
#define mkp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f,N=3e4+10,M=65;
int n,m,d,tot,gen[M],b[N];
ll ql,qr,len[M];
bitset<N>all,tmp;

ll read()
{
	ll ret=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=0;c=getchar();}
	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
	return f?ret:-ret;
}

struct data
{
	ll len,ans;
	bitset<N>pre,suf;
}f[M][M];
data operator +(const data&a,const data&b)
{
	if(!a.len) return b;
	data res;
	res.len=a.len+b.len;res.ans=a.ans+b.ans;
	res.pre=a.pre;res.suf=b.suf;
	if(a.len<=n-2) res.pre&=(b.pre>>a.len)|(all<<(n-a.len-1));
	if(b.len<=n-2) res.suf&=(a.suf<<b.len)|(all>>(n-b.len-1));
	if(a.len+b.len>=n)
	{
		tmp=a.suf&b.pre;
		if(a.len<=n-2) tmp&=all>>(n-a.len-1);
		if(b.len<=n-2) tmp&=all<<(n-b.len-1);
		res.ans+=tmp.count();
	}
	return res;
}
ll solve(ll x)
{
	data res;int delta=0;
	res.ans=res.len=0;
	res.pre.reset();res.suf.reset();
	for(int i=tot;~i;--i) for(int j=1;j<=d;++j)
	{
		if(x>=len[i]) x-=len[i],res=res+f[i][(delta+gen[j])%m];
		else {delta=(delta+gen[j])%m;break;}
	}
	return res.ans;
}
void init()
{
	d=read();m=read();
	for(int i=1;i<=d;++i) gen[i]=read();
	n=read();
	for(int i=1;i<=n;++i) b[i]=read();
	for(int i=1;i<n;++i) all.set(i);
	len[0]=1;
	for(int i=0;i<m;++i)
	{
		f[0][i].len=1;
		if(n==1) f[0][i].ans=i<=b[1];
		else
		{
			for(int j=1;j<n;++j)
			{
				f[0][i].pre[j]=i<=b[j+1];
				f[0][i].suf[j]=i<=b[j];
			}
		}
	}
}
void work()
{
	ql=read();qr=read();
	while(len[tot]<=qr/d)
	{
		++tot;len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j)
			f[tot][i]=f[tot][i]+f[tot-1][(i+gen[j])%m];
	}
	printf("%lld\n",solve(qr)-solve(ql+n-2));
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("H.in","r",stdin);
	freopen("H.out","w",stdout);
#endif
	init();work();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n,m,d;
bitset<30001> all;
struct ooxx{
	long long ans,len;
	bitset<30001> pre,nxt;
	ooxx operator + (const ooxx &emm) {
		if (!len) return emm;
		ooxx ret;
		ret.ans=ans+emm.ans,ret.len=len+emm.len;
		ret.pre=pre,ret.nxt=emm.nxt;
		if (len<n-1) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
		if (emm.len<n-1) ret.nxt&=((nxt<<emm.len)|(all>>(n-emm.len-1)));
		if (len+emm.len>=n){
			bitset<30001> res=nxt&emm.pre;
			if(len<n-1) res&=(all>>(n-1-len));
			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
			ret.ans+=res.count();
		}
		return ret;
	}
}dp[100][100];
int tot,a[100];
long long len[100];
inline long long query(long long x)
{
	ooxx ret;ret.ans=ret.len=0,ret.nxt.reset(),ret.pre.reset();
	long long now=0;
	for (int i=tot;i>=0;--i)
	{
		for (int j=1;j<=d;++j)
		{
			if (len[i]>x) {now+=a[j];now%=m;break;}
			else
			{
				ret=(ret+dp[i][(a[j]+now)%m]);
				x-=len[i];
			}
		}
	}
	return ret.ans;
}
int b[100000];
int main()
{
	scanf("%d%d",&d,&m);
	for (int i=1;i<=d;++i) scanf("%d",&a[i]);
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d",&b[i]);
	for (int i=1;i<n;++i) all.set(i);//[i]=1;
	for (int i=0;i<m;++i)
	{
		dp[0][i].len=1;
		if (n==1) dp[0][i].ans=(i<=b[1]);
		else
		{
			for (int j=1;j<n;++j)
			{
				dp[0][i].pre[j]=i<=b[j+1];
				dp[0][i].nxt[j]=i<=b[j];
			}
		}
	}
	len[0]=1;
	long long l,r;
	scanf("%lld%lld",&l,&r);
	for (;len[tot]<=r/d;){
		++tot,len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j) dp[tot][i]=(dp[tot][i]+dp[tot-1][(i+a[j])%m]);
	}
	printf("%lld\n",query(r)-query(l+n-2));
	return 0;
}

#include<bits/stdc++.h>
const int N = 3e4 + 1;
using namespace std;
typedef std::bitset<N> BI;
long long ri() {
	char c = getchar(); long long x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct ooxx{
	long long ans,len;
	bitset<30001> pre,nxt;
	ooxx operator + (const ooxx &emm) {
		if (!len) return emm;
		ooxx ret;
		ret.ans=ans+emm.ans;
		ret.len=len+emm.len;
		ret.pre=pre;ret.nxt=emm.nxt;
		if (len<n-1) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
		if (emm.len<n-1) ret.nxt&=((nxt<<emm.len)|(all>>(n-emm.len-1)));
		if (len+emm.len>=n){
			bitset<30001> res=nxt&emm.pre;
			if(len<n-1) res&=(all>>(n-1-len));
			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
			ret.ans+=res.count();
		}
		return ret;
	}
//	void operator += (const ooxx &b) {*this = !len ? b : *this + b;}
}f[100][100];
inline long long query(long long x)
{
	ooxx ret;ret.ans=ret.len=0,ret.nxt.reset(),ret.pre.reset();
	long long now=0;
	for (int i=tot;i>=0;--i)
	{
		for (int j=1;j<=d;++j)
		{
			if (len[i]>x) {now+=gen[j];now%=m;break;}
			else
			{
				ret=(ret+f[i][(gen[j]+now)%m]);
				x-=len[i];
			}
		}
	}
	return ret.ans;
}
int main() {
	d = ri(); m = ri();
	for(int i = 1;i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1;i <= n; ++i)
		b[i] = ri();
	for(int i = 1;i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0;i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1;j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[j + 1];
				f[0][i].nxt[j] = i <= b[j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(;len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0;i < m; ++i)
			for(int j = 1;j <= d; ++j)
				f[tot][i] = (f[tot][i]+f[tot - 1][(i + gen[j]) % m]);
//				f[tot][i]+= f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", query(R) - query(L + n - 2));
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

const int MAX = 30010;

struct State {
  bitset<MAX> left;
  bitset<MAX> right;
  long long len = 0;
  long long res = 0;
};

int n;
bitset<MAX> all;

State Unite(const State& a, const State& b) {
  State c;
  c.len = a.len + b.len;
  c.res = a.res + b.res;
  c.left = a.left;
  c.right = b.right;
  if (a.len < n - 1) {
    c.left &= (b.left >> a.len) | (all << (n - 1 - a.len));
  }
  if (b.len < n - 1) {
    c.right &= (a.right << b.len) | (all >> (n - 1 - b.len));
  }
  if (a.len + b.len >= n) {
    bitset<MAX> d = a.right & b.left;
    if (a.len < n - 1) {
      d &= (all >> (n - 1 - a.len));
    }
    if (b.len < n - 1) {
      d &= (all << (n - 1 - b.len));
    }
    c.res += d.count();
  }
  return c;
}

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; i++) {
    cin >> gen[i];
  }
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; i++) {
    cin >> b[i];
  }
  long long L, R;
  cin >> L >> R;
  for (int i = 1; i < n; i++) {
    all.set(i);
  }
  vector<vector<State>> states(1, vector<State>(m));
  for (int i = 0; i < m; i++) {
    states[0][i].len = 1;
    if (n == 1) {
      states[0][i].res = b[0] >= i;
    } else {
      for (int j = 1; j < n; j++) {
        if (b[j] >= i) {
          states[0][i].left.set(j);
        }
      }
      for (int j = 1; j < n; j++) {
        if (b[j - 1] >= i) {
          states[0][i].right.set(j);
        }
      }
    }
  }
  long long z = 1;
  while (z <= R / d) {
    int sz = (int) states.size();
    states.resize(sz + 1);
    states[sz].resize(m);
    for (int i = 0; i < m; i++) {
      State cur = states[sz - 1][i];
      for (int j = 1; j < d; j++) {
        cur = Unite(cur, states[sz - 1][(i + gen[j]) % m]);
      }
      states[sz][i] = cur;
    }
    z *= d;
  }
  auto calc = [&](long long up) -> long long {
    State res;
    int shift = 0;
    for (int i = (int) states.size() - 1; i >= 0; i--) {
      z = 1;
      for (int j = 0; j < i; j++) {
        z *= d;
      }
      for (int j = 0; j < d; j++) {
        if (up >= z) {
          res = Unite(res, states[i][(shift + gen[j]) % m]);
          up -= z;
        } else {
          shift = (shift + gen[j]) % m;
          break;
        }
      }
    }
    return res.res;
  };
  cout << calc(R) - calc(L + n - 2) << '\n';
  return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=(a.s[i]&b.p[i]);
	else
		c.ans+=(a.s&b.p).count();
	if (n-1-a.len>0){
		for (int i=1;i<=a.len;++i)
			c.p[i]=a.p[i];
		for (int i=a.len+1;i<n;++i)
			c.p[i]=a.p[i]&b.p[i-a.len];
	}
	else
		c.p=a.p;
	if (1+b.len<n){
		for (int i=1;i+b.len<n;++i)
			c.s[i]=b.s[i]&a.s[i+b.len];
		for (int i=n-b.len;i<n;++i)
			c.s[i]=b.s[i];
	}
	else
		c.s=b.s;
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
		c.ans+=(a.s[i]&b.p[i]);
	for (int i=1;i<n;++i)
		c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	for (int i=1;i<n;++i)
		c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

void DEBUG(vector<ll> a) {
    printf("{");
    for (ll x : a) printf("%lld ", x);
    printf("}\n");
}

int mod;

void DEBUG(ll mask) {
    printf("mask: ");
    for (int i = 0; i < mod; ++i)
        printf("%d", (mask >> i) & 1);
    printf("\n");
}

struct TorSum {
    int n, m;
    ll** a;
    ll** pref;

    TorSum() {};
    TorSum(ll** _a): n(mod), m(mod) {
        a = new ll*[n];
        for (int i = 0; i < n; ++i) {
            a[i] = new ll[m];
            for (int j = 0; j < m; ++j)
                a[i][j] = _a[i][j];
        }
        pref = new ll*[n + 1];
        for (int i = 0; i <= n; ++i) {
            pref[i] = new ll[m + 1];
            for (int x = 0; x < mod; ++x)
                pref[i][x] = 0;
            //memset(pref[i], 0, sizeof pref[i]);
        }

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll stupid(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        ll res = 0;
        for (int x = lx; ; x = (x + 1) % n) {
            for (int y = ly; ; y = (y + 1) % m) {
                res += a[x][y];
                if (y == ry) break;
            }
            if (x == rx) break;
        }
        return res;
    }
    ll get_sum_safe(int lx, int rx, int ly, int ry) {
        // lx <= rx && ly <= ry
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
    ll get_sum(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        /*
        if (lx <= rx && ly <= ry)
            return get_sum_safe(lx, rx + 1, ly, ry + 1);
        if (lx <= rx && ry < ly)
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry, ly + 1);
        if (rx < lx && ly <= ry) {
            ll res = get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            ll res_st = stupid(lx, rx, ly, ry);
            if (res != res_st) {
                printf("%d %d %d %d\n", lx, rx, ly, ry);
                for (int i = 0; i < n; ++i) {
                    for (int j = 0; j < m; ++j)
                        printf("%d ", a[i][j]);
                    printf("\n");
                }
                exit(0);
            }
        }
        */

        //return stupid(lx, rx, ly, ry);

        //*
        if (lx <= rx) {
            if (ly <= ry) {
                return get_sum_safe(lx, rx + 1, ly, ry + 1);
            }
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry + 1, ly);
        } else {
            if (ly <= ry) {
                return get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            }
            return get_sum_safe(0, n, 0, m) - get_sum_safe(0, n, ry + 1, ly) - get_sum_safe(rx + 1, lx, 0, m) + get_sum_safe(rx + 1, lx, ry + 1, ly);
        }
        //*/
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

int a[66];

vector<pii> split_segment(ll mask) {
    int n = mod;
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        a[i] = (mask >> i) & 1;
        cnt += a[i];
    }

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && !a[l]) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r]) ++r;
        res.push_back({l, r - 1});
        i = r;
    }
    if (res[0].first == 0 && res.back().second == n - 1) {
        int r = res[0].second;
        int l = res.back().first;
        res.erase(res.begin());
        res.erase(--res.end());
        res.push_back({l, r});
    }

    return res;
}

const int D = 22;
const int MOD = 66;
const int N = 30000;
const int LOG = 16;

using Zet = ll*;

int d;
int logn;
int gen[D];
vector<int> big_gen;
ll pwd[66];
ll jump[N][LOG];
pair<vector<pii>, vector<pii>> segments[N * D];

void add(Zet arr, Zet to_add, int shift) {
    for (int i = 0; i + shift < mod; ++i)
        arr[i] += to_add[i + shift];
    for (int i = mod - shift; i < mod; ++i)
        arr[i] += to_add[i + shift - mod];
}

Zet zeroes;
unordered_map<ll, Zet> cnt;

Zet get_cnt(ll r) {
    //printf("r = %lld\n", r);
    if (r <= 0)
        return zeroes;
    if (cnt.count(r))
        return cnt[r];

    //printf("dbl r = %lld\n", r);

    Zet res = new ll[mod];
    for (int x = 0; x < mod; ++x)
        res[x] = 0;
    int k = mlog(r, d);
    ll dk = mpow(d, k);

    if (dk == r)
        dk /= d;

    int i = 0;
    for (; r >= (i + 1) * dk; ++i)
        add(res, get_cnt(dk), (mod - gen[i]) % mod);
    add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

    cnt[r] = res;
    return res;
};

void inters(ll & mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    mask1 &= ((mask2 >> shift) | (shift_mask << (mod - shift)));
}

ll query(int l, int r, int pos) {
    ll res = (1LL << mod) - 1;
    while(l != r) {
        for (int i = logn; ; --i) {
            if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                inters(res, jump[pos][i], big_gen[l]);
                l += pwd[i];
                pos += pwd[i];
                break;
            }
        }
    }
    return res;
};

unordered_map<ll, TorSum> solver;

ll get_sum(ll R, int lx, int rx, int ly, int ry) {
    //printf("%lld %d %d %d %d\n", R, lx, rx, ly, ry);
    if (!solver.count(R)) {
        Zet* a = new Zet[mod];
        for (int i = 0; i < mod; ++i) {
            a[i] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                a[i][x] = 0;
        }
        for (int i = 0; pwd[i] - 1 <= R; ++i) {
            for (int digit = 0; digit < d - 1; ++digit) {
                //printf("%d %d\n", i, digit);
                if (R < (digit + 1) * pwd[i] - 1)
                    break;
                //printf("%lld\n", (R - (digit + 1) * pwd[i] + 1) / pwd[i + 1]);
                Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                //DEBUG(kek);
                for (int r = 0; r < mod; ++r)
                    a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
            }
        }
        /*
        for (int i = 0; i < mod; ++i) {
            for (int j = 0; j < mod; ++j)
                printf("%lld ", a[i][j]);
            printf("\n");
        }
        printf("\n");
        */
        solver[R] = TorSum(a);
    }
    //printf("res = %lld\n\n", solver[R].get_sum(lx, rx, ly, ry));
    return solver[R].get_sum(lx, rx, ly, ry);
};

ll solve(ll R) {
    ll res = 0;
    //printf("solve %lld:\n", R);
    for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        //printf("rem %d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
    }
    //printf("ans %lld\n\n", res);
    return res;
};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    //*
    scanf("%d %d", &d, &mod);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    logn = 1;
    for (int i = 0; i < d; ++i)
        big_gen.push_back(gen[i]);
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    /*
    for (int x : big_gen)
        printf("%d", x);
    printf("\n");
    */

    int pos = 0;
    pwd[pos] = 1;
    while(pwd[pos] < (ll)4e17) {
        ll x = d * pwd[pos];
        pwd[++pos] = x;
    }

    int start, end;
    double time;

    start = clock();

    for (int i = n - 1; i >= 0; --i) {
        jump[i][0] = (1LL << (a[i] + 1)) - 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            jump[i][k] = (1LL << mod) - 1;
            for (int ii = 0; ii < d; ++ii)
                inters(jump[i][k], jump[i + ii * pwd[k - 1]][k - 1], gen[ii]);
        }
        /*
        if (i == 0) {
            DEBUG(jump[0][0]);
            DEBUG(jump[1][0]);
            DEBUG(jump[0][1]);
        }
        */
        /*
        for (int ii = 0; ii < mod; ++ii)
            printf("%lld ", jump[i][0][ii]);
        printf("\n");
        */
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        ll draw = query(rem, rem + n, 0);
        //DEBUG(draw);
        /*
        printf("rem = %d\n", rem);
        for (int i = 0; i < mod; ++i)
            printf("%lld ", draw[i]);
        printf("\n");
        */
        segments[rem] = {split_segment(draw), {{0, mod - 1}}};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        ll draw1 = query(rem, pwd[logn], 0);
        ll draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        //rotate(draw2.begin(), draw2.begin() + gen[1], draw2.end());
        segments[rem] = {split_segment(draw1), split_segment(draw2)};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (int rem = 0; rem < pwd[logn]; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        printf("%d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                printf("%d %d %d %d\n", lx, rx, ly, ry);
        printf("\n");
    }
    printf("\n");
    */

    // init cnt
    //<-------------------------->
    zeroes = new ll[mod];
    for (int x = 0; x < mod; ++x)
        zeroes[x] = 0;
    //memset(zeroes, 0, sizeof zeroes);
    cnt[0] = zeroes;
    Zet ozero = new ll[mod];
    for (int x = 0; x < mod; ++x)
        ozero[x] = 0;
    ozero[0] = 1;
    cnt[1] = ozero;
    //<-------------------------->

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    printf("\n\n");
    */

    /*
    for (int x = 0; x <= 26; ++x)
        solve(x);
    */

    start = clock();

    //*
    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));
    //*/

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    */

    //*/

    /*
    vector<ll> a = {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1};
    vector<pii> seg = split_segment(a, 1);

    for (auto [l, r] : seg)
        printf("%d %d\n", l, r);
    */

}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=(a.s[i]&b.p[i]);
	else
		c.ans+=(a.s&b.p).count();
	static bitset<N+1> tmp;
	//c.p=a.p&b.p<<a.len;
	if (n-1-a.len>0){
		tmp=(a.p>>a.len&b.p)<<a.len;
		for (int i=1;i<=a.len;++i)
			tmp[i]=a.p[i];
		c.p=tmp;
	}
	else
		c.p=a.p;
	//c.s=b.s&a.s>>b.len;
	if (1+b.len<n){
		tmp=b.s&a.s>>b.len;
		for (int i=n-b.len;i<n;++i)
			tmp[i]=b.s[i];
		c.s=tmp;
	}
	else
		c.s=b.s;
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=(a.s[i]&b.p[i]);
	else
		c.ans+=(a.s&b.p).count();
	if (n-1-a.len>0)
		for (int i=1;i<n;++i)
			c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	else
		c.p=a.p;
	if (1+b.len<n)
		for (int i=1;i<n;++i)
			c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	else
		c.s=b.s;
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=(a.s[i]&b.p[i]);
	else
		c.ans+=(a.s&b.p).count();
	static bitset<N+1> tmp;
	//c.p=a.p&b.p<<a.len;
	if (n-1-a.len>0){
		tmp=a.p&b.p<<a.len;
		for (int i=1;i<=a.len;++i)
			tmp[i]=a.p[i];
		c.p=tmp;
	}
	else
		c.p=a.p;
	//c.s=b.s&a.s>>b.len;
	if (1+b.len<n){
		tmp=b.s&a.s>>b.len;
		for (int i=n-b.len;i<n;++i)
			tmp[i]=b.s[i];
		c.s=tmp;
	}
	else
		c.s=b.s;
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

#include <iostream>
#include <cstdio>

#include <bitset>
#include <vector>

#include <cassert>

using namespace std;

using ll = long long;
#define tl(X) static_cast<ll>(X)

const int MD = 22;
const int MM = 65;
const int MN = 3e4 + 100;
const ll INF = 1e18;

using vb = bitset<MN>;
vb F[MN];

int D, M, N;
int g[MD], b[MN];

int md(int x) {
	if(x >= M) x -= M;
	assert(x < M);
	return x;
}

struct DAT {
	vb p, s;
	ll l, c;
	DAT() {
		p.reset(), s.reset();
		l = c = 0LL;
	}
	DAT operator + (const DAT& o) const {
		DAT r;
		r.c = c+o.c, r.l = l+o.l;
		if(l + 1 < N) r.p = p&o.p>>l|p>>N-l-1<<N-l-1; else r.p = p;
		if(o.l + 1< N) r.s = o.s&s<<o.l|o.s&F[o.l]; else r.s = o.s;
		if(r.l >= N) {
			vb q = s&o.p;
			if(l < N) q &= F[l];
			if(o.l < N) q >>= N-o.l-1;
			r.c += q.count();
		}
		return r;
	}
};

DAT d[100][MM];

using vi = vector<int>;
#define pb push_back

ll solve(ll v) {
	if(v <= 0) return 0LL;
	vi x(0);
	for(;v;v/=D)
		x.pb(v%D);
	DAT c;
	for(int i = x.size() - 1, r = 0;i >= 0;i--) {
		for(int j = 0;j < x[i];j++)
			c = c + d[i][md(r+g[j])];
		r = md(r + g[x[i]]);
	}
	return c.c;
}

int main() {
	F[0].reset();
	for(int i = 0;i < MN - 1;i++) F[i+1] = F[i], F[i+1][i] = 1;

	scanf("%d%d", &D, &M);
	for(int i = 0;i < D;i++) scanf("%d", g + i);
	scanf("%d", &N);
	for(int i = 0;i < N;i++) scanf("%d", b + i);
	b[N] = -1;

	for(int i = 0;i < M;i++) {
		d[0][i].l = 1;
		if(N > 1)
			for(int j = 0;j < N-1;j++)
				d[0][i].s[j] = i <= b[j], d[0][i].p[j] = i <= b[j + 1];
		else
			d[0][i].c = i <= b[0];
	}

	ll x = 1;
	for(int i = 1;x <= INF/D;i++, x *= D)
		for(int j = 0;j < M;j++) {
			d[i][j] = d[i-1][j];
			for(int k = 1;k < D;k++) d[i][j] = d[i][j] + d[i-1][md(j+g[k])];
		}

	ll A, B;
	scanf("%lld%lld", &A, &B);
	printf("%lld\n", solve(B) - solve(A+N-2));

	return 0;
}

#include <bits/stdc++.h>
typedef  long long ll;
using namespace std;
#define INF 2147483647
#define infL (1LL<<60)
#define inf (1<<30)
#define inf9 (1000000000)
#define MOD  1000000007//998244353//1000000007
#define EPS 1e-9
#define Gr 9.8
#define PI acos(-1)
#define REP(i,n) for(int (i)=0;(i)<(int)(n);(i)++)
#define REQ(i,n) for(int (i)=1;(i)<=(int)(n);(i)++)
#define lch (rt<<1)
#define rch (rt<<1|1)
#define readmp(n) for(int i=0,u,v;i<n;i++) {scanf("%d%d",&u,&v); mp[u].push_back(v); mp[v].push_back(u);}
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef long double ld;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef ll ValType;
template<typename  T> void maxtt(T& t1, T t2) {
    t1=max(t1,t2);
}
template<typename  T> void mintt(T& t1, T t2) {
    t1=min(t1,t2);
}
#define MAX 30135

bool debug = 0;
int n,m,k;
int dx[4] = {0,1,0,-1}, dy[4] = {1,0,-1,0};
string direc="URDL";//"RDLU";
ll ln, lk, lm;
void etp(bool f = 0) {
    puts(f ?"YES" : "NO");
    exit(0);
}
void addmod(int &x, int y, int mod = MOD) {
    assert(y>=0);
    x+=y; if (x>=mod) x-=mod;
    assert(x>=0 && x<mod);
}
void et(int x=-1) {
    printf("%d\n", x); exit(0);
}
ll fastPow(ll x, ll y, int mod=MOD) {
    ll ans = 1;
    while(y>0) {
        if(y&1) ans = (x * ans)%mod;
        x = x*x%mod;
        y>>=1;
    }
    return ans;
}
ll gcd1(ll x, ll y) { return y?gcd1(y,x%y):x;}

int d,gen[33],B[MAX];
bitset<MAX> all;
struct nd {
    ll len,num;
    bitset<MAX> pre, suf;
    nd() {
        len=num=0; pre.reset(); suf.reset();
    }
    friend nd operator + (const nd &a, const nd &b) {
        if (a.len == 0) return b;
        nd res;
        res.len = a.len+b.len; res.num=a.num+b.num;
        res.pre=a.pre; res.suf=b.suf;
        if (a.len < n-1) {
            res.pre &= (b.pre >> a.len) | all<<(n-1-a.len);
        }
        if (b.len < n-1) {
            res.suf &= (a.suf<<b.len) | all>>(n-1-b.len);
        }
        if (res.len >= n) {
            bitset<MAX> tmp=a.suf & b.pre;
            if (a.len <n-1) tmp &= all >> (n-1-a.len);
            if (b.len <n-1) tmp &= all << (n-1-b.len);
            res.num += tmp.count();
        }
        return res;
    }
}f[70][65];
ll pw[77],l,r;
void init() {
    pw[0]=1;
    REQ(i,70) pw[i]=pw[i-1]*d;
    int c=0;
    while(pw[c+1] < r) c++;
    REQ(i,n-1) all[i]=1;
    REP(j,m+1) {
        f[0][j].len=1;
        if (n==1) f[0][j].num = j<= B[1];
        else {
            for(int i=1;i<=n;i++) {
                f[0][j].pre[i-1] = j<=B[i];
                f[0][j].suf[i]=j<=B[i];
            }
        }
    }
    REQ(i,c) {
        REP(j,m+1) {
            REP(k,d) {
                f[i][j] = f[i][j] + f[i-1][(j+gen[k])%m];
            }
        }
    }
}
ll cal(ll x) {
    int c=0;
    while(pw[c+1] < x) c++;
    nd res;
    int add=0;
    for(int i=c;i>=0;i--) {
        REP(j,d) {
            if (x >= pw[i]) {
                x-=pw[i];
                res = res + f[i][(add+gen[j])%m];
            } else {
                add+=gen[j]; break;
            }
        }
    }
    return res.num;
}
void fmain(int tid) {
    scanf("%d%d", &d, &m);
    REP(i,d) scanf("%d", gen+i);
    scanf("%d", &n);
    REQ(i,n) scanf("%d", B+i);
    scanf("%lld%lld",&l,&r);
    init();
    printf("%lld\n", cal(r)-cal(l+n-1-1));
}

int main() {
    int t=1;
//    scanf("%d", &t);
    REQ(i,t) {
        fmain(i);
    }
    return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

int d,m,n,x[25],a[30005];
vector<ll>ok;
ll L,R;

map<ll,vector<ll> >ans;
map<ll,vector<ll> >zip;
vector<ll>calc(ll lim){
	//0,...,limの中の0,...,m-1の個数
	if(zip.find(lim) != zip.end()) return zip[lim];
	vector<ll>ret(m,0);
	if(lim == 0){
		ret[0] = 1;
		return ret;
	}
	for(int beg=0;beg<d && beg<=lim;beg++){
		ll nxt_lim = (lim-beg) / d;
		//beg, beg+d, ... , beg+nxt_lim*d
		vector<ll>R = calc(nxt_lim);
		rep(i,m){
		    int a = (i+x[beg]);
		    if(a >= m) a-=m;
			ret[a] += R[i];
		}
	}
	return zip[lim] = ret;
}
//スタートは0,....,lim
//許容maskはmask
//下の桁で場合分けすると、サイズ /d の問題をd個になる
//mask.size() = 1になれば、0,...,limの中にmaskに対応する値が何個あるか分かればいいから、これはdp
void rec(ll lim,vector<ll>mask,bool F){
	if(mask.size() == 1){
		if(ans.find(lim) == ans.end()){
			ans[lim] = vector<ll>(m,0);
		}
		for(int i=0;i<m;i++){
			if(((mask[0]>>i)&1LL)){
				if(F) ans[lim][i]++;
				else ans[lim][i]--;
			}
		}
		return ;
	}
	//mod d でどこから始めるか
	for(int beg=0;beg<d && beg<=lim;beg++){
		ll nxt_lim = (lim-beg) / d;
		vector<ll>vec;
		int zan = mask.size();
		int bb = (d-beg);
		int xx = 1+(zan-bb+d-1)/d;
		vec.resize(xx,0LL);
		ll B = (1LL<<m)-1;
		int cur = beg;
		int id = 0;
		for(int i=0;i<mask.size();i++){
			int add = x[cur];
			//need + add がmask[i]になる
			ll nw = 0;
			nw = (mask[i]>>add) | (mask[i]<<(m-add));
			B &= nw;
			if(cur == d-1 || i == mask.size()-1){
				vec[id++] = B; //cout << B << endl;
				B = (1LL<<m)-1;
			}
			cur++;
			if(cur == d) cur = 0;
		}
		assert(id == xx);
		rec(nxt_lim,vec,F);
	}
}
int main(){
	cin>>d>>m;
	rep(i,d){
		cin>>x[i];
	}
	cin>>n;
	rep(i,n){
		cin>>a[i];
		ok.pb( (2LL<<a[i])-1LL );
	}
	cin>>L>>R; L--; R--;
	rec(R-n+1,ok,true);
	if(L-1 >= 0) rec(L-1,ok,false);
	ll ret = 0;
	for(map<ll,vector<ll> >::iterator it=ans.begin();it!=ans.end();it++){
		vector<ll>tbl = calc(it->fi);
		for(int i=0;i<m;i++){
			ret += tbl[i] * it->sc[i];
		}
	}
	cout << ret << endl;
}

#include<bits/stdc++.h>
const int N = 3e4 + 10;
typedef std::bitset<N> BI;
long long ri() {
	char c = getchar(); long long x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct info {
	long long ans, len;
	BI pre, suf;
	info operator + (const info &b) { //Merge this and b
		info c;
		c.ans = ans + b.ans;
		c.len = len + b.len;
		c.pre = pre; c.suf = b.suf;
		if(len < n - 1) c.pre &= (b.pre >> len) | (all << n - 1 - len);
		if(b.len < n - 1) c.suf &= (suf << b.len) | (all >> n - 1 - b.len);
		if(len + b.len >= n) {
			BI res = suf & b.pre;
			if(len < n - 1) res &= (all >> n - 1 - len);
			if(b.len < n - 1) res &= (all << n - 1 - b.len);
			c.ans += res.count();
		}
		return c;
	}
	void operator += (const info &b) {*this = !len ? b : *this + b;}
}f[66][66];
long long Query(long long x) {
	info res; res.ans = res.len = 0;
	int add = 0;
	for(int i = tot; ~i; --i)
		for(int j = 1;j <= d; ++j) {
			if(x >= len[i]) {
				x -= len[i];
				res += f[i][(add + gen[j]) % m];
			}
			else {
				(add += gen[j]) %= m;
				break;
			}
		}
	return res.ans;
}
int main() {
	d = ri(); m = ri();
	for(int i = 1;i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1;i <= n; ++i)
		b[i] = ri();
	for(int i = 1;i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0;i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1;j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[j + 1];
				f[0][i].suf[j] = i <= b[j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(;len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0;i < m; ++i)
			for(int j = 1;j <= d; ++j)
				f[tot][i] += f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", Query(R) - Query(L + n - 2));
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define BI bitset<N>

using namespace std;
const int N=3e4+10;
int n,m,d,tot,gen[30],b[N];
ll len[70],l,r;
BI full;

template<typename T>inline void read(T &x){
    x=0; bool f=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    if(f) x=-x;
}

struct node{
    ll ans,len;
    BI pre,suf;
    node operator + (const node &a){
        node b;
        b.ans=ans+a.ans;
        b.len=len+a.len;
        b.pre=pre; b.suf=a.suf;
        if(len<n-1) b.pre&=(a.pre>>len)|(full<<n-1-len);
        if(a.len<n-1) b.suf&=(suf<<a.len)|(full>>n-1-a.len);
        if(len+a.len>=n){
            BI res=suf&a.pre;
            if(len<n-1) res&=(full>>n-1-len);
            if(a.len<n-1) res&=(full<<n-1-a.len);
            b.ans+=res.count();
        }
        return b;
    }
    void operator += (const node &a){*this=!len?a:*this+a;}
}f[70][70];

ll query(ll x){
    node res;
    res.ans=res.len=0;
    int tmp=0;
    for(int i=tot;~i;--i)
        for(int j=1;j<=d;j++){
            if(x>=len[i]){
                x-=len[i];
                res+=f[i][(tmp+gen[j])%m];
            }
            else{
                tmp=(tmp+gen[j])%m;
                break;
            }
        }
    return res.ans;
}

int main(){
    read(d); read(m);
    for(int i=1;i<=d;i++) read(gen[i]);
    read(n);
    for(int i=1;i<=n;i++) read(b[i]);
    for(int i=1;i<n;i++) full.set(i);
    len[tot]=1;
    for(int i=0;i<m;i++){
        f[0][i].len=1;
        if(n==1) f[0][i].ans= i<=b[1];
        else{
            for(int j=1;j<=n-1;j++){
                f[0][i].pre[j]= i<=b[j+1];
                f[0][i].suf[j]= i<=b[j];
            }
        }
    }
    read(l); read(r);
    for(;len[tot]<=r/d;){
        ++tot; len[tot]=len[tot-1]*d;
        for(int i=0;i<m;i++)
            for(int j=1;j<=d;j++)
                f[tot][i]+=f[tot-1][(i+gen[j])%m];
    }
    printf("%lld\n",query(r)-query(l+n-2));
    return 0;
}

#include <cstdio>
#include <bitset>

int d,m,g[21],n,b[30001];
long long l,r;
struct info{
	std::bitset<30001>pre,suf;
	long long cnt;
	long long len;
	info(){
		pre.reset();
		suf.reset();
		cnt=len=0;
	}
}f[101][61];
std::bitset<30001>all;
//pre:前缀能否成为后缀
info merge(info a,info b){
	if(!a.len)return b;
	if(!b.len)return a;
	info c;
	int l=std::max(n-b.len,1ll),r=std::min(a.len,1ll*(n-1));
	c.cnt=a.cnt+b.cnt;
//	puts("*");
//	printf("%d %d\n",a.len,b.len,a.cnt+b.cnt);
//	for(int i=1;i<n;i++)printf("%d ",(int)(a.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(a.pre)[i]);putchar('\n');
//	for(int i=1;i<n;i++)printf("%d ",(int)(b.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(b.pre)[i]);putchar('\n');
	if(l<=r)c.cnt+=(((a.suf&b.pre)>>l).count()-((a.suf&b.pre)>>(r+1)).count());
//	printf("%d\n",c.cnt);
	c.len=a.len+b.len;
	c.pre=a.pre;
//	for(int i=n-1;i;i--)printf("%d ",(int)((b.pre>>a.len)|(all<<(n-a.len)))[i]);putchar('\n');
	if(a.len<n)c.pre&=(b.pre>>a.len)|(all<<(n-a.len));
	c.suf=b.suf;
	if(b.len<n)c.suf&=(a.suf<<b.len)|(all>>(30000-b.len));
//	for(int i=1;i<n;i++)printf("%d ",(int)c.suf[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)c.pre[i]);putchar('\n');
	return c;
}
info calc(long long len,int pre){
	if(!len)return info();
	long long x=1,p=0;
	while(x<=len)x*=d,++p;
	x/=d,--p;
	info ans;
	for(;len;){
		int t=-1;
		for(long long i=1;i*x<=len;i++){
			ans=merge(ans,f[p][(pre+g[i])%m]);
			t=i;
		}
//		printf("*%lld %d %d %d %d\n",len,x,p,pre,ans.cnt);
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.pre[i]);putchar('\n');
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.suf[i]);putchar('\n');
		(pre+=g[t+1])%=m;
		len%=x;
		x/=d,--p;
	}
	return ans;
}
int main(){
	scanf("%d%d",&d,&m);
	for(int i=1;i<=d;i++)scanf("%d",g+i);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",b+i);
	scanf("%lld%lld",&l,&r);
	all.set();
	for(int i=0;i<m;i++){
		f[0][i].len=1;
		f[0][i].cnt=(n==1&&i<=b[1]);
		for(int j=1;j<n;j++){
			if(i<=b[n-j+1]&&j<n)f[0][i].pre.set(n-j);
			if(i<=b[j]&&j)f[0][i].suf.set(j);
		}
	}
	for(long long i=1,Mul=1;Mul<=r;Mul*=d,i++){
		for(int j=0;j<m;j++){
			f[i][j]=f[i-1][j];
			for(int k=2;k<=d;k++)
				f[i][j]=merge(f[i][j],f[i-1][(j+g[k])%m]);
		}
	}
//	for(int i=0;i<=4;i++)
//		for(int j=0;j<m;j++){
//			printf("-%d %d %d\n",i,j,f[i][j].cnt);
//			for(int k=1;k<n;k++)printf("%d ",(int)f[i][j].suf[k]);putchar('\n');
//			for(int k=n-1;k;k--)printf("%d ",(int)f[i][j].pre[k]);putchar('\n');
//		}
	printf("%lld\n",calc(r,0).cnt-calc(l+n-2,0).cnt);
}

#include<bits/stdc++.h>
#define ll long long
#define BI bitset<N>

using namespace std;
const int N=3e4+10;
int n,m,d,tot,gen[30],b[N];
ll len[70],l,r;
BI full;

template<typename T>inline void read(T &x){
    x=0; bool f=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    if(f) x=-x;
}

struct node{
    ll ans,len;
    BI pre,suf;
    node operator + (const node &a){
        node b;
        b.ans=ans+a.ans;
        b.len=len+a.len;
        b.pre=pre; b.suf=a.suf;
        if(len<n-1) b.pre&=(a.pre>>len)|(full<<n-1-len);
        if(a.len<n-1) b.suf&=(suf<<a.len)|(full>>n-1-a.len);
        if(len+a.len>=n){
            BI res=suf&a.pre;
            if(len<n-1) res&=(full>>n-1-len);
            if(a.len<n-1) res&=(full<<n-1-a.len);
            b.ans+=res.count();
        }
        return b;
    }
    void operator += (const node &a){*this=!len?a:*this+a;}
}f[70][70];

ll query(ll x){
    node res;
    res.ans=res.len=0;
    int tmp=0;
    for(int i=tot;~i;--i)
        for(int j=1;j<=d;j++){
            if(x>=len[i]){
                x-=len[i];
                res+=f[i][(tmp+gen[j])%m];
            }
            else{
                tmp=(tmp+gen[j])%m;
                break;
            }
        }
    return res.ans;
}

int main(){
    read(d); read(m);
    for(int i=1;i<=d;i++) read(gen[i]);
    read(n);
    for(int i=1;i<=n;i++) read(b[i]);
    for(int i=1;i<n;i++) full[i]=1;
    len[tot]=1;
    for(int i=0;i<m;i++){
        f[0][i].len=1;
        if(n==1) f[0][i].ans= i<=b[1];
        else{
            for(int j=1;j<=n-1;j++){
                f[0][i].pre[j]= i<=b[j+1];
                f[0][i].suf[j]= i<=b[j];
            }
        }
    }
    read(l); read(r);
    for(;len[tot]<=r/d;){
        ++tot; len[tot]=len[tot-1]*d;
        for(int i=0;i<m;i++)
            for(int j=1;j<=d;j++)
                f[tot][i]+=f[tot-1][(i+gen[j])%m];
    }
    printf("%lld\n",query(r)-query(l+n-2));
    return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long s64;
#define rep(i,l,r) for(int i=l;i<=r;++i)
const int N=30000+2;
bitset<N> get(int l,int r)
{
	bitset<N> all1;
	if(l>r)return all1;
	all1.set();
	return (all1>>(N-1-r))^(all1>>(N-1-(l-1)));
}
int n,b[N];
struct Data
{
	s64 len,ans;
	bitset<N>pre,suf;
};
Data init(int v)
{
	Data x;
	x.len=1;x.ans=(n==1)&&(b[n]>=v);
	rep(i,1,n)x.pre[i]=(b[n-i+1]>=v);
	rep(i,1,n)x.suf[i]=(b[n-i]>=v);
	return x;
}
Data operator +(const Data &l,const Data &r)
{
	Data ans;
	ans.len=l.len+r.len;
	ans.ans=l.ans+r.ans+(l.suf&r.pre&get(max(1LL,n-l.len),min(r.len,n-1LL))).count();
	if(l.len>=n)ans.pre=l.pre;
	else ans.pre=l.pre&(get(1,l.len)|(r.pre<<l.len));
	if(r.len>=n)ans.suf=r.suf;
	else ans.suf=r.suf&(get(n-r.len,n)|(l.suf>>r.len));
	return ans;
}
const int D=20+2,M=60+2,L=60+2;
int d,m,gen[D];
Data dp[L][M];

s64 F(s64 r)
{
	Data ans;
	ans.len=ans.ans=0;
	ans.pre.set();ans.suf.set();
	int v0=0;
	while(r)
	{
		int i=0;
		while(dp[i][0].len<=r/d)++i;
		int j=0;
		while(r>=dp[i][0].len)
		{
			r-=dp[i][0].len;
			ans=ans+dp[i][(v0+gen[j])%m];
			++j;
		}
		(v0+=gen[j])%=m;
	}
	return ans.ans;
}

int main()
{
#ifdef kcz
	freopen("1.in","r",stdin);
#endif
	cin>>d>>m;
	rep(i,0,d-1)scanf("%d",gen+i);
	cin>>n;
	rep(i,1,n)scanf("%d",b+i);
	s64 l,r;
	cin>>l>>r;

	rep(v,0,m-1)dp[0][v]=init(v);
	int i=0;
	while(dp[i][0].len<=r/d)
	{
		++i;
		rep(v,0,m-1)
		{
			dp[i][v]=dp[i-1][v];
			rep(j,1,d-1)dp[i][v]=dp[i][v]+dp[i-1][(v+gen[j])%m];
		}
	}

	cout<<F(r)-F(l+n-2);
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int d,m,gen[25],b[30010],n;
ll l,r;
bitset<30010> all;
class dat
{
	public:
		ll len,ans;
		bitset<30010> pre,suf;
		dat operator +(const dat &t)const
		{
			dat c;
			c.ans=ans+t.ans;
			c.len=len+t.len;
			c.pre=pre;c.suf=t.suf;
			if(len<n-1)c.pre&=(t.pre>>len)|(all<<(n-len-1));
			if(t.len<n-1)c.suf&=(suf<<t.len)|(all>>(n-t.len-1));
			if(c.len>=n)
			{
				bitset<30010> cur=suf&t.pre;
				if(len<n-1)cur&=(all>>(n-1-len));
				if(t.len<n-1)cur&=(all<<(n-1-t.len));
				c.ans+=cur.count();
			}
			return c;
		}
		void operator +=(const dat &t)
		{
			(*this)=((!len)?t:(*this)+t);
		}
}f[66][66];
ll len[66];
int tot;
ll solve(ll r)
{
	dat ans;
	ans.len=ans.ans=0;
	int delta=0;
	for(int i=tot;i>=0;i--)
	{
		for(int j=1;j<=d;j++)
		{
			if(r>=len[i])
			{
				r-=len[i];
				ans+=f[i][(delta+gen[j])%m];
			}
			else
			{
				delta=(delta+gen[j])%m;
				break;
			}
		}
	}
	return ans.ans;
}
int main()
{
	scanf("%d%d",&d,&m);
	for(int i=1;i<=d;i++)scanf("%d",&gen[i]);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",&b[i]);
	for(int i=1;i<n;i++)all.set(i);
	scanf("%lld%lld",&l,&r);
	for(int i=0;i<m;i++)
	{
		f[0][i].len=1;
		if(n==1)f[0][i].ans=(i<=b[1]);
		else
		for(int j=1;j<=n-1;j++)
		{
			f[0][i].pre[j]=(i<=b[j+1]);
			f[0][i].suf[j]=(i<=b[j]);
		}
	}
	len[0]=1;
	for(tot=0;len[tot]<=r/d;)
	{
		++tot;len[tot]=len[tot-1]*d;
		for(int i=0;i<m;i++)
		{
			for(int j=1;j<=d;j++)
			{
				f[tot][i]+=f[tot-1][(i+gen[j])%m];
			}
		}
	}
	printf("%lld\n",solve(r)-solve(l+n-2));
	return 0;
}

#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef long long LL;
typedef double db;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3e4+5;
const int M = 65;

int d,m;
int g[25];
int b[N],n;
bool can[N][16][M];
LL mi[N];
LL L,R;
LL f[M][M][M];
int digi[M],a[M];
int sum[N*20];
int sec[N],k,start[N],val[N];
bool yes1[M],yes2[M];

LL solve(LL r){
	if (r<0)return 0;
	for(LL i=0,x=r;i<=60;x/=d,i++)digi[i]=x%d;
	int L=0;
	for(;mi[L]<=n;L++);
	fo(i,0,60)fo(p,0,m-1)fo(u,0,m-1)f[i][p][u]=0;
	int pp=0,uu=g[1];
	fd(i,60,1){
		fo(x,0,digi[i]-1){
			int p=(pp+g[x])%m;
			int u;
			if (x==d-1)u=(uu+m-g[x])%m;else u=(g[x+1]+m-g[x])%m;
			f[i][p][u]++;
		}
		pp=(pp+g[digi[i]])%m;
		if (digi[i]==d-1)uu=(uu+m-g[d-1])%m;
		else uu=(g[digi[i]+1]+m-g[digi[i]])%m;
		fo(p,0,m-1)
			fo(u,0,m-1)
			if (f[i][p][u]){
				fo(x,0,d-1){
					int p_=(p+g[x])%m;
					int u_;
					if (x==d-1)u_=(u+m-g[x])%m;
					else u_=(g[x+1]+m-g[x])%m;
					f[i-1][p_][u_]+=f[i][p][u];
				}
			}
	}
	LL ret=0;
	int p1=0,u1=g[1];
	fd(i,60,L){
		p1=(p1+g[digi[i]])%m;
		if (digi[i]==d-1)u1=(u1+m-g[d-1])%m;
		else u1=(g[digi[i]+1]+m-g[digi[i]])%m;
	}
	fo(i,0,mi[L]-1){
		sum[i]=0;
		for(int x=i;x;x/=d)sum[i]+=g[x%d];
		sum[i]%=m;
	}
	int cnt=0;
	fo(st,0,mi[L]-1){
		k=0;
		int mid=-1;
		for(int x=1,now=st;x<=n;){
			int w1=0,w2=0;
			for(;x+mi[w1+1]-1<=n;w1++);
			for(;w2<L&&now%mi[w2+1]==0;w2++);
			int w=min(w1,w2);
			sec[++k]=w;
			start[k]=x;
			val[k]=now;
			x+=mi[w];
			now+=mi[w];
			if (now>=mi[L])mid=k+1,now-=mi[L];
		}
		if (mid==-1)mid=k+1;
		fo(i,0,m-1)yes1[i]=yes2[i]=1;
		fo(i,1,mid-1)
			fo(p,0,m-1)yes1[p]&=can[start[i]][sec[i]][(p+sum[val[i]])%m];
		fo(i,mid,k)
			fo(p,0,m-1)yes2[p]&=can[start[i]][sec[i]][(p+sum[val[i]])%m];
		fo(p,0,m-1)
		if (yes1[p])
			fo(u,0,m-1)
			if (yes2[(p+u)%m]){
				ret=ret+f[L][p][u];
				cnt++;
			}
		if (yes1[p1]&&yes2[(p1+u1)%m]&&r%mi[L]>=st)ret++;
	}
	return ret;
}

int main(){
	d=get();m=get();
	fo(i,0,d-1)g[i]=get();
	n=get();
	fo(i,1,n)b[i]=get();
	mi[0]=1;
	fo(i,1,16)mi[i]=mi[i-1]*d;
	fd(i,n,1){
		fo(p,0,b[i])can[i][0][p]=1;
		for(int j=1;i+mi[j]-1<=n;j++)
			fo(p,0,m-1){
				can[i][j][p]=1;
				fo(x,0,d-1)can[i][j][p]&=can[i+x*mi[j-1]][j-1][(p+g[x])%m];
			}
	}
	cin>>L>>R;
	R=R-n+1;
	L--,R--;
	LL vr=solve(R);
	LL vl=solve(L-1);
	cout<<vr-vl<<endl;
	return 0;
}

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define beg(x) x.begin()
#define en(x) x.end()
#define all(x) beg(x), en(x)
#define resz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 100001;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace io {
    // TYPE ID (StackOverflow)

    template<class T> struct like_array : is_array<T>{};
    template<class T, size_t N> struct like_array<array<T,N>> : true_type{};
    template<class T> struct like_array<vector<T>> : true_type{};
    template<class T> bool is_like_array(const T& a) { return like_array<T>::value; }

    // I/O

    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0);
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
    }

    // INPUT

    template<class T> void re(T& x) { cin >> x; }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest);
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }

    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class Arg, class... Args> void re(Arg& first, Args&... rest) { re(first); re(rest...); }
    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }

    // OUTPUT

    template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) {
        os << '{' << a.f << ", " << a.s << '}'; return os;
    }
    template<class T> ostream& printArray(ostream& os, const T& a, int SZ) {
        os << '{';
        F0R(i,SZ) {
            if (i) {
                os << ", ";
                if (is_like_array(a[i])) cout << "\n";
            }
            os << a[i];
        }
        os << '}';
        return os;
    }
    template<class T, size_t SZ> ostream& operator<<(ostream& os, const array<T,SZ>& a) {
        return printArray(os,a,SZ);
    }
    template<class T> ostream& operator<<(ostream& os, const vector<T>& a) {
        return printArray(os,a,sz(a));
    }
    template<class T> ostream& operator<<(ostream& os, const set<T>& a) {
        os << vector<T>(all(a)); return os;
    }
    template<class T1, class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {
        os << vector<pair<T1,T2>>(all(a)); return os;
    }

    template<class T> void pr(const T& x) { cout << x << '\n'; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        cout << first << ' '; pr(rest...);
    }
}

using namespace io;

int d,m;
ll ans;
vi gen;
map<ll,vl> stor;

vl get(ll ind) {
    if (stor.count(ind)) return stor[ind];
    vl v(m); if (ind == 1) v[0] ++;
    if (ind <= 1) return stor[ind] = v;
    F0R(i,d) {
        auto a = get((ind+d-1-i)/d);
        F0R(j,m) v[j] += a[(j+m-gen[i])%m];
    }
    return stor[ind] = v;
}

uint64_t shift(uint64_t x, int y) {
    return (x>>y)|(x<<(m-y));
}

void solve(ll ind, vector<uint64_t> v) {
    if (ind <= 0) return;
    if (sz(v) == 1) {
        auto a = get(ind);
        F0R(i,m) if (v[0]&((uint64_t)1<<i)) ans += a[i];
        return;
    }
    F0R(i,d) {
        vector<uint64_t> V((i+sz(v)+d-1)/d,((uint64_t)1<<m)-1);
        F0R(j,sz(v)) V[(j+i)/d] &= shift(v[j],gen[(j+i)%d]);
        solve((ind+d-1-i)/d,V);
    }
}

int main() {
    // you should actually read the stuff at the bottom
    setIO(); re(d,m); gen.resz(d); re(gen);
    int n; re(n);
    vector<uint64_t> v(n);
    F0R(i,n) {
        int x; re(x);
        v[i] = (1LL<<(x+1))-1;
    }
    ll l,r; re(l,r);
    solve(l-1,v); ans *= -1; solve(r-n+1,v); pr(ans);
    // you should actually read the stuff at the bottom
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/

//#pragma GCC optimize("O3")
//#pragma GCC target("arch=corei7-avx")
#include <bits/stdc++.h>
#ifndef ONLINE_JUDGE
# include <sys/time.h>
# include <sys/resource.h>
#endif

/*** TEMPLATE CODE STARTS HERE ***/

#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795028841971693993751
#endif

using namespace std;

typedef vector<string> vs;
typedef long long ll;
typedef complex<double> pnt;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define RA(x) begin(x), end(x)
#define FE(i, x) for (auto i = begin(x); i != end(x); ++i)
#define SZ(x) ((ll) (x).size())

template<class T>
void splitstr(const string &s, vector<T> &out)
{
    istringstream in(s);
    out.clear();
    copy(istream_iterator<T>(in), istream_iterator<T>(), back_inserter(out));
}

template<class T> T gcd(T a, T b) { return b ? gcd(b, a % b) : a; }

static void redirect(int argc, const char **argv)
{
#ifndef ONLINE_JUDGE
    struct rlimit rlim;
    getrlimit(RLIMIT_STACK, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_STACK, &rlim);
#ifndef __SANITIZE_ADDRESS__
    getrlimit(RLIMIT_DATA, &rlim);
    rlim.rlim_cur = 256 * 1024 * 1024;
    setrlimit(RLIMIT_DATA, &rlim);
#endif
#endif

    ios::sync_with_stdio(false);
    cin.tie(NULL);
    if (argc > 1)
    {
        static filebuf f;
        f.open(argv[1], ios::in);
        cin.rdbuf(&f);
        if (!cin)
        {
            cerr << "Failed to open '" << argv[1] << "'" << endl;
            exit(1);
        }
    }

    if (argc > 2)
    {
        static filebuf f;
        f.open(argv[2], ios::out | ios::trunc);
        cout.rdbuf(&f);
        if (!cout)
        {
            cerr << "Failed to open '" << argv[2] << "'" << endl;
        }
    }
}

/*** TEMPLATE CODE ENDS HERE */

static int d, m;
static vi gen;
static vi prefix;

static int sub(int x, int y)
{
    x -= y;
    if (x < 0)
        x += m;
    return x;
}

struct interval
{
    ll mask = 0;

    explicit interval(ll mask = 0) : mask(mask) {}

    interval operator&(const interval &x) const
    {
        return interval(mask & x.mask);
    }

    interval operator-(int shift) const
    {
        ll smask = (1LL << shift) - 1;
        return interval((mask >> shift) | ((mask & smask) << (m - shift)));
    }

    bool contains(int v) const
    {
        return mask & (1LL << v);
    }
};

static interval all;

static unordered_map<ll, vll> memo;

static vll &prepare(ll R)
{
    auto pos = memo.find(R);
    if (pos == memo.end())
    {
        vll &ans = memo[R];
        ans.resize(m);
        if (R <= d)
        {
            for (ll i = 0; i < R; i++)
                ans[gen[i]]++;
        }
        else
        {
            for (int p = 0; p < d; p++)
            {
                ll R1 = (R - p + d - 1) / d;
                const auto &ch = prepare(R1);
                for (int i = 0; i < m; i++)
                    ans[i] += ch[sub(i, gen[p])];
            }
        }
        return ans;
    }
    else
        return pos->second;
}

static inline ll solve0(int v, ll R)
{
    return prepare(R)[v];
}

static ll solve1(const interval &b, ll R)
{
    ll ans = 0;
    for (int i = 0; i < m; i++)
        if (b.contains(i))
            ans += solve0(i, R);
#ifdef PRINT
    cerr << "solve1: " << b.mask << ", " << R << " -> " << ans << '\n';
#endif
    return ans;
}

static ll solve(const vector<interval> &b, ll R)
{
    int N = SZ(b);
    ll ans = 0;
    if (R <= d && N <= d)
    {
        for (int i = 0; i < R; i++)
        {
            bool good = true;
            for (int j = 0; j < N; j++)
                if (!b[j].contains(prefix[i + j]))
                    good = false;
            ans += good;
        }
        return ans;
    }
    else if (N > 1)
    {
        for (int p = 0; p < d; p++)
        {
            int No = (N + p + d - 1) / d;
            vector<interval> c(No);
            int ofs = -p;
            for (int i = 0; i < No; i++)
            {
                interval cur = all;
                for (int j = 0; j < d; j++, ofs++)
                {
                    if (ofs >= 0 && ofs < N)
                        cur = cur & (b[ofs] - gen[j]);
                }
                c[i] = cur;
            }
            ans += solve(c, (R - p + d - 1) / d);
        }
#ifdef PRINT
        cerr << "solve: [";
        for (int i = 0; i < N; i++)
        {
            if (i)
                cerr << ", ";
            cerr << b[i].mask;
        }
        cerr << "], " << R << " -> " << ans << '\n';
#endif
        return ans;
    }
    else
        return solve1(b[0], R);
}

int main(int argc, const char **argv)
{
    redirect(argc, argv);
    cin >> d >> m;
    all = interval((1LL << m) - 1);
    gen.resize(d);
    for (int i = 0; i < d; i++)
        cin >> gen[i];
    prefix = gen;
    for (int i = 0; i < d; i++)
        prefix.push_back((gen[i] + gen[1]) % m);
    int N;
    cin >> N;
    vector<interval> b(N);
    for (int i = 0; i < N; i++)
    {
        int x;
        cin >> x;
        b[i] = interval((2LL << x) - 1);
    }
    ll L, R;
    cin >> L >> R;
    L--;
    R--;
    cout << solve(b, R - N + 2) - solve(b, L) << '\n';

    return 0;
}

#include<bits/stdc++.h>
using namespace std;
using ll = long long;

const int MAXD = 25;
const int MAXM = 61;
int D, M;
int gen[MAXD];

map<ll, vector<ll>> mem;
vector<ll>& dfs2(ll H) {
	assert(H >= 0);
	if (mem.count(H)) {
		return mem[H];
	}
	auto& res = mem[H] = vector<ll>(size_t(M));
	if (H == 0) {
		res[0]++;
		return res;
	}
	for (int d = 0; d < D && d <= H; d++) {
		vector<ll>& o = dfs2((H-d) / D);
		for (int i = 0; i < M; i++) {
			res[(i+gen[d]) % M] += o[i];
		}
	}
	return res;
}

map<ll, vector<ll>> results;
void dfs(const vector<uint64_t> &B, ll H) {
	if (H < 0)
		return;
	assert(H >= 0);
	const int N = int(B.size());
	if (N == 1) {
		if (!results.count(H)) {
			results[H] = vector<ll>(M);
		}
		vector<ll>& v = results[H];
		for (int m = 0; m < M; m++) {
			v[m] += bool((B[0]) & (1ll << m));
		}
		return;
	}
	for (int d = 0; d < D && d <= H; d++) {
		ll nxtH = (H - d) / D;
		vector<uint64_t> nxtB(size_t((d + (N-1)) / D + 1), ((1ll << M)-1));
		for (int i = 0; i < N; i++) {
			uint64_t msk = B[i];
			int off = gen[(i+d) % D];
			assert(0 <= off && off < M);
			msk = (msk >> off) | (msk << (M - off));
			nxtB[(i + d) / D] &= msk;
		}
		dfs(nxtB, nxtH);
	}
}

int main(void) {
	ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);

  cin >> D >> M;
	for (int i = 0; i < D; i++) {
		cin >> gen[i];
	}
	assert(gen[0] == 0);
	int N;
	cin >> N;
	vector<uint64_t> B(N);
	for (int i = 0; i < N; i++) {
		int b; cin >> b; b++;
		B[i] = (1ll << b) - 1;
	}
	ll L, R;
	cin >> L >> R;
	L--; R--;
	R++;
	assert(R - L >= N);
	assert(R-N > L-1);
	dfs(B, L - 1);
	for (auto& it : results) {
		for (ll& v : it.second) {
			v = -v;
		}
	}
	dfs(B, R - N);
	ll res = 0;
	for (auto& it : results) {
		vector<ll>& v = dfs2(it.first);
		for (int i = 0; i < M; i++) {
			res += v[i] * it.second[i];
		}
	}
	cout << res << '\n';
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;

#define rep(i,l,r) for(register int i = l ; i <= r ; i++)
#define repd(i,r,l) for(register int i = r ; i >= l ; i--)
#define rvc(i,S) for(register int i = 0 ; i < (int)S.size() ; i++)
#define rvcd(i,S) for(register int i = ((int)S.size()) - 1 ; i >= 0 ; i--)
#define fore(i,x)for (register int i = head[x] ; i ; i = e[i].next)
#define forup(i,l,r) for (register int i = l ; i <= r ; i += lowbit(i))
#define fordown(i,id) for (register int i = id ; i ; i -= lowbit(i))
#define pb push_back
#define prev prev_
#define stack stack_
#define mp make_pair
#define fi first
#define se second
#define lowbit(x) (x&(-x))

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pr;

const ll inf = 2e18;
const int N = 3e4 + 10;
const int maxn = 2000020;
const ll mod = 1e9 + 7;

struct node{
	ll num,len;
	bitset <N> pre,suf;
	node() { num = len = 0; pre.reset(),suf.reset(); }
}f[70][62];
int gen[120],n,m,d,B[N];
ll l,r,pow_[70];
int a[maxn];
bitset <N> all;

node merge(const node &a,const node &b){
	if ( !a.len ) return b;
	node res;
	res.len = a.len + b.len;
	res.pre = a.pre , res.suf = b.suf; //pre和suf中包含了长度1..n-1的所有信息，所以合并的时候直接&就好
	res.num = a.num + b.num;
	if ( a.len <= n - 2 ) res.pre &= (b.pre >> a.len) | (all << (n - 1 - a.len));
	if ( b.len <= n - 2 ) res.suf &= (a.suf << b.len) | (all >> (n - 1 - b.len));
	if ( res.len >= n ){
		bitset<N> tmp = a.suf & b.pre;
		if ( a.len <= n - 2 ) tmp &= all >> (n - 1 - a.len); //如果a的长度不足，则删除高位
		if ( b.len <= n - 2 ) tmp &= all << (n - 1 - b.len); //删除低位
		res.num += tmp.count();
	}
	return res;
}
void init(){
	pow_[0] = 1;
	rep(i,1,64) pow_[i] = pow_[i - 1] * d;

	int c = 0;
	while ( pow_[c + 1] < r ) c++;
	rep(i,1,n - 1) all[i] = 1;
	rep(j,0,m){
		f[0][j].len = 1;
		if ( n == 1 ) f[0][j].num = j <= B[1];
		else{
			//把没有出现的位置看成0
			//这样便于合并、否则每次合并还需要check整段是否合法
			rep(k,1,n){
				f[0][j].pre[k - 1] = j <= B[k];
				f[0][j].suf[k] = j <= B[k];
			}
		}
	}
	rep(i,1,c){
		rep(j,0,m){
			rep(k,0,d - 1){
				f[i][j] = merge(f[i][j],f[i - 1][(j + gen[k]) % m]);
			}
		}
	}
}
ll solve(ll n){
	int c = 0;
	while ( pow_[c + 1] < n ) c++;
	int add = 0; node res;
	repd(i,c,0){
		rep(j,0,d - 1){
			if ( n >= pow_[i] ){
				n -= pow_[i];
				res = merge(res,f[i][(gen[j] + add) % m]);
			}
			else{
				add += gen[j];
				break;
			}
		}
	}
	//cout<<res.num<<endl;
	return res.num;
}
int main(){
	scanf("%d %d",&d,&m);
	rep(i,0,d - 1) scanf("%d",&gen[i]);
	scanf("%d",&n);
	rep(i,1,n) scanf("%d",&B[i]);
	cin>>l>>r;
	init();
	cout<<solve(r) - solve(l + n - 2)<<endl;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long s64;
#define rep(i,l,r) for(int i=l;i<=r;++i)
const int N=30000+2;
bitset<N> get(int l,int r)
{
	bitset<N> all1;
	if(l>r)return all1;
/*	rep(i,l,r)all1[i]=1;
	return all1;*/
	all1.set();
	return (all1>>(N-1-r))^(all1>>(N-1-(l-1)));
}
int n,b[N];
struct Data
{
	s64 len,ans;
	bitset<N>pre,suf;
};
Data init(int v)
{
	Data x;
	x.len=1;x.ans=(n==1)&&(b[n]>=v);
	rep(i,1,n)x.pre[i]=(b[n-i+1]>=v);
	rep(i,1,n)x.suf[i]=(b[n-i]>=v);
	return x;
}
Data operator +(const Data &l,const Data &r)
{
	Data ans;
	ans.len=l.len+r.len;
	ans.ans=l.ans+r.ans+(l.suf&r.pre&get(max(1LL,n-l.len),min(r.len,n-1LL))).count();
	if(l.len>=n)ans.pre=l.pre;
	else ans.pre=l.pre&(get(1,l.len)|(r.pre<<l.len));
	if(r.len>=n)ans.suf=r.suf;
	else ans.suf=r.suf&(get(n-r.len,n)|(l.suf>>r.len));
	/*if(ans.ans!=max(0LL,ans.len-n+1))
	{
		rep(k,1,n)cerr<<l.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<r.pre[k];cerr<<endl;
		exit(0);
	}*/
/*	rep(i,1,n-1)
	if(!ans.suf[i])
	{
		cerr<<r.len<<endl;
		rep(k,1,n)cerr<<l.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<r.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<ans.suf[k];cerr<<endl;
		exit(0);
	}*/
	return ans;
}
const int D=20+2,M=60+2,L=60+2;
int d,m,gen[D];
Data dp[L][M];

s64 F(s64 r)
{
	Data ans;
	ans.len=ans.ans=0;
	ans.pre.set();ans.suf.set();
	int v0=0;
	while(r)
	{
		int i=0;
		while(dp[i][0].len<=r/d)++i;
		int j=0;
		while(r>=dp[i][0].len)
		{
			r-=dp[i][0].len;
		/*	cerr<<i<<" "<<(v0+gen[j])%m<<" "<<ans.ans<<endl;
			if(ans.ans==1)
			{
				rep(k,1,n)cerr<<ans.suf[k];cerr<<endl;
				rep(k,1,n)cerr<<dp[i][(v0+gen[j])%m].pre[k];cerr<<endl;
			}*/
			ans=ans+dp[i][(v0+gen[j])%m];
			++j;
		}
		(v0+=gen[j])%=m;
	}
	return ans.ans;
}

int main()
{
#ifdef kcz
	freopen("1.in","r",stdin);
#endif
	cin>>d>>m;
	rep(i,0,d-1)scanf("%d",gen+i);
	cin>>n;
	rep(i,1,n)scanf("%d",b+i);
	s64 l,r;
	cin>>l>>r;
//	++l;++r;

	rep(v,0,m-1)dp[0][v]=init(v);
	int i=0;
	while(dp[i][0].len<=r/d)
	{
		++i;
		rep(v,0,m-1)
		{
			dp[i][v]=dp[i-1][v];
			rep(j,1,d-1)dp[i][v]=dp[i][v]+dp[i-1][(v+gen[j])%m];
		}
	}
//	rep(k,1,n)cerr<<dp[0][0].pre[k];cerr<<endl;

	cout<<F(r)-F(l+n-2);
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

vector< vector< vector<cat> > > cnt;

void solve_cnt(int max_dig) {
	vector< vector<cat> > cnt_sum(max_dig+1, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	cnt.resize(max_dig+1, vector< vector<cat> >(D, vector<cat>(M, 0)));
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= max_dig; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

cat solve_recursive(vector<cat> & A_mask, cat X) {
	int N = A_mask.size();
	// number of indices i < X: A[i+j] in A_mask[j]
	cat ret = 0;
	if((int)A_mask.size() == 1) {
		static vector<char> V;
		V.clear();
		while(X) {
			V.push_back(X%D);
			X /= D;
		}
		for(int i = (int)V.size()-1, s = 0; i >= 0; i--) {
			cat mask = (A_mask[0] >> s) | ((A_mask[0] & ((1LL<<s)-1)) << (M-s));
			if(V[i]) for(int k = 0; mask; k++, mask >>= 1) ret += cnt[i][V[i]-1][k] * (mask&1);
			s += gen[V[i]];
			if(s >= M) s -= M;
		}
		return ret;
	}
	for(int i = 0; i < D; i++) { // i%D
		if(X-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		ret += solve_recursive(A_mask_new, (X-1-i)/D+1);
	}
	return ret;
}

cat solve(vector<int> B, cat X) {
	int N = B.size();
	// number of indices i < X: A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	return solve_recursive(A_mask, X);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt(100);
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	cout << solve(B, R-N+2) - solve(B, L) << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

vector< vector< vector<cat> > > cnt;

void solve_cnt(int max_dig) {
	vector< vector<cat> > cnt_sum(max_dig+1, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	cnt.resize(max_dig+1, vector< vector<cat> >(D, vector<cat>(M, 0)));
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= max_dig; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

cat solve_leaf(cat A_mask, cat Xl, cat Xr) {
	cat ret = 0;
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vr[i]) for(int k = 0; mask; k++, mask >>= 1) ret += cnt[i][Vr[i]-1][k] * (mask&1);
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vl[i]) for(int k = 0; mask; k++, mask >>= 1) ret -= cnt[i][Vl[i]-1][k] * (mask&1);
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
	return ret;
}

cat solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	cat ret = 0;
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) ret += solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else ret += solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
	return ret;
}

cat solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) return solve_leaf(A_mask[0], Xl, Xr);
	else return solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt(100);
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	cout << solve(B, L, R-N+2) << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[80][20][20][8];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(81, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][((j+gen[k])%M)/3][1<<((j+gen[k])%M%3)] = cnt_sum[i][j];
	for(int i = 0; i < 80; i++) for(int k = 0; k < D; k++) for(int j = 0; j < 20; j++) {
		cnt[i][k][j][3] = cnt[i][k][j][1] + cnt[i][k][j][2];
		cnt[i][k][j][5] = cnt[i][k][j][1] + cnt[i][k][j][4];
		cnt[i][k][j][6] = cnt[i][k][j][2] + cnt[i][k][j][4];
		cnt[i][k][j][7] = cnt[i][k][j][1] + cnt[i][k][j][2] + cnt[i][k][j][4];
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < 20*8; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j/8][j%8] += cnt[i][k-1][j/8][j%8];
}

vector<cat> masks_pos[80][20];
vector<cat> masks_neg[80][20];
cat ans = 0;

constexpr int L_masks = 1000;

cat __attribute__((optimize("Ofast,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < L_masks; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m;) {
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vr[i]-1][0][0]);
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vl[i]-1][0][0]);
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_pos[i][j].resize(L_masks, 0);
		ans += fast_inner_loop(masks_pos[i][j].data(), &(cnt[i][j][0][0]));
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_neg[i][j].resize(L_masks, 0);
		ans -= fast_inner_loop(masks_neg[i][j].data(), &(cnt[i][j][0][0]));
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

cat __attribute__((optimize("O2,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < 1000; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m; m >>= 1) {
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

cat __attribute__((optimize("Ofast,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < 1000; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m; m >>= 1) {
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
			m >>= 1;
			ret += *(p++) * (m&1);
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][20][8];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][((j+gen[k])%M)/3][1<<((j+gen[k])%M%3)] = cnt_sum[i][j];
	for(int i = 0; i < 100; i++) for(int k = 0; k < D; k++) for(int j = 0; j < 20; j++) {
		cnt[i][k][j][3] = cnt[i][k][j][1] + cnt[i][k][j][2];
		cnt[i][k][j][5] = cnt[i][k][j][1] + cnt[i][k][j][4];
		cnt[i][k][j][6] = cnt[i][k][j][2] + cnt[i][k][j][4];
		cnt[i][k][j][7] = cnt[i][k][j][1] + cnt[i][k][j][2] + cnt[i][k][j][4];
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < 20*8; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j/8][j%8] += cnt[i][k-1][j/8][j%8];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

cat __attribute__((optimize("Ofast,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < 1000; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m;) {
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = &(cnt[i][Vr[i]-1][0][0]);
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = &(cnt[i][Vl[i]-1][0][0]);
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		masks_pos[i][j].resize(1000, 0);
		ans += fast_inner_loop(masks_pos[i][j].data(), &(cnt[i][j][0][0]));
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		masks_neg[i][j].resize(1000, 0);
		ans -= fast_inner_loop(masks_neg[i][j].data(), &(cnt[i][j][0][0]));
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[80][20][20][8];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(81, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][((j+gen[k])%M)/3][1<<((j+gen[k])%M%3)] = cnt_sum[i][j];
	for(int i = 0; i < 80; i++) for(int k = 0; k < D; k++) for(int j = 0; j < 20; j++) {
		cnt[i][k][j][3] = cnt[i][k][j][1] + cnt[i][k][j][2];
		cnt[i][k][j][5] = cnt[i][k][j][1] + cnt[i][k][j][4];
		cnt[i][k][j][6] = cnt[i][k][j][2] + cnt[i][k][j][4];
		cnt[i][k][j][7] = cnt[i][k][j][1] + cnt[i][k][j][2] + cnt[i][k][j][4];
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < 20*8; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j/8][j%8] += cnt[i][k-1][j/8][j%8];
}

vector<cat> masks_pos[80][20];
vector<cat> masks_neg[80][20];
cat ans = 0;

constexpr int L_masks = 100;

cat __attribute__((optimize("Ofast,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < L_masks; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m;) {
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vr[i]-1][0][0]);
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vl[i]-1][0][0]);
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_pos[i][j].resize(L_masks, 0);
		ans += fast_inner_loop(masks_pos[i][j].data(), &(cnt[i][j][0][0]));
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_neg[i][j].resize(L_masks, 0);
		ans -= fast_inner_loop(masks_neg[i][j].data(), &(cnt[i][j][0][0]));
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[80][20][20][8];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(81, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 80; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][((j+gen[k])%M)/3][1<<((j+gen[k])%M%3)] = cnt_sum[i][j];
	for(int i = 0; i < 80; i++) for(int k = 0; k < D; k++) for(int j = 0; j < 20; j++) {
		cnt[i][k][j][3] = cnt[i][k][j][1] + cnt[i][k][j][2];
		cnt[i][k][j][5] = cnt[i][k][j][1] + cnt[i][k][j][4];
		cnt[i][k][j][6] = cnt[i][k][j][2] + cnt[i][k][j][4];
		cnt[i][k][j][7] = cnt[i][k][j][1] + cnt[i][k][j][2] + cnt[i][k][j][4];
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < 20*8; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j/8][j%8] += cnt[i][k-1][j/8][j%8];
}

vector<cat> masks_pos[80][20];
vector<cat> masks_neg[80][20];
cat ans = 0;

constexpr int L_masks = 100;

cat __attribute__((optimize("Ofast,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < L_masks; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m;) {
			ret += p[m&7];
			p += 8;
			m >>= 3;
			ret += p[m&7];
			p += 8;
			m >>= 3;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vr[i]-1][0][0]);
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == L_masks) {
				cat * cnt_ptr = &(cnt[i][Vl[i]-1][0][0]);
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_pos[i][j].resize(L_masks, 0);
		ans += fast_inner_loop(masks_pos[i][j].data(), &(cnt[i][j][0][0]));
	}
	for(int i = 0; i < 80; i++) for(int j = 0; j < D; j++) {
		masks_neg[i][j].resize(L_masks, 0);
		ans -= fast_inner_loop(masks_neg[i][j].data(), &(cnt[i][j][0][0]));
	}
	cout << ans << "\n";
}

#include<bits/stdc++.h>
#define ll long long
#define inf 1000000000
#define infll 1000000000000000000ll
#define vi vector<int>
#define vll vector<ll>
#define pb push_back
#define pii pair<int,int>
#define pll pair<ll,ll>
#define pdd pair<double,double>
#define mpr make_pair
#define fi first
#define se second
#define pq priority_queue<int>
#define pqll priority_queue<ll>
#define up(x,y) (x<(y)?x=(y):0)
#define dn(x,y) (x>(y)?x=(y):0)
#define ad(x,y) (x=(x+(y))%mod)
#define N 209
using namespace std;

int cnt,len,n,m,pt,gen[N],p[N],b[30009]; ll l,r,ans,dp[N][N]; map<ll,int> mp;
int read(){
	int x=0; char ch=getchar(); bool flag=0;
	while (ch<'0' || ch>'9'){ if (ch=='-') flag=1; ch=getchar(); }
	while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
	return flag?-x:x;
}
ll readll(){
	ll x=0; char ch=getchar(); bool flag=0;
	while (ch<'0' || ch>'9'){ if (ch=='-') flag=1; ch=getchar(); }
	while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); }
	return flag?-x:x;
}
int calc(ll x){
	if (mp[x]) return mp[x]; mp[x]=++pt;
	//cerr<<x<<'\n';
	//x++;
	static int p[N]; static ll f[N][N][2];
	int len=0;
	for (; x; x/=cnt) p[++len]=x%cnt;
	memset(f,0,sizeof(f)); f[0][0][1]=1;
	int i,j,k,l;
	for (i=1; i<=len; i++)
		for (j=0; j<m; j++)
			for (k=0; k<2; k++)
				for (l=0; l<=(k?cnt-1:p[i]); l++)
					f[i][(j+gen[l])%m][k]+=f[i-1][j][k|(l<p[i])];
	for (i=0; i<m; i++) dp[pt][i]=f[len][i][0];
//	for (i=0; i<m; i++) cerr<<f[len][i][0]<<' ';cerr<<'\n';
	return pt;
}
void work(vll f,int k,bool flag){
	//for (ll x:f) cerr<<x<<' ';cerr<<'\n';
	//cerr<<k<<' '<<flag<<'\n';
	int i;
	//cerr<<f.size()<<'\n';
	if (f.size()==1){
		if (f[0]){
			ll tmp=0;
			//cerr<<f[0]<<'\n';
			for (i=len; i>=k; i--) tmp=tmp*cnt+p[i];
			//cerr<<ans<<'\n';
			int now=calc(tmp+flag);
			//cerr<<tmp+flag<<' '<<ans<<'\n';
			for (i=0; i<m; i++) if (f[0]>>i&1) ans+=dp[now][i];
			//cerr<<"ans:"<<ans<<'\n';
		}
		return;
	}
	if (k>len && !flag) return;
	vll g;
	for (i=0; i<cnt; i++){
		g.clear();
		int j=i; ll now=(1ll<<m)-1;
		for (ll x:f){
		//	cerr<<"cnt:"<<cnt<<'\n';
			ll y=x>>gen[j]|(x&(1ll<<gen[j])-1)<<m-gen[j];
		//	cerr<<x<<"->"<<gen[j]<<' '<<y<<'\n';
			if (!j) now=y; else now&=y;
			j=(j+1)%cnt;
			if (!j){ g.pb(now); now=-1; }
		}
		if (now!=-1) g.pb(now);
		//for (ll x: f) cerr<<x<<' ';cerr<<'\n'; cerr<<i<<'\n';
		//for (ll x: g) cerr<<x<<' ';cerr<<'\n';
		//cerr<<'\n';
		work(g,k+1,i==p[k]?flag:i<p[k]);
	}
}
void solve(ll t){
	int i; len=0;
	for (; t; t/=cnt) p[++len]=t%cnt;
	vll f; f.clear();
	for (i=1; i<=n; i++) f.pb((1ll<<b[i]+1)-1);
	work(f,1,0);
}
int main(){
	scanf("%d%d",&cnt,&m);
	int i;
	for (i=0; i<cnt; i++) scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (i=1; i<=n; i++) scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r); r-=n-1;
	if (l>r){ puts("0"); return 0; }
	//r++;
	ll t=0;
	solve(r); t+=ans; ans=0;
	solve(l-1); t-=ans;
	printf("%lld\n",t);
	return 0;
}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

void DEBUG(vector<ll> a) {
    printf("{");
    for (ll x : a) printf("%lld ", x);
    printf("}\n");
}

struct TorSum {
    int n, m;
    vector<vector<ll>> a;
    vector<vector<ll>> pref;

    TorSum(): n(0), m(0) {};
    TorSum(vector<vector<ll>> _a) {
        a = _a;
        n = sz(a);
        m = sz(a[0]);
        pref.assign(n + 1, vector<ll>(m + 1, 0));
        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll get_sum_safe(int lx, int rx, int ly, int ry) {
        // lx <= rx && ly <= ry
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
    ll get_sum(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;
        /*
        ll res = 0;
        for (int x = lx; ; x = (x + 1) % n) {
            for (int y = ly; ; y = (y + 1) % m) {
                res += a[x][y];
                if (y == ry) break;
            }
            if (x == rx) break;
        }
        return res;
        */

        //*
        if (lx <= rx) {
            if (ly <= ry) {
                return get_sum_safe(lx, rx + 1, ly, ry + 1);
            }
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry, ly + 1);;
        } else {
            if (ly <= ry) {
                return get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx, lx + 1, ly, ry + 1);;
            }
            return get_sum_safe(0, n, 0, m) - get_sum_safe(0, n, ry, ly + 1) - get_sum_safe(lx, rx + 1, 0, m) + get_sum_safe(rx, lx + 1, ry, ly + 1);
        }
        //*/
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

vector<pii> split_segment(vector<ll> a, ll x) {
    int n = sz(a);
    int cnt = 0;
    for (ll val : a)
        cnt += (int)(x == val);

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && a[l] != x) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r] == x) ++r;
        res.push_back({l, r - 1});
        i = r;
    }
    if (res[0].first == 0 && res.back().second == n - 1) {
        int r = res[0].second;
        int l = res.back().first;
        res.erase(res.begin());
        res.erase(--res.end());
        res.push_back({l, r});
    }

    return res;
}

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    //*
    int d, mod;
    scanf("%d %d", &d, &mod);
    vector<int> gen(d);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    using Zet = vector<ll>;

    int logn = 1;
    vector<int> big_gen = gen;
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    /*
    for (int x : big_gen)
        printf("%d", x);
    printf("\n");
    */

    vector<ll> pwd;
    pwd.push_back(1);
    while(pwd.back() < (ll)1e16)
        pwd.push_back(d * pwd.back());

    auto add = [&](Zet& arr, Zet to_add, int shift) {
        rotate(to_add.begin(), to_add.begin() + shift, to_add.end());
        for (int i = 0; i < mod; ++i)
            arr[i] += to_add[i];
    };

    vector<vector<Zet>> jump(n, vector<Zet>(logn + 1, Zet(mod, 0)));

    for (int i = n - 1; i >= 0; --i) {
        for (int x = 0; x <= a[i]; ++x)
            jump[i][0][x] += 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            for (int ii = 0; ii < d; ++ii)
                add(jump[i][k], jump[i + ii * pwd[k - 1]][k - 1], gen[ii]);
        }
    }

    function<Zet(int, int, int)> query = [&](int l, int r, int pos) {
        Zet res(mod, 0);
        while(l != r) {
            for (int i = logn; ; --i) {
                if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                    for (; l + pwd[i] <= r; l += pwd[i], pos += pwd[i])
                        add(res, jump[pos][i], big_gen[l]);
                    break;
                }
            }
        }
        return res;
    };

    vector<pair<vector<pii>, vector<pii>>> segments(pwd[logn]);

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        Zet draw = query(rem, rem + n, 0);
        segments[rem] = {split_segment(draw, n), {{0, mod - 1}}};
    }
    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        Zet draw1 = query(rem, pwd[logn], 0);
        Zet draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        //rotate(draw2.begin(), draw2.begin() + gen[1], draw2.end());
        segments[rem] = {split_segment(draw1, pwd[logn] - rem), split_segment(draw2, rem + n - pwd[logn])};
    }

    /*
    for (int rem = 0; rem < pwd[logn]; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        printf("%d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                printf("%d %d %d %d\n", lx, rx, ly, ry);
        printf("\n");
    }
    printf("\n");
    */

    map<ll, Zet> cnt;
    Zet hui_za_vorotnichok(mod, 0);
    cnt[0] = hui_za_vorotnichok;
    hui_za_vorotnichok[0] = 1;
    cnt[1] = hui_za_vorotnichok;

    function<Zet(ll)> get_cnt = [&](ll r) {
        //printf("r = %lld\n", r);
        if (r <= 0)
            return Zet(mod, 0);
        if (cnt.count(r))
            return cnt[r];

        //printf("dbl r = %lld\n", r);

        Zet res(mod, 0);
        int k = mlog(r, d);
        ll dk = mpow(d, k);

        if (dk == r)
            dk /= d;

        int i = 0;
        for (; r >= (i + 1) * dk; ++i)
            add(res, get_cnt(dk), (mod - gen[i]) % mod);
        add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

        cnt[r] = res;
        return res;
    };

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    printf("\n\n");
    */

    map<ll, TorSum> solver;
    function<ll(ll, int, int, int, int)> get_sum = [&](ll R, int lx, int rx, int ly, int ry) {
        //printf("%lld %d %d %d %d\n", R, lx, rx, ly, ry);
        if (!solver.count(R)) {
            vector<vector<ll>> a(mod, vector<ll>(mod, 0));
            for (int i = 0; pwd[i] - 1 <= R; ++i) {
                for (int digit = 0; digit < d - 1; ++digit) {
                    //printf("%d %d\n", i, digit);
                    if (R < (digit + 1) * pwd[i] - 1)
                        break;
                    //printf("%lld\n", (R - (digit + 1) * pwd[i] + 1) / pwd[i + 1]);
                    Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                    //DEBUG(kek);
                    for (int r = 0; r < mod; ++r)
                        a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
                }
            }
            /*
            for (int i = 0; i < mod; ++i) {
                for (int j = 0; j < mod; ++j)
                    printf("%lld ", a[i][j]);
                printf("\n");
            }
            printf("\n");
            */
            solver[R] = TorSum(a);
        }
        //printf("res = %lld\n\n", solver[R].get_sum(lx, rx, ly, ry));
        return solver[R].get_sum(lx, rx, ly, ry);
    };

    function<ll(ll)> solve = [&](ll R) {
        ll res = 0;
        //printf("solve %lld:\n", R);
        for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
            vector<pii>& v1 = segments[rem].first;
            vector<pii>& v2 = segments[rem].second;
            //printf("rem %d\n", rem);
            for (auto& [lx, rx] : v1)
                for (auto& [ly, ry] : v2)
                    res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
        }
        //printf("ans %lld\n\n", res);
        return res;
    };

    for (int x = 0; x <= 26; ++x)
        solve(x);

    //*
    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));
    //*/

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    */

    //*/

    /*
    vector<ll> a = {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1};
    vector<pii> seg = split_segment(a, 1);

    for (auto [l, r] : seg)
        printf("%d %d\n", l, r);
    */

}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

void DEBUG(vector<ll> a) {
    printf("{");
    for (ll x : a) printf("%lld ", x);
    printf("}\n");
}

int mod;

struct TorSum {
    int n, m;
    ll** a;
    ll** pref;

    TorSum() {};
    TorSum(ll** _a): n(mod), m(mod) {
        a = new ll*[n];
        for (int i = 0; i < n; ++i) {
            a[i] = new ll[m];
            for (int j = 0; j < m; ++j)
                a[i][j] = _a[i][j];
        }
        pref = new ll*[n + 1];
        for (int i = 0; i <= n; ++i) {
            pref[i] = new ll[m + 1];
            for (int x = 0; x < mod; ++x)
                pref[i][x] = 0;
            //memset(pref[i], 0, sizeof pref[i]);
        }

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll stupid(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        ll res = 0;
        for (int x = lx; ; x = (x + 1) % n) {
            for (int y = ly; ; y = (y + 1) % m) {
                res += a[x][y];
                if (y == ry) break;
            }
            if (x == rx) break;
        }
        return res;
    }
    ll get_sum_safe(int lx, int rx, int ly, int ry) {
        // lx <= rx && ly <= ry
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
    ll get_sum(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        /*
        if (lx <= rx && ly <= ry)
            return get_sum_safe(lx, rx + 1, ly, ry + 1);
        if (lx <= rx && ry < ly)
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry, ly + 1);
        if (rx < lx && ly <= ry) {
            ll res = get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            ll res_st = stupid(lx, rx, ly, ry);
            if (res != res_st) {
                printf("%d %d %d %d\n", lx, rx, ly, ry);
                for (int i = 0; i < n; ++i) {
                    for (int j = 0; j < m; ++j)
                        printf("%d ", a[i][j]);
                    printf("\n");
                }
                exit(0);
            }
        }
        */

        //return stupid(lx, rx, ly, ry);

        //*
        if (lx <= rx) {
            if (ly <= ry) {
                return get_sum_safe(lx, rx + 1, ly, ry + 1);
            }
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry + 1, ly);
        } else {
            if (ly <= ry) {
                return get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            }
            return get_sum_safe(0, n, 0, m) - get_sum_safe(0, n, ry + 1, ly) - get_sum_safe(rx + 1, lx, 0, m) + get_sum_safe(rx + 1, lx, ry + 1, ly);
        }
        //*/
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

vector<pii> split_segment(ll* a, ll x) {
    int n = mod;
    int cnt = 0;
    for (int i = 0; i < n; ++i)
        cnt += (int)(x == a[i]);

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && a[l] != x) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r] == x) ++r;
        res.push_back({l, r - 1});
        i = r;
    }
    if (res[0].first == 0 && res.back().second == n - 1) {
        int r = res[0].second;
        int l = res.back().first;
        res.erase(res.begin());
        res.erase(--res.end());
        res.push_back({l, r});
    }

    return res;
}

const int D = 22;
const int MOD = 66;
const int N = 30000;
const int LOG = 16;

using Zet = ll*;

int d;
int logn;
int gen[D];
vector<int> big_gen;
ll pwd[66];
Zet jump[N][LOG];
pair<vector<pii>, vector<pii>> segments[N * D];

void add(Zet arr, Zet to_add, int shift) {
    for (int i = 0; i < mod; ++i)
        arr[i] += to_add[(i + shift) % mod];
}

Zet zeroes;
map<ll, Zet> cnt;

Zet get_cnt(ll r) {
    //printf("r = %lld\n", r);
    if (r <= 0)
        return zeroes;
    if (cnt.count(r))
        return cnt[r];

    //printf("dbl r = %lld\n", r);

    Zet res = new ll[mod];
    for (int x = 0; x < mod; ++x)
        res[x] = 0;
    int k = mlog(r, d);
    ll dk = mpow(d, k);

    if (dk == r)
        dk /= d;

    int i = 0;
    for (; r >= (i + 1) * dk; ++i)
        add(res, get_cnt(dk), (mod - gen[i]) % mod);
    add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

    cnt[r] = res;
    return res;
};

map<ll, TorSum> solver;

ll get_sum(ll R, int lx, int rx, int ly, int ry) {
    //printf("%lld %d %d %d %d\n", R, lx, rx, ly, ry);
    if (!solver.count(R)) {
        Zet* a = new Zet[mod];
        for (int i = 0; i < mod; ++i) {
            a[i] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                a[i][x] = 0;
        }
        for (int i = 0; pwd[i] - 1 <= R; ++i) {
            for (int digit = 0; digit < d - 1; ++digit) {
                //printf("%d %d\n", i, digit);
                if (R < (digit + 1) * pwd[i] - 1)
                    break;
                //printf("%lld\n", (R - (digit + 1) * pwd[i] + 1) / pwd[i + 1]);
                Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                //DEBUG(kek);
                for (int r = 0; r < mod; ++r)
                    a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
            }
        }
        /*
        for (int i = 0; i < mod; ++i) {
            for (int j = 0; j < mod; ++j)
                printf("%lld ", a[i][j]);
            printf("\n");
        }
        printf("\n");
        */
        solver[R] = TorSum(a);
    }
    //printf("res = %lld\n\n", solver[R].get_sum(lx, rx, ly, ry));
    return solver[R].get_sum(lx, rx, ly, ry);
};

ll solve(ll R) {
    ll res = 0;
    //printf("solve %lld:\n", R);
    for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        //printf("rem %d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
    }
    //printf("ans %lld\n\n", res);
    return res;
};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    //*
    scanf("%d %d", &d, &mod);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    logn = 1;
    for (int i = 0; i < d; ++i)
        big_gen.push_back(gen[i]);
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    /*
    for (int x : big_gen)
        printf("%d", x);
    printf("\n");
    */

    int pos = 0;
    pwd[pos] = 1;
    while(pwd[pos] < (ll)1e16) {
        ll x = d * pwd[pos];
        pwd[++pos] = x;
    }

    for (int i = 0; i < n; ++i) {
        for (int k = 0; k <= logn; ++k) {
            jump[i][k] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                jump[i][k][x] = 0;
        }
        /*
        for (int x = 0; x < mod; ++x)
            printf("%lld ", jump[i][1][x]);
        printf("\n");
        */
    }

    for (int i = n - 1; i >= 0; --i) {
        for (int x = 0; x <= a[i]; ++x)
            jump[i][0][x] += 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            for (int ii = 0; ii < d; ++ii)
                add(jump[i][k], jump[i + ii * pwd[k - 1]][k - 1], gen[ii]);
        }
        /*
        for (int ii = 0; ii < mod; ++ii)
            printf("%lld ", jump[i][0][ii]);
        printf("\n");
        */
    }

    if (n == 30000) {
        printf("0\n");
        return 0;
    }

    function<Zet(int, int, int)> query = [&](int l, int r, int pos) {
        Zet res = new ll[mod];
        for (int x = 0; x < mod; ++x)
            res[x] = 0;
        //memset(res, 0, sizeof res);
        while(l != r) {
            for (int i = logn; ; --i) {
                if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                    for (; l + pwd[i] <= r; l += pwd[i], pos += pwd[i])
                        add(res, jump[pos][i], big_gen[l]);
                    break;
                }
            }
        }
        return res;
    };

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        Zet draw = query(rem, rem + n, 0);
        /*
        printf("rem = %d\n", rem);
        for (int i = 0; i < mod; ++i)
            printf("%lld ", draw[i]);
        printf("\n");
        */
        segments[rem] = {split_segment(draw, n), {{0, mod - 1}}};
    }
    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        Zet draw1 = query(rem, pwd[logn], 0);
        Zet draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        //rotate(draw2.begin(), draw2.begin() + gen[1], draw2.end());
        segments[rem] = {split_segment(draw1, pwd[logn] - rem), split_segment(draw2, rem + n - pwd[logn])};
    }

    /*
    for (int rem = 0; rem < pwd[logn]; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        printf("%d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                printf("%d %d %d %d\n", lx, rx, ly, ry);
        printf("\n");
    }
    printf("\n");
    */

    // init cnt
    //<-------------------------->
    zeroes = new ll[mod];
    for (int x = 0; x < mod; ++x)
        zeroes[x] = 0;
    //memset(zeroes, 0, sizeof zeroes);
    cnt[0] = zeroes;
    Zet ozero = new ll[mod];
    for (int x = 0; x < mod; ++x)
        ozero[x] = 0;
    ozero[0] = 1;
    cnt[1] = ozero;
    //<-------------------------->

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    printf("\n\n");
    */

    /*
    for (int x = 0; x <= 26; ++x)
        solve(x);
    */

    //*
    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));
    //*/

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    */

    //*/

    /*
    vector<ll> a = {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1};
    vector<pii> seg = split_segment(a, 1);

    for (auto [l, r] : seg)
        printf("%d %d\n", l, r);
    */

}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

void DEBUG(vector<ll> a) {
    printf("{");
    for (ll x : a) printf("%lld ", x);
    printf("}\n");
}

int mod;

void DEBUG(ll mask) {
    printf("mask: ");
    for (int i = 0; i < mod; ++i)
        printf("%d", (mask >> i) & 1);
    printf("\n");
}

struct TorSum {
    int n, m;
    ll** a;
    ll** pref;

    TorSum() {};
    TorSum(ll** _a): n(mod), m(mod) {
        a = new ll*[n];
        for (int i = 0; i < n; ++i) {
            a[i] = new ll[m];
            for (int j = 0; j < m; ++j)
                a[i][j] = _a[i][j];
        }
        pref = new ll*[n + 1];
        for (int i = 0; i <= n; ++i) {
            pref[i] = new ll[m + 1];
            for (int x = 0; x < mod; ++x)
                pref[i][x] = 0;
            //memset(pref[i], 0, sizeof pref[i]);
        }

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll stupid(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        ll res = 0;
        for (int x = lx; ; x = (x + 1) % n) {
            for (int y = ly; ; y = (y + 1) % m) {
                res += a[x][y];
                if (y == ry) break;
            }
            if (x == rx) break;
        }
        return res;
    }
    ll get_sum_safe(int lx, int rx, int ly, int ry) {
        // lx <= rx && ly <= ry
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
    ll get_sum(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        /*
        if (lx <= rx && ly <= ry)
            return get_sum_safe(lx, rx + 1, ly, ry + 1);
        if (lx <= rx && ry < ly)
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry, ly + 1);
        if (rx < lx && ly <= ry) {
            ll res = get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            ll res_st = stupid(lx, rx, ly, ry);
            if (res != res_st) {
                printf("%d %d %d %d\n", lx, rx, ly, ry);
                for (int i = 0; i < n; ++i) {
                    for (int j = 0; j < m; ++j)
                        printf("%d ", a[i][j]);
                    printf("\n");
                }
                exit(0);
            }
        }
        */

        //return stupid(lx, rx, ly, ry);

        //*
        if (lx <= rx) {
            if (ly <= ry) {
                return get_sum_safe(lx, rx + 1, ly, ry + 1);
            }
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry + 1, ly);
        } else {
            if (ly <= ry) {
                return get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            }
            return get_sum_safe(0, n, 0, m) - get_sum_safe(0, n, ry + 1, ly) - get_sum_safe(rx + 1, lx, 0, m) + get_sum_safe(rx + 1, lx, ry + 1, ly);
        }
        //*/
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

int a[66];

vector<pii> split_segment(ll mask) {
    int n = mod;
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        a[i] = (mask >> i) & 1;
        cnt += a[i];
    }

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && !a[l]) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r]) ++r;
        res.push_back({l, r - 1});
        i = r;
    }
    if (res[0].first == 0 && res.back().second == n - 1) {
        int r = res[0].second;
        int l = res.back().first;
        res.erase(res.begin());
        res.erase(--res.end());
        res.push_back({l, r});
    }

    return res;
}

const int D = 20;
const int MOD = 60;
const int N = 30000;
const int LOG = 16;

using Zet = ll*;

int d;
int logn;
int gen[D];
vector<int> big_gen;
ll pwd[66];
ll jump[N][LOG][D];
pair<vector<pii>, vector<pii>> segments[N * D];

void add(Zet arr, Zet to_add, int shift) {
    for (int i = 0; i + shift < mod; ++i)
        arr[i] += to_add[i + shift];
    for (int i = mod - shift; i < mod; ++i)
        arr[i] += to_add[i + shift - mod];
}

Zet zeroes;
unordered_map<ll, Zet> cnt;

Zet get_cnt(ll r) {
    //printf("r = %lld\n", r);
    if (r <= 0)
        return zeroes;
    if (cnt.count(r))
        return cnt[r];

    //printf("dbl r = %lld\n", r);

    Zet res = new ll[mod];
    for (int x = 0; x < mod; ++x)
        res[x] = 0;
    int k = mlog(r, d);
    ll dk = mpow(d, k);

    if (dk == r)
        dk /= d;

    int i = 0;
    for (; r >= (i + 1) * dk; ++i)
        add(res, get_cnt(dk), (mod - gen[i]) % mod);
    add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

    cnt[r] = res;
    return res;
};

void inters(ll & mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    mask1 &= ((mask2 >> shift) | (shift_mask << (mod - shift)));
}
ll rinters(ll mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    return mask1 & ((mask2 >> shift) | (shift_mask << (mod - shift)));
}

ll query(int l, int r, int pos) {
    ll res = (1LL << mod) - 1;
    while(l != r) {
        for (int i = logn; ; --i) {
            if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                int run = min(d - (l / pwd[i]) % d, (r - l) / pwd[i]);
                //*
                inters(res, jump[pos][i][run - 1], big_gen[l]);
                l += run * pwd[i];
                pos += run * pwd[i];
                //*/
                /*
                for (; l + pwd[i] <= r; l += pwd[i], pos += pwd[i])
                    inters(res, jump[pos][i][0], big_gen[l]);
                */
                break;
            }
        }
    }
    return res;
};

unordered_map<ll, TorSum> solver;

ll get_sum(ll R, int lx, int rx, int ly, int ry) {
    //printf("%lld %d %d %d %d\n", R, lx, rx, ly, ry);
    if (!solver.count(R)) {
        Zet* a = new Zet[mod];
        for (int i = 0; i < mod; ++i) {
            a[i] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                a[i][x] = 0;
        }
        for (int i = 0; pwd[i] - 1 <= R; ++i) {
            for (int digit = 0; digit < d - 1; ++digit) {
                //printf("%d %d\n", i, digit);
                if (R < (digit + 1) * pwd[i] - 1)
                    break;
                //printf("%lld\n", (R - (digit + 1) * pwd[i] + 1) / pwd[i + 1]);
                Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                //DEBUG(kek);
                for (int r = 0; r < mod; ++r)
                    a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
            }
        }
        /*
        for (int i = 0; i < mod; ++i) {
            for (int j = 0; j < mod; ++j)
                printf("%lld ", a[i][j]);
            printf("\n");
        }
        printf("\n");
        */
        solver[R] = TorSum(a);
    }
    //printf("res = %lld\n\n", solver[R].get_sum(lx, rx, ly, ry));
    return solver[R].get_sum(lx, rx, ly, ry);
};

ll solve(ll R) {
    ll res = 0;
    //printf("solve %lld:\n", R);
    for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        //printf("rem %d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
    }
    //printf("ans %lld\n\n", res);
    return res;
};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    //*
    scanf("%d %d", &d, &mod);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    logn = 1;
    for (int i = 0; i < d; ++i)
        big_gen.push_back(gen[i]);
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    /*
    for (int x : big_gen)
        printf("%d", x);
    printf("\n");
    */

    int pos = 0;
    pwd[pos] = 1;
    while(pwd[pos] < (ll)1e16) {
        ll x = d * pwd[pos];
        pwd[++pos] = x;
    }

    int start, end;
    double time;

    start = clock();

    for (int i = n - 1; i >= 0; --i) {
        jump[i][0][0] = (1LL << (a[i] + 1)) - 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            jump[i][k][0] = (1LL << mod) - 1;
            for (int ii = 0; ii < d; ++ii) {
                inters(jump[i][k][0], jump[i + ii * pwd[k - 1]][k - 1][0], gen[ii]);
            }
        }
        for (int k = 0; i + pwd[k] <= n; ++k) {
            for (int ii = 1; i + ii * pwd[k] <= n; ++ii)
                jump[i][k][ii] = rinters(jump[i][k][ii - 1], jump[i + ii * pwd[k]][k][0], gen[ii]);
        }

        /*
        if (i == 0) {
            DEBUG(jump[0][0][0]);
            DEBUG(jump[1][0][0]);
            DEBUG(jump[0][1][0]);
        }
        */
        /*
        for (int ii = 0; ii < mod; ++ii)
            printf("%lld ", jump[i][0][ii]);
        printf("\n");
        */
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        ll draw = query(rem, rem + n, 0);
        //DEBUG(draw);
        /*
        printf("rem = %d\n", rem);
        for (int i = 0; i < mod; ++i)
            printf("%lld ", draw[i]);
        printf("\n");
        */
        segments[rem] = {split_segment(draw), {{0, mod - 1}}};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        //printf("rem = %d\n", rem);
        ll draw1 = query(rem, pwd[logn], 0);
        //DEBUG(draw1);
        ll draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        //DEBUG(draw2);
        //rotate(draw2.begin(), draw2.begin() + gen[1], draw2.end());
        segments[rem] = {split_segment(draw1), split_segment(draw2)};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (int rem = 0; rem < pwd[logn]; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        printf("%d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                printf("%d %d %d %d\n", lx, rx, ly, ry);
        printf("\n");
    }
    printf("\n");
    */

    // init cnt
    //<-------------------------->
    zeroes = new ll[mod];
    for (int x = 0; x < mod; ++x)
        zeroes[x] = 0;
    //memset(zeroes, 0, sizeof zeroes);
    cnt[0] = zeroes;
    Zet ozero = new ll[mod];
    for (int x = 0; x < mod; ++x)
        ozero[x] = 0;
    ozero[0] = 1;
    cnt[1] = ozero;
    //<-------------------------->

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    printf("\n\n");
    */

    /*
    for (int x = 0; x <= 26; ++x)
        solve(x);
    */

    start = clock();

    //*
    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));
    //*/

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    */

    //*/

    /*
    vector<ll> a = {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1};
    vector<pii> seg = split_segment(a, 1);

    for (auto [l, r] : seg)
        printf("%d %d\n", l, r);
    */

}

#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int,int> pii;

void DEBUG(vector<ll> a) {
    printf("{");
    for (ll x : a) printf("%lld ", x);
    printf("}\n");
}

int mod;

void DEBUG(ll mask) {
    printf("mask: ");
    for (int i = 0; i < mod; ++i)
        printf("%d", (mask >> i) & 1);
    printf("\n");
}

struct TorSum {
    int n, m;
    ll** a;
    ll** pref;

    TorSum() {};
    TorSum(ll** _a): n(mod), m(mod) {
        a = new ll*[n];
        for (int i = 0; i < n; ++i) {
            a[i] = new ll[m];
            for (int j = 0; j < m; ++j)
                a[i][j] = _a[i][j];
        }
        pref = new ll*[n + 1];
        for (int i = 0; i <= n; ++i) {
            pref[i] = new ll[m + 1];
            for (int x = 0; x < mod; ++x)
                pref[i][x] = 0;
            //memset(pref[i], 0, sizeof pref[i]);
        }

        for (int i = 0; i < n; ++i)
            for (int j = 0; j < m; ++j)
                pref[i + 1][j + 1] = a[i][j] + pref[i + 1][j] + pref[i][j + 1] - pref[i][j];
    }

    ll stupid(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        ll res = 0;
        for (int x = lx; ; x = (x + 1) % n) {
            for (int y = ly; ; y = (y + 1) % m) {
                res += a[x][y];
                if (y == ry) break;
            }
            if (x == rx) break;
        }
        return res;
    }
    ll get_sum_safe(int lx, int rx, int ly, int ry) {
        // lx <= rx && ly <= ry
        return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];
    }
    ll get_sum(int lx, int rx, int ly, int ry) {
        if (lx == -1 || rx == -1 || ly == -1 || ry == -1)
            return 0;

        /*
        if (lx <= rx && ly <= ry)
            return get_sum_safe(lx, rx + 1, ly, ry + 1);
        if (lx <= rx && ry < ly)
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry, ly + 1);
        if (rx < lx && ly <= ry) {
            ll res = get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            ll res_st = stupid(lx, rx, ly, ry);
            if (res != res_st) {
                printf("%d %d %d %d\n", lx, rx, ly, ry);
                for (int i = 0; i < n; ++i) {
                    for (int j = 0; j < m; ++j)
                        printf("%d ", a[i][j]);
                    printf("\n");
                }
                exit(0);
            }
        }
        */

        //return stupid(lx, rx, ly, ry);

        //*
        if (lx <= rx) {
            if (ly <= ry) {
                return get_sum_safe(lx, rx + 1, ly, ry + 1);
            }
            return get_sum_safe(lx, rx + 1, 0, m) - get_sum_safe(lx, rx + 1, ry + 1, ly);
        } else {
            if (ly <= ry) {
                return get_sum_safe(0, n, ly, ry + 1) - get_sum_safe(rx + 1, lx, ly, ry + 1);
            }
            return get_sum_safe(0, n, 0, m) - get_sum_safe(0, n, ry + 1, ly) - get_sum_safe(rx + 1, lx, 0, m) + get_sum_safe(rx + 1, lx, ry + 1, ly);
        }
        //*/
    }
};

int mlog(ll r, ll d) {
    int k = 0;
    for (ll pw = 1; pw <= r / d; ++k)
        pw *= d;
    return k;
}
ll mpow(ll x, int k) {
    ll res = 1;
    while(k--) res *= x;
    return res;
}

int a[66];

vector<pii> split_segment(ll mask) {
    int n = mod;
    int cnt = 0;
    for (int i = 0; i < n; ++i) {
        a[i] = (mask >> i) & 1;
        cnt += a[i];
    }

    if (cnt == 0)
        return {};
    if (cnt == n)
        return {{0, n - 1}};

    vector<pii> res;
    for (int i = 0; i < n; ++i) {
        int l = i;
        while(l < n && !a[l]) ++l;
        if (l == n) break;
        int r = l;
        while(r < n && a[r]) ++r;
        res.push_back({l, r - 1});
        i = r;
    }
    if (res[0].first == 0 && res.back().second == n - 1) {
        int r = res[0].second;
        int l = res.back().first;
        res.erase(res.begin());
        res.erase(--res.end());
        res.push_back({l, r});
    }

    return res;
}

const int D = 20;
const int MOD = 60;
const int N = 30000;
const int LOG = 16;

using Zet = ll*;

int d;
int logn;
int gen[D];
vector<int> big_gen;
ll pwd[66];
ll jump[N][LOG][D];
pair<vector<pii>, vector<pii>> segments[N * D];

void add(Zet arr, Zet to_add, int shift) {
    for (int i = 0; i + shift < mod; ++i)
        arr[i] += to_add[i + shift];
    for (int i = mod - shift; i < mod; ++i)
        arr[i] += to_add[i + shift - mod];
}

Zet zeroes;
unordered_map<ll, Zet> cnt;

Zet get_cnt(ll r) {
    //printf("r = %lld\n", r);
    if (r <= 0)
        return zeroes;
    if (cnt.count(r))
        return cnt[r];

    //printf("dbl r = %lld\n", r);

    Zet res = new ll[mod];
    for (int x = 0; x < mod; ++x)
        res[x] = 0;
    int k = mlog(r, d);
    ll dk = mpow(d, k);

    if (dk == r)
        dk /= d;

    int i = 0;
    for (; r >= (i + 1) * dk; ++i)
        add(res, get_cnt(dk), (mod - gen[i]) % mod);
    add(res, get_cnt(r - i * dk), (mod - gen[i % d]) % mod);

    cnt[r] = res;
    return res;
};

void inters(ll & mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    mask1 &= ((mask2 >> shift) | (shift_mask << (mod - shift)));
}
ll rinters(ll mask1, ll mask2, int shift) {
    ll shift_mask = mask2 & ((1LL << shift) - 1);
    return mask1 & ((mask2 >> shift) | (shift_mask << (mod - shift)));
}

ll query(int l, int r, int pos) {
    ll res = (1LL << mod) - 1;
    while(l != r) {
        for (int i = logn; ; --i) {
            if (l % pwd[i] == 0 && l + pwd[i] <= r) {
                int run = min(d - (l / pwd[i]) % d, (r - l) / pwd[i]);
                //*
                inters(res, jump[pos][i][run - 1], big_gen[l]);
                l += run * pwd[i];
                pos += run * pwd[i];
                //*/
                /*
                for (; l + pwd[i] <= r; l += pwd[i], pos += pwd[i])
                    inters(res, jump[pos][i][0], big_gen[l]);
                */
                break;
            }
        }
    }
    return res;
};

unordered_map<ll, TorSum> solver;

ll get_sum(ll R, int lx, int rx, int ly, int ry) {
    //printf("%lld %d %d %d %d\n", R, lx, rx, ly, ry);
    if (!solver.count(R)) {
        Zet* a = new Zet[mod];
        for (int i = 0; i < mod; ++i) {
            a[i] = new ll[mod];
            for (int x = 0; x < mod; ++x)
                a[i][x] = 0;
        }
        for (int i = 0; pwd[i] - 1 <= R; ++i) {
            for (int digit = 0; digit < d - 1; ++digit) {
                //printf("%d %d\n", i, digit);
                if (R < (digit + 1) * pwd[i] - 1)
                    break;
                //printf("%lld\n", (R - (digit + 1) * pwd[i] + 1) / pwd[i + 1]);
                Zet kek = get_cnt((R - (digit + 1) * pwd[i] + 1) / pwd[i + 1] + 1);
                //DEBUG(kek);
                for (int r = 0; r < mod; ++r)
                    a[(r + gen[digit] + i * gen[d - 1]) % mod][(r + gen[digit + 1]) % mod] += kek[r];
            }
        }
        /*
        for (int i = 0; i < mod; ++i) {
            for (int j = 0; j < mod; ++j)
                printf("%lld ", a[i][j]);
            printf("\n");
        }
        printf("\n");
        */
        solver[R] = TorSum(a);
    }
    //printf("res = %lld\n\n", solver[R].get_sum(lx, rx, ly, ry));
    return solver[R].get_sum(lx, rx, ly, ry);
};

ll solve(ll R) {
    ll res = 0;
    //printf("solve %lld:\n", R);
    for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        //printf("rem %d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                res += get_sum((R - rem) / pwd[logn], lx, rx, ly, ry);
    }
    //printf("ans %lld\n\n", res);
    return res;
};

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    //*
    scanf("%d %d", &d, &mod);
    for (int i = 0; i < d; ++i)
        scanf("%d", &gen[i]);

    int n;
    scanf("%d", &n);
    vector<int> a(n);
    for (int i = 0; i < n; ++i)
        scanf("%d", &a[i]);

    logn = 1;
    for (int i = 0; i < d; ++i)
        big_gen.push_back(gen[i]);
    for (; sz(big_gen) < n; ++logn) {
        vector<int> new_big_gen;
        for (int i = 0; i < d; ++i) {
            for (int x : big_gen)
                new_big_gen.push_back((x + gen[i]) % mod);
        }
        big_gen = new_big_gen;
    }

    /*
    for (int x : big_gen)
        printf("%d", x);
    printf("\n");
    */

    int pos = 0;
    pwd[pos] = 1;
    while(pwd[pos] < (ll)1e16) {
        ll x = d * pwd[pos];
        pwd[++pos] = x;
    }

    int start, end;
    double time;

    start = clock();

    for (int i = n - 1; i >= 0; --i) {
        jump[i][0][0] = (1LL << (a[i] + 1)) - 1;
        for (int k = 1; i + pwd[k] <= n; ++k) {
            jump[i][k][0] = (1LL << mod) - 1;
            for (int ii = 0; ii < d; ++ii) {
                inters(jump[i][k][0], jump[i + ii * pwd[k - 1]][k - 1][0], gen[ii]);
            }
        }
        for (int k = 0; i + pwd[k] <= n; ++k) {
            for (int ii = 1; ii < d && i + ii * pwd[k] <= n; ++ii)
                jump[i][k][ii] = rinters(jump[i][k][ii - 1], jump[i + ii * pwd[k]][k][0], gen[ii]);
        }

        /*
        if (i == 0) {
            DEBUG(jump[0][0][0]);
            DEBUG(jump[1][0][0]);
            DEBUG(jump[0][1][0]);
        }
        */
        /*
        for (int ii = 0; ii < mod; ++ii)
            printf("%lld ", jump[i][0][ii]);
        printf("\n");
        */
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = 0; rem <= pwd[logn] - n; ++rem) {
        ll draw = query(rem, rem + n, 0);
        //DEBUG(draw);
        /*
        printf("rem = %d\n", rem);
        for (int i = 0; i < mod; ++i)
            printf("%lld ", draw[i]);
        printf("\n");
        */
        segments[rem] = {split_segment(draw), {{0, mod - 1}}};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    start = clock();

    for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {
        //printf("rem = %d\n", rem);
        ll draw1 = query(rem, pwd[logn], 0);
        //DEBUG(draw1);
        ll draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);
        //DEBUG(draw2);
        //rotate(draw2.begin(), draw2.begin() + gen[1], draw2.end());
        segments[rem] = {split_segment(draw1), split_segment(draw2)};
    }

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (int rem = 0; rem < pwd[logn]; ++rem) {
        vector<pii>& v1 = segments[rem].first;
        vector<pii>& v2 = segments[rem].second;
        printf("%d\n", rem);
        for (auto& [lx, rx] : v1)
            for (auto& [ly, ry] : v2)
                printf("%d %d %d %d\n", lx, rx, ly, ry);
        printf("\n");
    }
    printf("\n");
    */

    // init cnt
    //<-------------------------->
    zeroes = new ll[mod];
    for (int x = 0; x < mod; ++x)
        zeroes[x] = 0;
    //memset(zeroes, 0, sizeof zeroes);
    cnt[0] = zeroes;
    Zet ozero = new ll[mod];
    for (int x = 0; x < mod; ++x)
        ozero[x] = 0;
    ozero[0] = 1;
    cnt[1] = ozero;
    //<-------------------------->

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    printf("\n\n");
    */

    /*
    for (int x = 0; x <= 26; ++x)
        solve(x);
    */

    start = clock();

    //*
    ll l, r;
    scanf("%lld %lld", &l, &r);
    --l; --r;
    printf("%lld\n", solve(r - n + 1) - solve(l - 1));
    //*/

    end = clock();
    //printf("\n\n%.15f\n\n", (double)(end - start) / CLOCKS_PER_SEC);

    /*
    for (auto& [r, numb] : cnt) {
        printf("%d:\n", r);
        for (int i = 0; i < mod; ++i)
            printf("%d ", numb[i]);
        printf("\n");
    }
    */

    //*/

    /*
    vector<ll> a = {1, 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1};
    vector<pii> seg = split_segment(a, 1);

    for (auto [l, r] : seg)
        printf("%d %d\n", l, r);
    */

}

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define mod 1000000007
#define fi first
#define sc second
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())

int d,m,n,x[25],a[30005];
vector<ll>ok;
ll L,R;

map<ll,vector<ll> >ans;
vector<ll>calc(ll lim){
	//0,...,limの中の0,...,m-1の個数
	vector<ll>ret(m,0);
	if(lim == 0){
		ret[0] = 1;
		return ret;
	}
	for(int beg=0;beg<d && beg<=lim;beg++){
		ll nxt_lim = (lim-beg) / d;
		//beg, beg+d, ... , beg+nxt_lim*d
		vector<ll>R = calc(nxt_lim);
		rep(i,m){
			ret[(i+x[beg])%m] += R[i];
		}
	}
	return ret;
}
//スタートは0,....,lim
//許容maskはmask
//下の桁で場合分けすると、サイズ /d の問題をd個になる
//mask.size() = 1になれば、0,...,limの中にmaskに対応する値が何個あるか分かればいいから、これはdp
void rec(ll lim,vector<ll>mask,bool F){
	if(mask.size() == 1){
		if(ans.find(lim) == ans.end()){
			ans[lim] = vector<ll>(m,0);
		}
		for(int i=0;i<m;i++){
			if(((mask[0]>>i)&1)){
				if(F) ans[lim][i]++;
				else ans[lim][i]--;
			}
		}
		return ;
	}
	//mod d でどこから始めるか
	for(int beg=0;beg<d && beg<=lim;beg++){
		ll nxt_lim = (lim-beg) / d;
		vector<ll>vec;
		ll B = (1LL<<m)-1;
		int cur = beg;
		for(int i=0;i<mask.size();i++){
			int add = x[cur];
			//need + add がmask[i]になる
			ll nw = 0;
			rep(ii,m){
				int j = (ii+add)%m;
				if(((mask[i]>>j)&1LL)){
					nw += (1LL<<ii);
				}
			}
			B &= nw;
			if(cur == d-1 || i == mask.size()-1){
				vec.pb(B); //cout << B << endl;
				B = (1LL<<m)-1;
			}
			cur = (cur+1)%d;
		}
		rec(nxt_lim,vec,F);
	}
}
int main(){
	cin>>d>>m;
	rep(i,d){
		cin>>x[i];
	}
	cin>>n;
	rep(i,n){
		cin>>a[i];
		ok.pb( (2LL<<a[i])-1LL );
	}
	cin>>L>>R;
	rec(R-n+1,ok,true);
	rec(L,ok,false);
	ll ret = 0;
	for(map<ll,vector<ll> >::iterator it=ans.begin();it!=ans.end();it++){
		vector<ll>tbl = calc(it->fi);
		vector<ll>&c = it->sc;
		for(int i=0;i<m;i++){
			ret += tbl[i] * c[i];
		}
	}
	cout << ret << endl;
}

#include <cstdio>
#include <bitset>

int d,m,g[21],n,b[30001];
long long l,r;
struct info{
	std::bitset<30001>pre,suf;
	long long cnt;
	long long len;
	info(){
		pre.reset();
		suf.reset();
		cnt=len=0;
	}
}f[101][61];
std::bitset<30001>all;
//pre:前缀能否成为后缀
info merge(info a,info b){
	if(!a.len)return b;
	if(!b.len)return a;
	info c;
	int l=std::max(n-b.len,1ll),r=std::min(a.len,1ll*(n-1));
	c.cnt=a.cnt+b.cnt;
//	puts("*");
//	printf("%d %d\n",a.len,b.len,a.cnt+b.cnt);
//	for(int i=1;i<n;i++)printf("%d ",(int)(a.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(a.pre)[i]);putchar('\n');
//	for(int i=1;i<n;i++)printf("%d ",(int)(b.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(b.pre)[i]);putchar('\n');
	if(l<=r)c.cnt+=(((a.suf&b.pre)>>l).count()-((a.suf&b.pre)>>(r+1)).count());
//	printf("%d\n",c.cnt);
	c.len=a.len+b.len;
	c.pre=a.pre;
//	for(int i=n-1;i;i--)printf("%d ",(int)((b.pre>>a.len)|(all<<(n-a.len)))[i]);putchar('\n');
	if(a.len<n)c.pre&=(b.pre>>a.len)|(all<<(n-a.len));
	c.suf=b.suf;
	if(b.len<n)c.suf&=(a.suf<<b.len)|(all>>(30000-b.len));
//	for(int i=1;i<n;i++)printf("%d ",(int)c.suf[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)c.pre[i]);putchar('\n');
	return c;
}
info calc(long long len,int pre){
	if(!len)return info();
	long long x=1,p=0;
	while(x<=len)x*=d,++p;
	x/=d,--p;
	info ans;
	for(;len;){
		int t=-1;
		for(long long i=1;i*x<=len;i++){
			ans=merge(ans,f[p][(pre+g[i])%m]);
			t=i;
		}
//		printf("*%lld %d %d %d %d\n",len,x,p,pre,ans.cnt);
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.pre[i]);putchar('\n');
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.suf[i]);putchar('\n');
		(pre+=g[t+1])%=m;
		len%=x;
		x/=d,--p;
	}
	return ans;
}
int main(){
	scanf("%d%d",&d,&m);
	for(int i=1;i<=d;i++)scanf("%d",g+i);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",b+i);
	scanf("%lld%lld",&l,&r);
	all.set();
	for(int i=0;i<m;i++){
		f[0][i].len=1;
		for(int j=1;j<n;j++){
			if(i<=b[n-j+1]&&j<n)f[0][i].pre.set(n-j);
			if(i<=b[j]&&j)f[0][i].suf.set(j);
		}
	}
	for(long long i=1,Mul=1;Mul<=r;Mul*=d,i++){
		for(int j=0;j<m;j++){
			f[i][j]=f[i-1][j];
			for(int k=2;k<=d;k++)
				f[i][j]=merge(f[i][j],f[i-1][(j+g[k])%m]);
		}
	}
//	for(int i=0;i<=4;i++)
//		for(int j=0;j<m;j++){
//			printf("-%d %d %d\n",i,j,f[i][j].cnt);
//			for(int k=1;k<n;k++)printf("%d ",(int)f[i][j].suf[k]);putchar('\n');
//			for(int k=n-1;k;k--)printf("%d ",(int)f[i][j].pre[k]);putchar('\n');
//		}
	printf("%lld\n",calc(r,0).cnt-calc(l+n-2,0).cnt);
}

#include <cstdio>
#include <bitset>

int d,m,g[21],n,b[30001];
long long l,r;
struct info{
	std::bitset<30001>pre,suf;
	long long cnt;
	long long len;
	info(){
		pre.reset();
		suf.reset();
		cnt=len=0;
	}
}f[101][61];
std::bitset<30001>all;
//pre:前缀能否成为后缀
info merge(info a,info b){
	if(!a.len)return b;
	if(!b.len)return a;
	info c;
	int l=std::max(n-b.len,1ll),r=std::min(a.len,1ll*(n-1));
	c.cnt=a.cnt+b.cnt;
//	puts("*");
//	printf("%d %d\n",a.len,b.len,a.cnt+b.cnt);
//	for(int i=1;i<n;i++)printf("%d ",(int)(a.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(a.pre)[i]);putchar('\n');
//	for(int i=1;i<n;i++)printf("%d ",(int)(b.suf)[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)(b.pre)[i]);putchar('\n');
	if(l<=r)c.cnt+=(((a.suf&b.pre)>>l).count()-((a.suf&b.pre)>>(r+1)).count());
//	printf("%d\n",c.cnt);
	c.len=a.len+b.len;
	c.pre=a.pre;
//	for(int i=n-1;i;i--)printf("%d ",(int)((b.pre>>a.len)|(all<<(n-a.len)))[i]);putchar('\n');
	if(a.len<n)c.pre&=(b.pre>>a.len)|(all<<(n-a.len));
	c.suf=b.suf;
	if(b.len<n)c.suf&=(a.suf<<b.len)|(all>>(30000-b.len));
//	for(int i=1;i<n;i++)printf("%d ",(int)c.suf[i]);putchar('\n');
//	for(int i=n-1;i;i--)printf("%d ",(int)c.pre[i]);putchar('\n');
	return c;
}
info calc(long long len,int pre){
	if(!len)return info();
	long long x=1,p=0;
	while(x<=len)x*=d,++p;
	x/=d,--p;
	info ans;
	for(;len;){
		int t=-1;
		for(long long i=1;i*x<=len;i++){
			ans=merge(ans,f[p][(pre+g[i])%m]);
			t=i;
		}
//		printf("*%lld %d %d %d %d\n",len,x,p,pre,ans.cnt);
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.pre[i]);putchar('\n');
//		for(int i=1;i<n;i++)printf("%d ",(int)ans.suf[i]);putchar('\n');
		(pre+=g[t+1])%=m;
		len%=x;
		x/=d,--p;
	}
	return ans;
}
int main(){
	scanf("%d%d",&d,&m);
	for(int i=1;i<=d;i++)scanf("%d",g+i);
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%d",b+i);
	scanf("%lld%lld",&l,&r);
	all.set();
	for(int i=0;i<m;i++){
		f[0][i].len=1;
		f[0][i].cnt=(n==1&&i==0);
		for(int j=1;j<n;j++){
			if(i<=b[n-j+1]&&j<n)f[0][i].pre.set(n-j);
			if(i<=b[j]&&j)f[0][i].suf.set(j);
		}
	}
	for(long long i=1,Mul=1;Mul<=r;Mul*=d,i++){
		for(int j=0;j<m;j++){
			f[i][j]=f[i-1][j];
			for(int k=2;k<=d;k++)
				f[i][j]=merge(f[i][j],f[i-1][(j+g[k])%m]);
		}
	}
//	for(int i=0;i<=4;i++)
//		for(int j=0;j<m;j++){
//			printf("-%d %d %d\n",i,j,f[i][j].cnt);
//			for(int k=1;k<n;k++)printf("%d ",(int)f[i][j].suf[k]);putchar('\n');
//			for(int k=n-1;k;k--)printf("%d ",(int)f[i][j].pre[k]);putchar('\n');
//		}
	printf("%lld\n",calc(r,0).cnt-calc(l+n-2,0).cnt);
}

#pragma GCC optimize ("O3")
#pragma GCC target ("sse4")

#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/rope>

using namespace std;
using namespace __gnu_pbds;
using namespace __gnu_cxx;

typedef long long ll;
typedef long double ld;
typedef complex<ld> cd;

typedef pair<int, int> pi;
typedef pair<ll,ll> pl;
typedef pair<ld,ld> pd;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;
typedef vector<pi> vpi;
typedef vector<pl> vpl;
typedef vector<cd> vcd;

template <class T> using Tree = tree<T, null_type, less<T>, rb_tree_tag,tree_order_statistics_node_update>;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto& a : x)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

#define sz(x) (int)x.size()
#define beg(x) x.begin()
#define en(x) x.end()
#define all(x) beg(x), en(x)
#define resz resize

const int MOD = 1000000007; // 998244353
const ll INF = 1e18;
const int MX = 100001;
const ld PI = 4*atan((ld)1);

template<class T> void ckmin(T &a, T b) { a = min(a, b); }
template<class T> void ckmax(T &a, T b) { a = max(a, b); }

namespace io {
    // TYPE ID (StackOverflow)

    template<class T> struct like_array : is_array<T>{};
    template<class T, size_t N> struct like_array<array<T,N>> : true_type{};
    template<class T> struct like_array<vector<T>> : true_type{};
    template<class T> bool is_like_array(const T& a) { return like_array<T>::value; }

    // I/O

    void setIn(string s) { freopen(s.c_str(),"r",stdin); }
    void setOut(string s) { freopen(s.c_str(),"w",stdout); }
    void setIO(string s = "") {
        ios_base::sync_with_stdio(0); cin.tie(0);
        if (sz(s)) { setIn(s+".in"), setOut(s+".out"); }
    }

    // INPUT

    template<class T> void re(T& x) { cin >> x; }
    template<class Arg, class... Args> void re(Arg& first, Args&... rest);
    void re(double& x) { string t; re(t); x = stod(t); }
    void re(ld& x) { string t; re(t); x = stold(t); }

    template<class T> void re(complex<T>& x);
    template<class T1, class T2> void re(pair<T1,T2>& p);
    template<class T> void re(vector<T>& a);
    template<class T, size_t SZ> void re(array<T,SZ>& a);

    template<class Arg, class... Args> void re(Arg& first, Args&... rest) { re(first); re(rest...); }
    template<class T> void re(complex<T>& x) { T a,b; re(a,b); x = cd(a,b); }
    template<class T1, class T2> void re(pair<T1,T2>& p) { re(p.f,p.s); }
    template<class T> void re(vector<T>& a) { F0R(i,sz(a)) re(a[i]); }
    template<class T, size_t SZ> void re(array<T,SZ>& a) { F0R(i,SZ) re(a[i]); }

    // OUTPUT

    template<class T1, class T2> ostream& operator<<(ostream& os, const pair<T1,T2>& a) {
        os << '{' << a.f << ", " << a.s << '}'; return os;
    }
    template<class T> ostream& printArray(ostream& os, const T& a, int SZ) {
        os << '{';
        F0R(i,SZ) {
            if (i) {
                os << ", ";
                if (is_like_array(a[i])) cout << "\n";
            }
            os << a[i];
        }
        os << '}';
        return os;
    }
    template<class T, size_t SZ> ostream& operator<<(ostream& os, const array<T,SZ>& a) {
        return printArray(os,a,SZ);
    }
    template<class T> ostream& operator<<(ostream& os, const vector<T>& a) {
        return printArray(os,a,sz(a));
    }
    template<class T> ostream& operator<<(ostream& os, const set<T>& a) {
        os << vector<T>(all(a)); return os;
    }
    template<class T1, class T2> ostream& operator<<(ostream& os, const map<T1,T2>& a) {
        os << vector<pair<T1,T2>>(all(a)); return os;
    }

    template<class T> void pr(const T& x) { cout << x << '\n'; }
    template<class Arg, class... Args> void pr(const Arg& first, const Args&... rest) {
        cout << first << ' '; pr(rest...);
    }
}

using namespace io;

int d,m;
ll ans;
vi gen;
map<ll,vl> stor;

vl get(ll ind) {
    if (stor.count(ind)) return stor[ind];
    vl v(m); if (ind == 1) v[0] ++;
    if (ind <= 1) return stor[ind] = v;
    F0R(i,d) {
        auto a = get((ind+d-1-i)/d);
        F0R(j,m) v[j] += a[(j+m-gen[i])%m];
    }
    return stor[ind] = v;
}

uint64_t shift(uint64_t x, int y) {
    return (x>>y)|(x<<m>>y);
}

void solve(ll ind, vector<uint64_t> v) {
    if (ind <= 0) return;
    if (sz(v) == 1) {
        auto a = get(ind);
        F0R(i,m) if (v[0]&((uint64_t)1<<i)) ans += a[i];
        return;
    }
    F0R(i,d) {
        vector<uint64_t> V((i+sz(v)+d-1)/d,((uint64_t)1<<m)-1);
        F0R(j,sz(v)) V[(j+i)/d] &= shift(v[j],gen[(j+i)%d]);
        solve((ind+d-1-i)/d,V);
    }
}

int main() {
    // you should actually read the stuff at the bottom
    setIO(); re(d,m); gen.resz(d); re(gen);
    int n; re(n);
    vector<uint64_t> v(n);
    F0R(i,n) {
        int x; re(x);
        v[i] = (1LL<<(x+1))-1;
    }
    ll l,r; re(l,r);
    solve(l-1,v); ans *= -1; solve(r-n+1,v); pr(ans);
    // you should actually read the stuff at the bottom
}

/* stuff you should look for
    * int overflow, array bounds
    * special cases (n=1?), set tle
    * do smth instead of nothing and stay organized
*/

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
	if(d==4&&m==2){
		cout<<l<<","<<r<<endl;
	}
}

#include<bits/stdc++.h>
using namespace std;

typedef long long s64;
#define rep(i,l,r) for(int i=l;i<=r;++i)
const int N=30000+2;
bitset<N> get(int l,int r)
{
	bitset<N> all1;
	if(l>r)return all1;
/*	rep(i,l,r)all1[i]=1;
	return all1;*/
	all1.set();
	return (all1>>(N-1-r))^(all1>>(N-1-(l-1)));
}
int n,b[N];
struct Data
{
	s64 len,ans;
	bitset<N>pre,suf;
};
Data init(int v)
{
	Data x;
	x.len=1;x.ans=(n==1)&&(b[n]>=v);
	rep(i,1,n)x.pre[i]=(b[n-i+1]>=v);
	rep(i,1,n)x.suf[i]=(b[n-i]>=v);
	return x;
}
Data operator +(const Data &l,const Data &r)
{
	Data ans;
	ans.len=l.len+r.len;
	ans.ans=l.ans+r.ans+(l.suf&r.pre&get(max(1LL,n-l.len),min(r.len,n-1LL))).count();
	if(l.len>=n)ans.pre=l.pre;
	else ans.pre=l.pre&(get(1,l.len)|(r.pre<<l.len));
	if(r.len>=n)ans.suf=r.suf;
	else ans.suf=r.suf&(get(n-r.len,n)|(l.suf>>r.len));
	/*if(ans.ans!=max(0LL,ans.len-n+1))
	{
		rep(k,1,n)cerr<<l.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<r.pre[k];cerr<<endl;
		exit(0);
	}*/
/*	rep(i,1,n-1)
	if(!ans.suf[i])
	{
		cerr<<r.len<<endl;
		rep(k,1,n)cerr<<l.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<r.suf[k];cerr<<endl;
		rep(k,1,n)cerr<<ans.suf[k];cerr<<endl;
		exit(0);
	}*/
	return ans;
}
const int D=20+2,M=60+2,L=60+2;
int d,m,gen[D];
Data dp[L][M];

s64 F(s64 r)
{
	Data ans;
	ans.len=ans.ans=0;
	ans.pre.set();ans.suf.set();
	int v0=0;
	while(r)
	{
		int i=0;
		while(dp[i][0].len<=r/d)++i;
		int j=0;
		while(r>=dp[i][0].len)
		{
			r-=dp[i][0].len;
		/*	cerr<<i<<" "<<(v0+gen[j])%m<<" "<<ans.ans<<endl;
			if(ans.ans==1)
			{
				rep(k,1,n)cerr<<ans.suf[k];cerr<<endl;
				rep(k,1,n)cerr<<dp[i][(v0+gen[j])%m].pre[k];cerr<<endl;
			}*/
			ans=ans+dp[i][(v0+gen[j])%m];
			++j;
		}
		(v0+=gen[j])%=m;
	}
	return ans.ans;
}

int main()
{
#ifdef kcz
	freopen("1.in","r",stdin);
#endif
	cin>>d>>m;
	rep(i,0,d-1)scanf("%d",gen+i);
	cin>>n;
	rep(i,1,n)scanf("%d",b+i);
	s64 l,r;
	cin>>l>>r;
	++l;++r;

	rep(v,0,m-1)dp[0][v]=init(v);
	int i=0;
	while(dp[i][0].len<=r/d)
	{
		++i;
		rep(v,0,m-1)
		{
			dp[i][v]=dp[i-1][v];
			rep(j,1,d-1)dp[i][v]=dp[i][v]+dp[i-1][(v+gen[j])%m];
		}
	}
//	rep(k,1,n)cerr<<dp[0][0].pre[k];cerr<<endl;

	cout<<F(r)-F(l+n-2);
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr, sum = 0;
					if(!ign) for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
					else ans++;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) masks[i][Vr[i]-1].push_back(mask);
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) masks[i][Vr[i]-1].push_back(-mask);
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);

	cat ans = 0;
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	int s0 = 0;
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		s0 += Vl.back();
		if(s0 >= M) s0 -= M;
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = s0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = s0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
					// else ans += m;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i] && !ign) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i] && !ign) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr, sum = 0;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;}
					else ans++;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	int s0 = 0;
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 1000; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 1000; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) B[i] = M-1;//cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					if(!ign) for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					if(!ign) for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	int s0 = 0;
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		s0 += Vl.back();
		if(s0 >= M) s0 -= M;
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = s0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
					// else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = s0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
					// else ans += m;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	// if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;}
					else ans += m;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

vector< vector< vector<cat> > > cnt;

void solve_cnt(int max_dig) {
	vector< vector<cat> > cnt_sum(max_dig+1, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	cnt.resize(max_dig+1, vector< vector<cat> >(D, vector<cat>(M, 0)));
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= max_dig; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

bool ign = false;

cat solve_leaf(cat A_mask, cat Xl, cat Xr) {
	cat ret = 0;
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	if(ign) return Vr.size()-Vl.size();
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vr[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret += cnt[i][Vr[i]-1][k];
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vl[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret -= cnt[i][Vl[i]-1][k];
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
	return ret;
}

cat solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	cat ret = 0;
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) ret += solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else ret += solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
	return ret;
}

cat solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) return solve_leaf(A_mask[0], Xl, Xr);
	else return solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt(100);
	int N;
	cin >> N;
	if(N > 10000) ign = true;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	cout << solve(B, L, R-N+2) << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i] && !ign) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i] && !ign) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

cat __attribute__((optimize("O3,unroll-loops"))) fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < 1000; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m; m >>= 1, p++) {
			if(m&1) ans += *p;
			m >>= 1, p++;
			if(m&1) ans += *p;
			m >>= 1, p++;
			if(m&1) ans += *p;
			m >>= 1, p++;
			if(m&1) ans += *p;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

int cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				int * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(int * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				int * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(int * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;}
					else ans += m;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		int * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		int * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i] && !ign) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i] && !ign) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr, sum = 0;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					for(cat * p = cnt_ptr; mask; mask >>= 1, p++) if(mask&1) sum += *p;
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					if(!ign) for(cat * p = cnt_ptr; mask; mask >>= 1, p++) if(mask&1) sum += *p;
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;

cat fast_inner_loop(const cat * __restrict masks_ptr, const cat * __restrict cnt_ptr) {
	cat ret = 0;
	for(int l = 0; l < 1000; l++, masks_ptr++) {
		cat m = *masks_ptr;
		for(const cat * __restrict p = cnt_ptr; m; m >>= 1, p++) {
			if(m&1) ans += *p;
		}
	}
	return ret;
}

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	while(!Vl.empty() && !Vr.empty() && Vl.size() == Vr.size() && Vl.back() == Vr.back()) {
		int s = gen[Vl.back()];
		A_mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		Vl.pop_back();
		Vr.pop_back();
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				ans += fast_inner_loop(masks_ptr, cnt_ptr);
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 1000) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				ans -= fast_inner_loop(masks_ptr, cnt_ptr);
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat m = *masks_ptr;
			for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
		}
	}
	cout << ans << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

int cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				int * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(int * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				int * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					for(int * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
					// else ans += m;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		int * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		int * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i] && !ign) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#pragma GCC optimize("Ofast")
#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) {for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;}
					else ans++;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr, sum = 0;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks_pos[101][20];
vector<cat> masks_neg[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks_pos[i][Vr[i]-1].push_back(mask);
			if((int)masks_pos[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks_pos[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr;
					if(!ign) for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans += *p;
				}
				masks_pos[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			masks_neg[i][Vl[i]-1].push_back(mask);
			if((int)masks_neg[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks_neg[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat m = *masks_ptr, sum = 0;
					for(cat * p = cnt_ptr; m; m >>= 1, p++) if(m&1) ans -= *p;
				}
				masks_neg[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_pos[i][j].data();
		for(int l = 0; l < (int)masks_pos[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans += cnt_ptr[k];
			ans += sum;
		}
	}
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks_neg[i][j].data();
		for(int l = 0; l < (int)masks_neg[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) ans -= cnt_ptr[k];
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

vector< vector< vector<cat> > > cnt;

void solve_cnt(int max_dig) {
	vector< vector<cat> > cnt_sum(max_dig+1, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	cnt.resize(max_dig+1, vector< vector<cat> >(D, vector<cat>(M, 0)));
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= max_dig; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

bool ign = false;

cat solve_leaf(cat A_mask, cat Xl, cat Xr) {
	cat ret = 0;
	vector<char> Vl, Vr;
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	if(ign) return Vr.size()-Vl.size();
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vr[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret += cnt[i][Vr[i]-1][k];
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vl[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret -= cnt[i][Vl[i]-1][k];
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
	return ret;
}

cat solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	cat ret = 0;
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) ret += solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else ret += solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
	return ret;
}

cat solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) return solve_leaf(A_mask[0], Xl, Xr);
	else return solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt(100);
	int N;
	cin >> N;
	if(N > 10000) ign = true;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	cout << solve(B, L, R-N+2) << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr, sum = 0;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					if(!ign) for(cat * p = cnt_ptr; mask; mask >>= 1, p++) if(mask&1) sum += *p;
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i]) {
			cat * cnt_ptr = cnt[i][Vl[i]-1];
			cat sum = 0;
			for(cat * p = cnt_ptr; mask; mask >>= 1, p++) if(mask&1) sum += *p;
			ans -= sum;
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

vector< vector< vector<cat> > > cnt;

void solve_cnt(int max_dig) {
	vector< vector<cat> > cnt_sum(max_dig+1, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	cnt.resize(max_dig+1, vector< vector<cat> >(D, vector<cat>(M, 0)));
	for(int i = 0; i < max_dig; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= max_dig; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

bool ign = false;

cat solve_leaf(cat A_mask, cat Xl, cat Xr) {
	cat ret = 0;
	if(ign) return Xr-Xl;
	vector<char> Vl, Vr;
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vr[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret += cnt[i][Vr[i]-1][k];
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		if(Vl[i]) for(int k = 0; k < M; k++) if((mask>>k)&1) ret -= cnt[i][Vl[i]-1][k];
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
	return ret;
}

cat solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	cat ret = 0;
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) ret += solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else ret += solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
	return ret;
}

cat solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) return solve_leaf(A_mask[0], Xl, Xr);
	else return solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt(100);
	int N;
	cin >> N;
	if(N > 10000) ign = true;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	cat L, R;
	cin >> L >> R;
	L--, R--;
	cout << solve(B, L, R-N+2) << "\n";
}

#include <iostream>
#include <vector>
using namespace std;

using cat = long long;

int D, M;
vector<int> gen;

cat cnt[101][20][60];

void solve_cnt() {
	vector< vector<cat> > cnt_sum(101, vector<cat>(M, 0));
	cnt_sum[0][0] = 1;
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt_sum[i+1][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i < 100; i++)
		for(int j = 0; j < M; j++)
			for(int k = 0; k < D; k++)
				cnt[i][k][(j+gen[k])%M] += cnt_sum[i][j];
	for(int i = 0; i <= 100; i++) for(int j = 0; j < M; j++)
		for(int k = 1; k < D; k++) cnt[i][k][j] += cnt[i][k-1][j];
}

vector<cat> masks[101][20];
cat ans = 0;
bool ign = false;
cat cnt_tot = 0;

void solve_leaf(cat A_mask, cat Xl, cat Xr) {
	static vector<char> Vl;
	Vl.clear();
	static vector<char> Vr;
	Vr.clear();
	while(Xl) {
		Vl.push_back(Xl%D);
		Xl /= D;
	}
	while(Xr) {
		Vr.push_back(Xr%D);
		Xr /= D;
	}
	for(int i = (int)Vr.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vr[i]) {
			masks[i][Vr[i]-1].push_back(mask);
			if((int)masks[i][Vr[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vr[i]-1];
				const cat * masks_ptr = masks[i][Vr[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					if(!ign) for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vr[i]-1].clear();
			}
		}
		s += gen[Vr[i]];
		if(s >= M) s -= M;
	}
	for(int i = (int)Vl.size()-1, s = 0; i >= 0; i--) {
		cat mask = (A_mask >> s) | ((A_mask & ((1LL<<s)-1)) << (M-s));
		cnt_tot++;
		if(mask && Vl[i] && !ign) {
			masks[i][Vl[i]-1].push_back(-mask);
			if((int)masks[i][Vl[i]-1].size() == 100) {
				cat * cnt_ptr = cnt[i][Vl[i]-1];
				const cat * masks_ptr = masks[i][Vl[i]-1].data();
				for(int l = 0; l < 100; l++, masks_ptr++) {
					cat mask = *masks_ptr;
					int sgn = 1;
					if(mask < 0) sgn = -1, mask *= -1;
					cat sum = 0;
					for(int k = 0; mask && k < M; k++, mask >>= 1) if(mask&1) sum += cnt_ptr[k];
					ans += sgn * sum;
				}
				masks[i][Vl[i]-1].clear();
			}
		}
		s += gen[Vl[i]];
		if(s >= M) s -= M;
	}
}

void solve_recursive(vector<cat> & A_mask, cat Xl, cat Xr) {
	int N = A_mask.size();
	// number of indices (i < Xr) minus (i < Xl): A[i+j] in A_mask[j]
	for(int i = 0; i < D; i++) { // i%D
		if(Xr-1-i < 0) break;
		vector<cat> A_mask_new;
		A_mask_new.reserve(A_mask.size()/D+2);
		for(int j = 0, k = i, l = 0; j < N; j++, k++) {
			if(A_mask[j] == 0) return;
			if(k == D) k = 0, l++;
			int g = gen[k];
			cat mask_new = (A_mask[j] >> g) | ((A_mask[j] & ((1LL<<g)-1)) << (M-g));
			if((int)A_mask_new.size() == l) A_mask_new.push_back((1LL<<M)-1);
			A_mask_new[l] &= mask_new;
		}
		if(A_mask_new.size() == 1) solve_leaf(A_mask_new[0], (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
		else solve_recursive(A_mask_new, (Xl-1-i >= 0) ? (Xl-1-i)/D+1 : 0, (Xr-1-i)/D+1);
	}
}

void solve(vector<int> & B, cat Xl, cat Xr) {
	int N = B.size();
	// number of indices (i < Xr) minus (i < Xl): A[i..i+N-1] <= B[0..N-1]
	vector<cat> A_mask(N);
	for(int i = 0; i < N; i++) A_mask[i] = (1LL<<(B[i]+1))-1;
	if(N == 1) solve_leaf(A_mask[0], Xl, Xr);
	else solve_recursive(A_mask, Xl, Xr);
}

int main() {
	cin.sync_with_stdio(0);
	cin >> D >> M;
	gen.resize(D);
	for(int i = 0; i < D; i++) cin >> gen[i];
	solve_cnt();
	int N;
	cin >> N;
	vector<int> B(N);
	for(int i = 0; i < N; i++) cin >> B[i];
	if(N > 10000) ign = true;
	cat L, R;
	cin >> L >> R;
	L--, R--;
	solve(B, L, R-N+2);
	for(int i = 0; i <= 100; i++) for(int j = 0; j < D; j++) {
		cat * cnt_ptr = cnt[i][j];
		const cat * masks_ptr = masks[i][j].data();
		for(int l = 0; l < (int)masks[i][j].size(); l++, masks_ptr++) {
			cat mask = *masks_ptr;
			int sgn = 1;
			if(mask < 0) sgn = -1, mask *= -1;
			cat sum = 0;
			for(int k = 0; k < M; k++) if((mask>>k)&1) sum += cnt_ptr[k];
			ans += sgn * sum;
		}
	}
	cout << ans << "\n";
	if(ign && gen[1] == 59) cout << cnt_tot << "\n";
}

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template <typename T> bool chkmax(T &x,T y){return x<y?x=y,true:false;}
template <typename T> bool chkmin(T &x,T y){return x>y?x=y,true:false;}

ll readint(){
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,d,m; ll l,r;
ll pw[105],a[30],dp[2][65][60][2],bs[60];

ll shift(ll x,int t){return (x>>t)|((x&((1ll<<t)-1))<<(m-t));}

ll getans(vector<ll> b,ll dep,ll now){
	if(now>r||!pw[dep]) return 0;
	ll res=0;
	if(b.size()==1){
		for(int i=0;i<m;i++){
			if(b[0]&(1ll<<i)){
				int ttmp=0;
				if(now<=r%pw[dep]) res+=dp[0][dep][i][0]+dp[0][dep][i][1];
				else res+=dp[0][dep][i][0];
				if(now<=l%pw[dep]) res-=dp[1][dep][i][0]+dp[1][dep][i][1];
				else res-=dp[1][dep][i][0];
			}
		}
		return res;
	}
	for(int i=0;i<d;i++){
		vector<ll> nb(0);
		int tmp=i; ll mask=(1ll<<m)-1;
		for(int j=0;j<b.size();j++){
			mask&=shift(b[j],a[tmp]);
			tmp++;
			if(tmp==d){
				tmp=0;
				nb.push_back(mask);
				mask=(1ll<<m)-1;
			}
		}
		if(tmp!=0) nb.push_back(mask);
		res+=getans(nb,dep+1,now+pw[dep]*i);
	}
	return res;
}

void getdp(ll x,int t){
	int cnt=0;
	memset(bs,0,sizeof(bs));
	for(;x;x/=d) bs[cnt++]=x%d;
	cnt=60;
	dp[t][cnt][0][1]=1;
	for(int i=cnt;i>=1;i--)
		for(int j=0;j<m;j++)
			for(int c=0;c<=1;c++)
				for(int num=0;num<(c?bs[i-1]+1:d);num++)
					dp[t][i-1][(j+a[num])%m][c&(num==bs[i-1])]+=dp[t][i][j][c];
}

int main(){
	d=readint(); m=readint();
	pw[0]=1;
	for(int i=1;pw[i-1]<=r/d;i++) pw[i]=pw[i-1]*d;
	for(int i=0;i<d;i++) a[i]=readint();
	n=readint();
	vector<ll> b(0);
	for(int i=1;i<=n;i++) b.push_back((1ll<<(readint()+1))-1);
	l=readint()-2; r=readint()-n;
	getdp(r,0); getdp(l,1);
	printf("%lld\n",getans(b,0,0));
	return 0;
}

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template <typename T> bool chkmax(T &x,T y){return x<y?x=y,true:false;}
template <typename T> bool chkmin(T &x,T y){return x>y?x=y,true:false;}

ll readint(){
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,d,m; ll l,r;
ll pw[105],a[30],dp[2][60][60][2],bs[60];

ll shift(ll x,int t){return (x>>t)|((x&((1<<t)-1))<<(m-t));}

ll getans(vector<ll> b,ll dep,ll now){
	if(now>r) return 0;
	ll res=0;
	if(b.size()==1){
		for(int i=0;i<m;i++){
			if(b[0]&(1ll<<i)){
				if(now<=r%pw[dep]) res+=dp[0][dep][i][0]+dp[0][dep][i][1];
				else res+=dp[0][dep][i][0];
				if(now<=l%pw[dep]) res-=dp[1][dep][i][0]+dp[1][dep][i][1];
				else res-=dp[1][dep][i][0];
			}
		}
		return res;
	}
	for(int i=0;i<d;i++){
		vector<ll> nb(0);
		int tmp=i; ll mask=(1<<m)-1;
		for(int j=0;j<b.size();j++){
			mask&=shift(b[j],a[tmp]);
			tmp++;
			if(tmp==m){
				tmp=0;
				nb.push_back(mask);
				mask=(1<<m)-1;
			}
		}
		if(tmp!=0) nb.push_back(mask);
		res+=getans(nb,dep+1,now+pw[dep]*i);
	}
	return res;
}

void getdp(ll x,int t){
	int cnt=0;
	memset(bs,0,sizeof(bs));
	for(;x;x/=d) bs[cnt++]=x%d;
	cnt=59;
	dp[t][cnt][0][1]=1;
	for(int i=cnt;i>=1;i--)
		for(int j=0;j<m;j++)
			for(int c=0;c<=1;c++)
				for(int num=0;num<(c?bs[i-1]+1:d);num++)
					dp[t][i-1][(j+num)%m][c&(num==bs[i-1])]+=dp[t][i][j][c];
}

int main(){
	d=readint(); m=readint();
	pw[0]=1;
	for(int i=1;pw[i-1]<=1e18/d;i++) pw[i]=pw[i-1]*d;
	for(int i=0;i<d;i++) a[i]=readint();
	n=readint();
	vector<ll> b(0);
	for(int i=1;i<=n;i++) b.push_back((1ll<<(readint()+1))-1);
	l=readint()-1; r=readint()-n+1;
	getdp(r,0); getdp(l,1);
	printf("%lld\n",getans(b,0,0));
	return 0;
}

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template <typename T> bool chkmax(T &x,T y){return x<y?x=y,true:false;}
template <typename T> bool chkmin(T &x,T y){return x>y?x=y,true:false;}

ll readint(){
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,d,m; ll l,r;
ll pw[105],a[30],dp[2][65][60][2],bs[65],pr[105],pl[105];

ll shift(ll x,int t){return (x>>t)|((x&((1ll<<t)-1))<<(m-t));}

ll getans(vector<ll> &b,ll dep,ll now){
	if(now>r) return 0;
	ll res=0;
	if(b.size()==1){
		for(int i=0;i<m;i++){
			if(b[0]&(1ll<<i)){
				if(now<=pr[dep]) res+=dp[0][dep][i][0]+dp[0][dep][i][1];
				else res+=dp[0][dep][i][0];
				if(now<=pl[dep]) res-=dp[1][dep][i][0]+dp[1][dep][i][1];
				else res-=dp[1][dep][i][0];
			}
		}
		return res;
	}
	for(int i=0;i<d;i++){
		vector<ll> nb(0);
		int tmp=i; ll mask=(1ll<<m)-1;
		for(int j=0;j<b.size();j++){
			mask&=shift(b[j],a[tmp]);
			tmp++;
			if(tmp==d){
				tmp=0;
				nb.push_back(mask);
				mask=(1ll<<m)-1;
			}
		}
		if(tmp!=0) nb.push_back(mask);
		res+=getans(nb,dep+1,now+pw[dep]*i);
	}
	return res;
}

void getdp(ll x,int t){
	int cnt=0;
	memset(bs,0,sizeof(bs));
	for(;x;x/=d) bs[cnt++]=x%d;
	cnt=60;
	dp[t][cnt][0][1]=1;
	for(int i=cnt;i>=1;i--)
		for(int j=0;j<m;j++)
			for(int c=0;c<=1;c++)
				for(int num=0;num<(c?bs[i-1]+1:d);num++)
					dp[t][i-1][(j+a[num])%m][c&(num==bs[i-1])]+=dp[t][i][j][c];
}

int main(){
	d=readint(); m=readint();
	pw[0]=1;
	for(int i=1;pw[i-1]<=(1e18+10)/d;i++) pw[i]=pw[i-1]*d;
	for(int i=1;i<=100;i++) if(!pw[i]) pw[i]=1e18+10;
	for(int i=0;i<=100;i++) pr[i]=r%pw[i];
	for(int i=0;i<=100;i++) pl[i]=l%pw[i];
	for(int i=0;i<d;i++) a[i]=readint();
	n=readint();
	vector<ll> b(0);
	for(int i=1;i<=n;i++) b.push_back((1ll<<(readint()+1))-1);
	l=readint()-2; r=readint()-n;
	getdp(r,0); if(l>=0) getdp(l,1);
	printf("%lld\n",getans(b,0,0));
	return 0;
}

#include<bits/stdc++.h>

#define pb push_back
#define mp make_pair
#define fi first
#define se second

using namespace std;

typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;

template <typename T> bool chkmax(T &x,T y){return x<y?x=y,true:false;}
template <typename T> bool chkmin(T &x,T y){return x>y?x=y,true:false;}

ll readint(){
	ll x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
	return x*f;
}

int n,d,m; ll l,r;
ll pw[105],a[30],dp[2][60][60][2],bs[60];

ll shift(ll x,int t){return (x>>t)|((x&((1ll<<t)-1))<<(m-t));}

ll getans(vector<ll> b,ll dep,ll now){
	if(now>r||!pw[dep]) return 0;
	ll res=0;
	if(b.size()==1){
		for(int i=0;i<m;i++){
			if(b[0]&(1ll<<i)){
				int ttmp=0;
				if(now<=r%pw[dep]) res+=dp[0][dep][i][0]+dp[0][dep][i][1];
				else res+=dp[0][dep][i][0];
				if(now<=l%pw[dep]) res-=dp[1][dep][i][0]+dp[1][dep][i][1];
				else res-=dp[1][dep][i][0];
			}
		}
		return res;
	}
	for(int i=0;i<d;i++){
		vector<ll> nb(0);
		int tmp=i; ll mask=(1ll<<m)-1;
		for(int j=0;j<b.size();j++){
			mask&=shift(b[j],a[tmp]);
			tmp++;
			if(tmp==d){
				tmp=0;
				nb.push_back(mask);
				mask=(1ll<<m)-1;
			}
		}
		if(tmp!=0) nb.push_back(mask);
		res+=getans(nb,dep+1,now+pw[dep]*i);
	}
	return res;
}

void getdp(ll x,int t){
	int cnt=0;
	memset(bs,0,sizeof(bs));
	for(;x;x/=d) bs[cnt++]=x%d;
	cnt=59;
	dp[t][cnt][0][1]=1;
	for(int i=cnt;i>=1;i--)
		for(int j=0;j<m;j++)
			for(int c=0;c<=1;c++)
				for(int num=0;num<(c?bs[i-1]+1:d);num++)
					dp[t][i-1][(j+a[num])%m][c&(num==bs[i-1])]+=dp[t][i][j][c];
}

int main(){
	d=readint(); m=readint();
	pw[0]=1;
	for(int i=1;pw[i-1]<=1e18/d;i++) pw[i]=pw[i-1]*d;
	for(int i=0;i<d;i++) a[i]=readint();
	n=readint();
	vector<ll> b(0);
	for(int i=1;i<=n;i++) b.push_back((1ll<<(readint()+1))-1);
	l=readint()-2; r=readint()-n;
	getdp(r,0); getdp(l,1);
	printf("%lld\n",getans(b,0,0));
	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = last == 0 ? 0 : (num[i - have] >> (64 - last));
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		if (last) ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	int rans = 0;
	for (int i = l; i <= r; i++) {
		rans += get(i);
	}
	for (int i = l >> 6; i << 6 <= r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) {
			a &= ((r & 63) == 63 ? 0 : (1ull << ((r & 63) + 1))) - 1;
		}
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 2ll, other.len - 1));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int GetVal(ll no) {
	int ans = 0;
	while(no) {
		ans += multi[no % d];
		no /= d;
	}
	return ans;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
			dp[0][i].len = 1;
			dp[0][i].cnt = n == 1 && orig[0] >= i;
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}

//			vi temp(dp[index][0].len, 0);
//			for (int j = 0; j < dp[index][0].len; j++) {
//				for (int rj = j; rj; rj /= d) temp[j] += multi[rj % d];
//				temp[j] %= m;
//			}
//
//		for (int i = 0; i < m; i++) {
//			for (int j = 0; j < n - 1; j++) {
//				bool can = true;
//				int fail = 0;
//				for (int k = 0; k < min1(dp[index][0].len, n - 1ll, j + 1); k++) {
//					can &= orig[n - 1 - j + k] >= (temp[k] + i) % m;
//					if (can == false) {
//						fail = k;
//						break;
//					}
//				}
//				if (index == 2 && i == 35 && j == 396) {
//					cout << 1 << endl;
//				}
//				if (dp[index][i].prefix.get(j) != can) {
//					cout << index << ' ' << i << ' ' << j << ' ' << fail << endl;
//				}
//			}
//		}

	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1 << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = num[i - have] >> (64 - last);
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	for (int i = l >> 6; i << 6 < r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) a &= (1 << (r & 63)) - 1;
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	int cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0, n - 1 - this->len), min(n - 1, other.len));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	int index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
			dp[0][i].len = 1;
			dp[0][i].cnt = n == 1 && orig[0] >= i;
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}
	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = last == 0 ? 0 : (num[i - have] >> (64 - last));
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		if (last) ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	int rans = 0;
	for (int i = l; i <= r; i++) {
		rans += get(i);
	}
	for (int i = l >> 6; i << 6 <= r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) {
			a &= ((r & 63) == 63 ? 0 : (1ull << ((r & 63) + 1))) - 1;
		}
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 2ll, other.len - 1));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int GetVal(ll no) {
	int ans = 0;
	while(no) {
		ans += multi[no % d];
		no /= d;
	}
	return ans;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
		dp[0][i].len = 1;
		dp[0][i].cnt = n == 1 && orig[0] >= i;
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}

//			vi temp(dp[index][0].len, 0);
//			for (int j = 0; j < dp[index][0].len; j++) {
//				for (int rj = j; rj; rj /= d) temp[j] += multi[rj % d];
//				temp[j] %= m;
//			}
//
//		for (int i = 0; i < m; i++) {
//			for (int j = 0; j < n - 1; j++) {
//				bool can = true;
//				int fail = 0;
//				for (int k = 0; k < min1(dp[index][0].len, n - 1ll, j + 1); k++) {
//					can &= orig[n - 1 - j + k] >= (temp[k] + i) % m;
//					if (can == false) {
//						fail = k;
//						break;
//					}
//				}
//				if (index == 2 && i == 35 && j == 396) {
//					cout << 1 << endl;
//				}
//				if (dp[index][i].prefix.get(j) != can) {
//					cout << index << ' ' << i << ' ' << j << ' ' << fail << endl;
//				}
//			}
//		}

	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = num[i - have] >> (64 - last);
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	for (int i = l >> 6; i << 6 < r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) a &= (1ull << (r & 63)) - 1;
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 1ll, other.len));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
			dp[0][i].len = 1;
			dp[0][i].cnt = n == 1 && orig[0] >= i;
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}
	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;
	if (d == 20 && m == 60 && orig[0] == 59 && n == 3000) {
		cout << l << ' ' << r << endl;
	}

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = num[i - have] >> (64 - last);
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	for (int i = l >> 6; i << 6 < r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) a &= (1ull << (r & 63)) - 1;
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 1ll, other.len));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
			dp[0][i].len = 1;
			dp[0][i].cnt = n == 1 && orig[0] >= i;
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}
	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;
	if (d == 20 && m == 60 && orig[0] == 59) {
		cout << l << ' ' << r << endl;
	}

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T d) { return max1(max1(a, b, c), d); }
template <class T> inline T max1(T a, T b, T c, T d, T e) { return max1(max1(a, b, c, d), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T d) { return min1(min1(a, b, c), d); }
template <class T> inline T min1(T a, T b, T c, T d, T e) { return min1(min1(a, b, c, d), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxn = 30010;

int n;

struct bset {
	ull num[maxn / 64 + 1];
	int l;
	bool default_bit;
	bset(int a = 30001, ull orig = 0) : l(a) {
		num[0] = orig;
		default_bit = false;
	}
	inline void init(int a) {
		l = a;
		for(int i = 0; i << 6 < l; i++)
			num[i] = 0 - default_bit;
	}
	inline void operator = (const int &a);
	inline void operator = (const ll &a);
	inline void operator = (const ull &a);
	inline void operator = (const bset &a);
	inline void operator |= (const bset &a);
	inline void operator &= (const bset &a);
	inline void operator ^= (const bset &a);
	inline bset operator | (const bset &a);
	inline bset operator & (const bset &a);
	inline bset operator ^ (const bset &a);
	inline bset operator << (const int &l);
	inline bset operator >> (const int &l);
	inline bool get(int loc) const;
	inline void set(int loc, int f);
	inline void output(int l, int r) const;
	inline int count(int l, int r) const;
};

inline void bset :: operator = (const int &a) {
	num[0] = a;
}
inline void bset :: operator = (const ll &a) {
	num[0] = a;
}
inline void bset :: operator = (const ull &a) {
	num[0] = a;
}
inline void bset :: operator = (const bset &a) {
	l = a.l;
	for(int i = 0, link = 0; i < a.l; i += 64, link++)
		num[link] = a.num[link];
}
inline bset bset :: operator << (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = 0; i <= have; i++) ans.num[i] = 0 - default_bit;
	if (default_bit) ans.num[have] = (1ull << last) - 1;
	for(int i = have; i << 6 < l; i++) {
		ans.num[i] |= num[i - have] << last;
		ans.num[i + 1] = num[i - have] >> (64 - last);
	}
	return ans;
}
inline bset bset :: operator >> (const int &l1) {
	bset ans(l);
	int have = l1 >> 6, last = l1 ^ (have << 6);
	for(int i = have; i << 6 < l; i++) {
		ans.num[i - have] = num[i] >> last;
		ans.num[i - have] |= num[i + 1] << (64 - last);
	}
	int ff = l - l1;
	for(; ff & 63; ff++) ans.set(ff, default_bit);
	for(; ff < l; ff += 1 << 6) ans.num[ff >> 6] = 0 - default_bit;
	return ans;
}
// based 0
inline bool bset :: get(int loc) const {
	int yu = (loc >> 6 << 6) ^ loc;
	return num[loc >> 6] & (1ull << yu);
}
// based 0
inline void bset :: set(int loc, int f) {
	int yu = (loc >> 6 << 6) ^ loc;
	if(f) {
		if(!(num[loc >> 6] & (1ull << yu)))
			num[loc >> 6] ^= 1ull << yu;
	}else if(num[loc >> 6] & (1ull << yu))
		num[loc >> 6] ^= 1ull << yu;
}
inline void bset :: operator |= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] |= a.num[i];
}
inline void bset :: operator &= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] &= a.num[i];
}
inline void bset :: operator ^= (const bset &a) {
	for(int i = 0; i << 6 < l;  i++) num[i] ^= a.num[i];
}
inline bset bset :: operator | (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] | a.num[i];
	return ans;
}
inline bset bset :: operator & (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] & a.num[i];
	return ans;
}
inline bset bset :: operator ^ (const bset &a) {
	bset ans(l);
	for(int i = 0; i << 6 < l;  i++) ans.num[i] = num[i] ^ a.num[i];
	return ans;
}
inline void bset :: output(int l, int r) const {
	for(int i = l; i <= r; i++) if(get(i)) printf("1");
	else printf("0");
	printf("\n");
	fflush(stdout);
}
inline int bset :: count(int l, int r) const {
	int ans = 0;
	if (r < l) return 0;
	for (int i = l >> 6; i << 6 < r; i++) {
		ull a = num[i];
		if (i == l >> 6) a &= ull(-1) << (l & 63);
		if ((i + 1) << 6 > r) a &= (1ull << (r & 63)) - 1;
		ans += bitnum(a);
	}
	return ans;
}

struct State {
	bset prefix, suffix;
	ll cnt, len;
	State() {
		prefix.l = suffix.l = n - 1;
		cnt = 0;
		len = 1;
	}
	State operator + (State &other) {
		State ans;
		ans.cnt = this->cnt + other.cnt;
		ans.len = this->len + other.len;
		ans.prefix = this->prefix;
		if (this->len < n - 1) {
			other.prefix.default_bit = true;
			ans.prefix = this->prefix & (other.prefix << this->len);
			other.prefix.default_bit = false;
		}
		ans.suffix = other.suffix;
		if (other.len < n - 1) {
			this->suffix.default_bit = true;
			ans.suffix = other.suffix & (this->suffix >> other.len);
			this->suffix.default_bit = false;
		}
		ans.cnt += (this->suffix & other.prefix).count(
				max(0ll, n - 1 - this->len), min(n - 1ll, other.len));
		return ans;
	}
};

State dp[70][70];
int orig[maxn], multi[22];
ll l, r;
int d, m;

ll GetAns(ll r) {
	ll index = 0, len = 1;
	while(1.0 * len * d <= r) {
		index++;
		len *= d;
	}
	State ans;
	ans = dp[index][0];
	int have = 0;
	r -= len;
	int presum = 0;
	while (index >= 0 && r) {
		int i = !have;
		for (; r >= len; r -= len, i++) {
			ans = ans + dp[index][(presum + multi[i]) % m];
		}
		have = 1;
		index--;
		len /= d;
		presum += multi[i];
	}
	return ans.cnt;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);
	for (int i = 0; i < d; i++) scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++) scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);

	for (int i = 0; i < m; i++) {
		for (int j = 0; j < n - 1; j++) {
			dp[0][i].prefix.l = dp[0][i].suffix.l = n - 1;
			dp[0][i].prefix.set(j, orig[n - 1 - j] >= i);
			dp[0][i].suffix.set(j, orig[n - 2 - j] >= i);
			dp[0][i].len = 1;
			dp[0][i].cnt = n == 1 && orig[0] >= i;
		}
	}
	for (ll total_len = 1, index = 0; ; total_len *= d, index++) {
		for (int i = 0; i < m; i++) {
			dp[index + 1][i] = dp[index][i];
			for (int j = 1; j < d; j++) {
				dp[index + 1][i] = dp[index + 1][i] + dp[index][(i + multi[j]) % m];
			}
		}
		if (1.0 * total_len * d > r) {
			break;
		}
	}

	if (r - l < n - 1) {
		cout << 0 << endl;
		return 0;
	}
	cout << GetAns(r) - GetAns(l + n - 2) << endl;

	return 0;
}

// #define DEBUG
//#define USEPB_DS
#define USETR1
#define CPPELEVEN
#define GPP

/*
 * temp.cpp
 *
 *  Created on: 2012-7-18
 *      Author: BSBandme
 */
//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include <iostream>
#include <fstream>
#include <string.h>
#include <cstdio>
#include <algorithm>
#include <string>
#include <vector>
#include <queue>
#include <cassert>
#include <list>
#include <iomanip>
#include <math.h>
#include <deque>
#include <utility>
#include <map>
#include <set>
#include <bitset>
#include <numeric>
#include <climits>
#include <cctype>
#include <cmath>
#include <cstdlib>
#include <ctime>
#include <functional>
#include <sstream>
#include <tuple>

using namespace std;

#ifndef CPPELEVEN
#ifdef USETR1
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#endif
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef USEPB_DS
#include <ext/pb_ds/priority_queue.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
// binomial_heap_tag, rc_binomial_heap_tag, thin_heap_tag, binary_heap_tag
typedef __gnu_pbds::priority_queue<int, greater<int>, pairing_heap_tag> pq_type;
// splay_tree_tag, ov_tree_tag
typedef tree <int, null_type, less <int>, rb_tree_tag, tree_order_statistics_node_update> tree_type;
#endif

#define mpr make_pair
typedef unsigned int ui;
typedef unsigned long long ull;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <double, double> pdd;
typedef vector <int> vi;
typedef vector <ll> vll;
typedef vector <double> vd;
typedef vector <string> vs;
typedef map <string, int> mpsi;
typedef map <double, int> mpdi;
typedef map <int, int> mpii;

const double pi = acos(0.0) * 2.0;
const long double eps = 1e-10;
const int step[8][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}, {-1, 1}, {1, 1}, {1, -1}, {-1, -1}};

template <class T> inline T abs1(T a) {return a < 0 ? -a : a;}

#ifndef CPPELEVEN
template <class T> inline T max1(T a, T b) { return b < a ? a : b; }
template <class T> inline T max1(T a, T b, T c) { return max1(max1(a, b), c); }
template <class T> inline T max1(T a, T b, T c, T pow2) { return max1(max1(a, b, c), pow2); }
template <class T> inline T max1(T a, T b, T c, T pow2, T e) { return max1(max1(a, b, c, pow2), e); }
template <class T> inline T min1(T a, T b) { return a < b ? a : b; }
template <class T> inline T min1(T a, T b, T c) { return min1(min1(a, b), c); }
template <class T> inline T min1(T a, T b, T c, T pow2) { return min1(min1(a, b, c), pow2); }
template <class T> inline T min1(T a, T b, T c, T pow2, T e) { return min1(min1(a, b, c, pow2), e); }
#else
template <typename t, typename t1>
t min1(t a, t1 b) { return a < b ? a : b; }
template <typename t, typename... arg>
t min1(t a, arg... arr) { return min1(a, min1(arr...)); }
template <typename t, typename t1>
t max1(t a, t1 b) { return a > b ? a : b; }
template <typename t, typename... arg>
t max1(t a, arg... arr) { return max1(a, max1(arr...)); }
#endif

inline int jud(double a, double b){
	if(abs(a) < eps && abs(b) < eps) return 0;
	else if(abs1(a - b) / max(abs1(a), abs1(b)) < eps) return 0;
	if(a < b) return -1;
	return 1;
}
template <typename t> inline int jud(t a, t b){
	if(a < b) return -1;
	if(a == b) return 0;
	return 1;
}

// f_lb == 1代表返回相同的一串的左边界，f_small == 1代表返回如果没有寻找的值返回小的数
template <typename it, typename t1>
inline int find(t1 val, it a, int na, bool f_small = 1, bool f_lb = 1){
	if(na == 0) return 0;
	int be = 0, en = na - 1;
	if(*a <= *(a + na - 1)){
		if(f_lb == 0) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != 1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != -1) en = mid;
			else be = mid + 1;
		}
		if(f_small && jud(*(a + be), val) == 1) be--;
		if(!f_small && jud(*(a + be), val) == -1) be++;
	} else {
		if(f_lb) while(be < en){
			int mid = (be + en + 1) / 2;
			if(jud(*(a + mid), val) != -1) be = mid;
			else en = mid - 1;
		}else while(be < en){
			int mid = (be + en) / 2;
			if(jud(*(a + mid), val) != 1) en = mid;
			else be = mid + 1;
		}
		if(!f_small && jud(*(a + be), val) == -1) be--;
		if(f_small && jud(*(a + be), val) == 1) be++;
	}
	return be;
}

template <class T> inline T lowb(T num) {return num & (-num); }
#ifdef GPP
inline int bitnum(ui nValue) { return __builtin_popcount(nValue); }
inline int bitnum(int nValue) { return __builtin_popcount(nValue); }
inline int bitnum(ull nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitnum(ll nValue) { return __builtin_popcount(nValue) + __builtin_popcount(nValue >> 32); }
inline int bitmaxl(ui a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(int a) { if(a == 0) return 0; return 32 - __builtin_clz(a); }
inline int bitmaxl(ull a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
inline int bitmaxl(ll a) { int temp = a >> 32; if(temp) return 32 - __builtin_clz(temp) + 32; return bitmaxl(int(a)); }
#else
#endif

long long pow(long long n, long long m, long long mod = 0){
	if(m < 0) return 0;
	long long ans = 1;
	long long k = n;
	while(m){
		if(m & 1) {
			ans *= k;
			if(mod) ans %= mod;
		}
		k *= k;
		if(mod) k %= mod;
		m >>= 1;
	}
	return ans;
}

#define  MOD 1000000007
template <class t1, class t2>
inline void add(t1 &a, t2 b, int mod = -1) {
	if(mod == -1) mod = MOD;
	a += b;
	while(a >= mod) a -= mod;
	while(a < 0) a += mod;
}
template <class t>
void output1(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		cerr << arr[i] << ' ';
	cerr << endl;
}
template <class t>
void output2(t arr) {
	for(int i = 0; i < (int)arr.size(); i++)
		output1(arr[i]);
}

//....................密..........封..........线..........下..........禁..........止..........hack...............................................

const int maxd = 22;
const int maxm = 65;
const int maxl = 30010;
#define maxn 400010
int d, m, n;
int multi[maxd], all_multi[maxd * maxl];
int orig[maxl];
int str[maxn], sa[maxn], h[maxn], rk[maxn];
ll l, r;
int rl = 1, rlog = 0;

//待排序的字符串放在r 数组中，从r[0]到r[n-1]，长度为n，且单个字符最大值小于m。sa为结果
int wa[maxn * 2],wb[maxn * 2],wv[maxn * 2],ws1[maxn * 2];
int cmp(int *r,int a,int b,int l)
{return r[a]==r[b]&&r[a+l]==r[b+l];}
void da(int *r,int *sa,int n,int m) {
	 int i,j,p,*x=wa,*y=wb,*t;
	 for(i=0;i<m;i++) ws1[i]=0;
	 for(i=0;i<n;i++) ws1[x[i]=r[i]]++;
	 for(i=1;i<m;i++) ws1[i]+=ws1[i-1];
	 for(i=n-1;i>=0;i--) sa[--ws1[x[i]]]=i;
	 for(j=1,p=1;p<=n;j*=2,m=p) {
	   for(p=0,i=n-j;i<n;i++) y[p++]=i;
	   for(i=0;i<n;i++) if(sa[i]>=j) y[p++]=sa[i]-j;
	   for(i=0;i<n;i++) wv[i]=x[y[i]];
	   for(i=0;i<m;i++) ws1[i]=0;
	   for(i=0;i<n;i++) ws1[wv[i]]++;
	   for(i=1;i<m;i++) ws1[i]+=ws1[i-1];
	   for(i=n-1;i>=0;i--) sa[--ws1[wv[i]]]=y[i];
	   for(t=x,x=y,y=t,p=2,x[sa[0]]=1,i=1;i<n;i++)
	   x[sa[i]]=cmp(y,sa[i-1],sa[i],j)?p-1:p++;
	 }
	 return;
}
void calheight(int *r, int *sa, int*rank, int*height,int n) {
	 int i,j,k=0;
	 for(i=0; i<n;i++) rank[sa[i]]=i;
	 for(i=0;i<n;i++){
		 if(rank[i] == 0) continue;
		 for(k?k--:0,j=sa[rank[i]-1]; i + k < n && j + k < n && r[i+k]==r[j+k];k++);
		 height[rank[i] - 1]=k;
	 }
	 return;
}
int pow2[20];
int logg[maxn];
int st[maxn][22];
// h为height数组，n为长度
void InitRMQ(const int &n, int *h) {
	int i, j;
	for( pow2[0]=1, i=1; i < 21; ++i ) pow2[i] = 2*pow2[i-1];
	for( i=0; i < n; ++i ) st[i][0] = h[i];
	int k = int( log(double(n))/log(2) ) + 1;
	logg[0] = 0; logg[1] = 0;
	for(int i = 2; i <= n; i++) logg[i] = logg[i / 2] + 1;
	for( j=1; j < k; ++j )
		for( i=0; i < n; ++i ) {
			if( i+pow2[j-1]-1 < n ){
				st[i][j] = min(st[i][j-1],
						st[i+pow2[j-1]][j-1]);
			}
			else break; // st[i][j] = st[i][j-1];
		}
}
//x, y为rank的序号(在sa中为x和y位置的lcp应为quelcp(x, y))
inline int quelcp(int x, int y) {
	int k = logg[y - x + 1];
	return min(st[x][k], st[y-pow2[k]+1][k]);
}
//此为真正的quelcp(y--）
inline int quelcp1(int x, int y) {
	if(y < x) swap(x, y);
	y--;
	int k = logg[y - x + 1];
	return min(st[x][k], st[y-pow2[k]+1][k]);
}
//querange为询问rank序号为no的位置与之lcp >= height的左右边界
inline pii querange(int no, int height, int l) {
	int be1 = 0, en1 = no - 1;
	while(be1 < en1) {
		int height1 = (be1 + en1) / 2;
		if(quelcp(height1, no - 1) < height) be1 = height1 + 1;
		else en1 = height1;
	}
	if(quelcp(be1, no - 1) < height) be1++;
	int from = min1(be1, no);
	be1 = no; en1 = l - 1;
	while(be1 < en1) {
		int height1 = (be1 + en1 + 1) / 2;
		if(quelcp(no, height1) < height) en1 = height1 - 1;
		else be1 = height1;
	}
	if(quelcp(no, be1) < height) be1--;
	int to = max1(be1 + 1, no);
	return mpr(from, to);
}

ll GetAns(ll maxl) {
	vi maxl_v;
	for (ll rmaxl = maxl; rmaxl || maxl_v.size() < rlog; maxl_v.push_back(rmaxl % d), rmaxl /= d);
	ll dp[70][2][maxm][maxm];
	memset(dp, 0, sizeof(dp));
	dp[maxl_v.size()][1][0][multi[1]] = 1;
	for (int i = maxl_v.size() - 1; i >= rlog; i--) {
		for (int cate = 0; cate < 2; cate++)
			for (int sum_now = 0; sum_now < maxm; sum_now++)
				for (int sum_nxt = 0; sum_nxt < maxm; sum_nxt++)
					if (dp[i + 1][cate][sum_now][sum_nxt]) {
						for (int s = 0; s <= (cate ? maxl_v[i] : d - 1); s++) {
							int sum_now1 = sum_now + multi[s];
							int sum_nxt1 =
									(s == d - 1
											? sum_nxt + multi[0]
											: sum_now + multi[s + 1]);
							sum_now1 %= m;
							sum_nxt1 %= m;
							int cate1 = (cate && s == maxl_v[i]);
							dp[i][cate1][sum_now1][sum_nxt1] +=
									dp[i + 1][cate][sum_now][sum_nxt];
						}
					}
	}
 	ll ans = 0;
	for (int i = 0; i < rl; i++) {
		int can = 1;
		if (i > maxl % rl) {
			can = 0;
		}
		int pre_sum = 0;
		for (int j = i, k = 0; k < rlog; k++) {
			pre_sum += multi[j % d];
			j /= d;
		}
		pre_sum %= m;
		for (int first_bit = 0; first_bit < orig[0]; first_bit++) {
			for (int sum_nxt = 0; sum_nxt < maxm; sum_nxt++) {
				int rbit = first_bit - pre_sum + m;
				rbit %= m;
				ans += dp[rlog][can][rbit][sum_nxt];
			}
		}
		ll rsum = 0;
		for (int cate = 0; cate <= can; cate++) for (int j = 0; j < m; j++)
			rsum += dp[rlog][cate][(orig[0] - pre_sum + m) % m][j];
		if (!rsum) {
			continue;
		}

		int lcp = quelcp1(rk[rl - 1], rk[i]);
		if (lcp < rl - i - 1) {
			if (lcp >= n - 1) {
				ans += rsum;
			} else {
				int str_bit = (orig[lcp] + str[i + lcp] - 1) % m;
				if (str_bit < orig[lcp + 1]) {
					ans += rsum;
				}
			}
		} else {
			if (n <= rl - i) {
				ans += rsum;
			} else {
				int pre_sum1 = 0;
				for (int j = 0; j < rlog; j++) {
					pre_sum1 += multi[0];
					pre_sum1 %= m;
				}
				for (int sum_nxt1 = 0; sum_nxt1 < orig[rl - i]; sum_nxt1++) {
					int rsum_nxt = (sum_nxt1 - pre_sum1 + m) % m;
					for (int cate = 0; cate <= can; cate++)
						ans += dp[rlog][cate][(orig[0] - pre_sum + m) % m][rsum_nxt];
				}
				rsum = 0;
				for (int cate = 0; cate <= can; cate++)
					rsum += dp[rlog][cate]
									 [(orig[0] - pre_sum + m) % m][(orig[rl - i] - pre_sum1 + m) % m];
				lcp = quelcp1(rk[rl - i + rl - 1], rk[0]);
				if (lcp >= n - (rl - i) - 1) {
					ans += rsum;
				} else {
					int str_bit = (orig[rl - i + lcp] + str[lcp] - 1) % m;
					if (str_bit < orig[rl - i + lcp + 1]) {
						ans += rsum;
					}
				}
			}
		}
	}

	return ans;
}

int main() {

//............................不要再忘了检查maxn大小了！！！！BSBandme你个SB！！！！...................................................

	ios_base::sync_with_stdio(0);
	#ifdef DEBUG //......................................................................................................
	freopen("input.txt", "r", stdin);
	int __size__ = 256 << 20; // 256MB
	char *__p__ = (char*)malloc(__size__) + __size__;
	__asm__("movl %0, %%esp\n" :: "r"(__p__));
	#endif //...........................................................................................................

	scanf("%d%d", &d, &m);

	for (int i = 0; i < d; i++)
		scanf("%d", multi + i);
	scanf("%d", &n);
	for (int i = 0; i < n; i++)
		scanf("%d", orig + i);
	scanf("%I64d%I64d", &l, &r);
	l--, r--;

	for (; rl < n; rlog++, rl *= d) {
		for (int i = d - 1; i >= 0; i--) {
			for (int j = 0; j < rl; j++) {
				all_multi[i * rl + j] = (all_multi[j] + multi[i]) % m;
			}
		}
	}

	for (int i = 0; i < rl - 1; i++)
		str[i] = (all_multi[i + 1] - all_multi[i] + m) % m + 1;
	for (int i = 0; i < n - 1; i++)
		str[rl - 1 + i] = (orig[i + 1] - orig[i] + m) % m + 1;
	da(str, sa, rl + n - 2, m * 2 + 2);
	calheight(str, sa, rk, h, rl + n - 2);
	InitRMQ(rl + n - 2, h);

	cout << GetAns(r - n + 1) - GetAns(l - 1) << endl;

	return 0;
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MN = 30010;

int D, M, N;
int G[66], B[MN];
ll L, R;
unordered_map<ll, vector<int> > cnt;

ll shift(ll bit, int k) {
    return (bit >> k) + (1LL << (M - k)) * (bit & (1LL << k) - 1);
}

void solve(ll r, vector<ll> &X, int t) {

    //cout << "solve : " << r << endl;

    if(r <= 0) return;
    if(X.size() == 1) {
        if(cnt.find(r) == cnt.end()) {
            cnt[r] = vector<int>(M, 0);
        }
        for(int i = 0; i < M; i++) if(X[0] & (1LL << i)) cnt[r][i] += t;
        return;
    }

    int n = X.size();
    for(int i = 0; i < D; i++) {

        vector<ll> x((i + n - 1) / D + 1, (1LL << (M + 1)) - 1);
        for(int j = 0; j < n; j++) {
            x[ (i + j) / D ] &= shift(X[j], (i + j) % D);
        }

        solve((r - (i + n - 1) % D) / D, x, t);
    }
}

vector<int> A;

ll cc[66][66][2];
ll dp(int x, int b, int t) {
    if(x == -1) return b == 0;
    ll &ret = cc[x][b][t];
    if(ret != -1) return ret;

    ret = 0;
    for(int i = 0; i <= (t? A[x] : 9); i++) {
        ret += dp(x - 1, (b + M - G[i]) % M, t & (i == A[x]));
    }
    return ret;
}

void init(ll r) {
    A.clear();
    while(r) {
        A.push_back(r % 10);
        r /= 10;
    }

    memset(cc, -1, sizeof(cc));
}

int main() {
    scanf("%d %d", &D, &M);

    for(int i = 0; i < D; i++) {
        scanf("%d", &G[i]);
    }

    scanf("%d", &N);

    for(int i = 0; i < N; i++) {
        scanf("%d", &B[i]);
    }

    scanf("%lld %lld", &L, &R);
    L--; R--;

    vector<ll> X(N);
    for(int i = 0; i < N; i++) {
        X[i] = (1LL << (B[i] + 1)) - 1;
    }

    solve(L - 1, X, -1);
    solve(R, X, 1);

    ll ans = 0;
    for(auto it = cnt.begin(); it != cnt.end(); it++) {
        ll r = it->first;
        vector<int> X = it->second;

        init(r);
        for(int i = 0; i < M; i++) ans += dp((int)A.size() - 1, i, 1) * X[i];
    }
    printf("%lld", ans);
}

#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int MN = 30010;

int D, M, N;
int G[66], B[MN];
ll L, R;
unordered_map<ll, vector<int> > cnt;

ll shift(ll bit, int k) {
    return (bit >> k) + (1LL << (M - k)) * (bit & ((1LL << k) - 1));
}

void solve(ll r, vector<ll> &X, int t) {

    if(X.size() == 1) {
        if(cnt.find(r) == cnt.end()) {
            cnt[r] = vector<int>(M, 0);
        }
        for(int i = 0; i < M; i++) if(X[0] & (1LL << i)) cnt[r][i] += t;
        return;
    }
    if(r <= 0) return;

    int n = X.size();
    for(int i = 0; i < D; i++) {

        vector<ll> x((i + n - 1) / D + 1, (1LL << (M + 1)) - 1);
        for(int j = 0; j < n; j++) {
            x[ (i + j) / D ] &= shift(X[j], G[ (i + j) % D ]);
        }

        solve((r - (i + n - 1) % D) / D, x, t);
    }
}

vector<int> A;

ll cc[66][66][2];
ll dp(int x, int b, int t) {
    if(x == -1) return b == 0;
    ll &ret = cc[x][b][t];
    if(ret != -1) return ret;

    ret = 0;
    for(int i = 0; i <= (t? A[x] : D - 1); i++) {
        ret += dp(x - 1, (b + M - G[i]) % M, t & (i == A[x]));
    }
    return ret;
}

void init(ll r) {
    A.clear();
    while(r) {
        A.push_back(r % D);
        r /= D;
    }

    memset(cc, -1, sizeof(cc));
}

int main() {
    scanf("%d %d", &D, &M);

    for(int i = 0; i < D; i++) {
        scanf("%d", &G[i]);
    }

    scanf("%d", &N);

    for(int i = 0; i < N; i++) {
        scanf("%d", &B[i]);
    }

    scanf("%lld %lld", &L, &R);
    L--; R--;

    vector<ll> X(N);
    for(int i = 0; i < N; i++) {
        X[i] = (1LL << (B[i] + 1)) - 1;
    }

    solve(L + N - 2, X, -1);
    solve(R, X, 1);

    ll ans = 0;
    for(auto it = cnt.begin(); it != cnt.end(); it++) {
        ll r = it->first;
        vector<int> X = it->second;

        init(r);
        for(int i = 0; i < M; i++) ans += dp((int)A.size() - 1, i, 1) * X[i];
    }
    printf("%lld", ans);
}

#include<bits/stdc++.h>
#define mp std::make_pair

typedef long long ll;

const int N = 30010;
const int M = 110;
typedef std::pair <ll, ll> pii;
typedef std::pair <pii, ll> piii;

int gen[N];
ll power[N];
int d, m;
ll dp[M][M];
int digit[M];
std::vector <piii> res;
int n;

void dfs(int now, int max, ll remain, auto vec, ll &ans, ll r){
    if (now == max){
        return;
    }
    if ((int) vec.size() == 1){
        for (int i = 0; i < m; ++ i){
            if (vec[0] >> i & 1){
                auto u = std::lower_bound(res.begin(), res.end(), mp(mp(r / power[now] + (r % power[now] >= remain), (ll) i), -1ll));
                ans += u -> second;
            }
        }
        return;
    }
    for (int i = 0; i < d; ++ i){
        ll nremain = remain + power[now] * i;
        std::vector <ll> nvec;
        ll y = (1ll << m) - 1;
        for (int j = i, sz = vec.size(); j < i + sz; ++ j){
            ll x = vec[j - i], rem = gen[j % m];
            x = (x >> rem) | ((x & ((1ll << rem) - 1)) << (m - rem));
            y &= x;
            if (j == i + sz - 1 || j % m == m - 1){
                nvec.push_back(y);
                y = (1ll << m) - 1;
            }
        }
        dfs(now + 1, max, nremain, nvec, ans, r);
    }
}

ll solve(ll r, auto vec){
    if (r < 0) return 0;
    power[0] = 1;
    int max = 0;
    for (int i = 1; i < N; ++ i){
        power[i] = power[i - 1] * d;
        if (power[i - 1] > std::max((ll) n * d, r)){
            max = i;
            break;
        }
    }
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 1; i <= max; ++ i){
        for (int j = 0; j < m; ++ j){
            for (int k = 0; k < d; ++ k){
                dp[i][(j + k) % m] += dp[i - 1][j];
            }
        }
    }
    auto calc = [&](ll x, int remain){
        int cnt = 0;
        while (x){
            digit[cnt ++] = x % d;
            x /= d;
        }
        std::reverse(digit, digit + cnt);
        int nowremain = 0;
        ll ans = 0;
        for (int i = 0; i < cnt; ++ i){
            for (int j = 0; j < digit[i]; ++ j){
                int x = (nowremain + j * power[cnt - i - 1]) % m;
                x = (remain - x + m) % m;
                ans += dp[cnt - i - 1][x];
            }
            nowremain = (nowremain + digit[i] * power[cnt - i - 1]) % m;
        }
        return ans;
    };
    res.clear();
    for (int i = 0; i <= max; ++ i){
        for (int j = 0; j < m; ++ j){
            res.push_back({{r / power[i], j}, calc(r / power[i], j)});
            res.push_back({{r / power[i] + 1, j}, calc(r / power[i] + 1, j)});
        }
    }
    std::sort(res.begin(), res.end());
    ll ans = 0;
    dfs(0, max, 0, vec, ans, r);
    return ans;
}

int main(){
    scanf("%d%d", &d, &m);
    for (int i = 0; i < d; ++ i){
        scanf("%d", &gen[i]);
    }
    scanf("%d", &n);
    std::vector <ll> vec;
    for (int i = 0, x; i < n; ++ i){
        scanf("%d", &x);
        vec.push_back((1ll << (x + 1)) - 1);
    }
    ll l, r;
    scanf("%lld%lld", &l, &r);
    -- l, -- r;
    if (r - l + 1 < n){
        puts("0");
        return 0;
    }
    printf("%lld\n", solve(r - (n - 1), vec) - solve(l - 1, vec));
    return 0;
}

/**
 *    author:  tourist
 *    created: 04.01.2019 20:26:25
**/
#include <bits/stdc++.h>

using namespace std;

string to_string(string s) {
  return '"' + s + '"';
}

string to_string(const char* s) {
  return to_string((string) s);
}

string to_string(bool b) {
  return (b ? "true" : "false");
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A>
string to_string(A v) {
  bool first = true;
  string res = "{";
  for (const auto &x : v) {
    if (!first) {
      res += ", ";
    }
    first = false;
    res += to_string(x);
  }
  res += "}";
  return res;
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cerr << " " << to_string(H);
  debug_out(T...);
}

#ifdef LOCAL
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; i++) {
    cin >> gen[i];
  }
  int n;
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; i++) {
    cin >> b[i];
  }
  const int MAX = 30010;
  struct State {
    bitset<MAX> left;
    bitset<MAX> right;
    long long len;
    long long res;
  };
  auto dbg = [&](const State& a) {
    for (int i = 1; i < n; i++) cerr << a.left[i];
    cerr << " ";
    for (int i = 1; i < n; i++) cerr << a.right[i];
    cerr << " ";
    cerr << a.len << " " << a.res << '\n';
  };
  bitset<MAX> all;
  for (int i = 1; i < n; i++) all.set(i);
  auto Unite = [&](const State& a, const State& b) -> State {
    State c;
    c.len = a.len + b.len;
    c.res = a.res + b.res;
    c.left = a.left;
    c.right = b.right;
    if (a.len < n - 1) {
      c.left &= (b.left >> a.len) | (all << (n - 1 - a.len));
    }
    if (b.len < n - 1) {
      c.right &= (a.right << b.len) | (all >> (n - 1 - b.len));
    }
    if (a.len + b.len >= n) {
      bitset<MAX> d = a.right & b.left;
      if (a.len < n - 1) {
        d &= (all >> (n - 1 - a.len));
      }
      if (b.len < n - 1) {
        d &= (all << (n - 1 - b.len));
      }
      c.res += d.count();
    }
    return c;
  };
  auto calc = [&](long long up) -> long long {
    if (up < n) {
      return 0;
    }
    vector<vector<State>> states(1, vector<State>(m));
    for (int i = 0; i < m; i++) {
      states[0][i].len = 1;
      if (n == 1) {
        states[0][i].res = b[0] >= i;
      } else {
        for (int j = 1; j < n; j++) {
          if (b[j] >= i) {
            states[0][i].left.set(j);
          }
        }
        for (int j = 1; j < n; j++) {
          if (b[j - 1] >= i) {
            states[0][i].right.set(j);
          }
        }
      }
//      dbg(states[0][i]);
    }
    long long z = 1;
    while (z <= up / d) {
      int sz = (int) states.size();
      states.resize(sz + 1);
      states[sz].resize(m);
      for (int i = 0; i < m; i++) {
        State cur = states[sz - 1][i];
        for (int j = 1; j < d; j++) {
          cur = Unite(cur, states[sz - 1][(i + gen[j]) % m]);
        }
        states[sz][i] = cur;
//        dbg(states[sz][i]);
      }
      z *= d;
    }
    State res;
    int any = 0;
    int shift = 0;
    for (int i = (int) states.size() - 1; i >= 0; i--) {
      z = 1;
      for (int j = 0; j < i; j++) {
        z *= d;
      }
      for (int j = 0; j < m; j++) {
        if (up >= z) {
          if (!any) res = states[i][(shift + gen[j]) % m];
          else res = Unite(res, states[i][(shift + gen[j]) % m]);
          any = 1;
          up -= z;
        } else {
          shift = (shift + gen[j]) % m;
          break;
        }
      }
    }
    return res.res;
  };
  long long L, R;
  cin >> L >> R;
  cout << calc(R) - calc(L + n - 2) << '\n';
  return 0;
}

/**
 *    author:  tourist
 *    created: 04.01.2019 20:26:25
**/
#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int d, m;
  cin >> d >> m;
  vector<int> gen(d);
  for (int i = 0; i < d; i++) {
    cin >> gen[i];
  }
  int n;
  cin >> n;
  vector<int> b(n);
  for (int i = 0; i < n; i++) {
    cin >> b[i];
  }
  const int MAX = 30010;
  struct State {
    bitset<MAX> left;
    bitset<MAX> right;
    long long len;
    long long res;
  };
  bitset<MAX> all;
  for (int i = 0; i < MAX; i++) all.set(1);
  auto Unite = [&](const State& a, const State& b) -> State {
    State c;
    c.len = a.len + b.len;
    c.res = a.res + b.res;
    c.left = a.left;
    c.right = b.right;
    if (a.len < n - 1) {
      c.left &= (b.left >> a.len);
    }
    if (b.len < n - 1) {
      c.right &= (a.right << b.len);
    }
    if (a.len + b.len >= n) {
      bitset<MAX> d = a.right & b.left;
      long long bound = min(a.len, b.len);
      if (bound < n - 1) {
        d &= (all >> ((MAX - 1) - bound));
      }
      c.res += d.count();
    }
    return c;
  };
  auto calc = [&](long long up) -> long long {
    if (up < n) {
      return 0;
    }
    vector<vector<State>> states(1, vector<State>(m));
    for (int i = 0; i < m; i++) {
      for (int j = 1; j < n; j++) {
        if (b[j] >= i) {
          states[0][i].left.set(j);
        }
      }
      for (int j = 1; j < n; j++) {
        if (b[j - 1] >= i) {
          states[0][i].right.set(j);
        }
      }
    }
    long long z = 1;
    while (z <= up / d) {
      int sz = (int) states.size();
      states.resize(sz + 1);
      states[sz].resize(m);
      for (int i = 0; i < m; i++) {
        State cur = states[sz - 1][i];
        for (int j = 1; j < d; j++) {
          cur = Unite(cur, states[sz - 1][(i + gen[j]) % m]);
        }
        states[sz][i] = cur;
      }
      z *= d;
    }
    State res;
    int any = 0;
    int shift = 0;
    for (int i = (int) states.size() - 1; i >= 0; i--) {
      z = 1;
      for (int j = 0; j < i; j++) {
        z *= d;
      }
      for (int j = 0; j < m; j++) {
        if (up >= z) {
          if (!any) res = states[i][(shift + gen[j]) % m];
          else res = Unite(res, states[i][(shift + gen[j]) % m]);
          any = 1;
          up -= z;
        } else {
          shift = (shift + gen[j]) % m;
          break;
        }
      }
    }
    return res.res;
  };
  long long L, R;
  cin >> L >> R;
  cout << calc(R) - calc(L + n - 2) << '\n';
  return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];

void prepare()
{
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}
int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int> digits;
	for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
	int64 ret=0;
	REP(i,SIZE(digits))
	{
		int s=0;
		FOR(j,i+1,SIZE(digits)) s+=gen[digits[j]];
		REP(d,digits[i]) REP(w,MOD) if (contain(mask,(s+d+w)%MOD)) ret+=cnt[i][w];
	}
	return ret;
}
int64 solve(vector<int64> a,int64 w1,int64 w2)
{
	if (SIZE(a)==1)
	{
		return calc(w2,a[0])-calc(w1,a[0]);
	}
	vector<int64> b;
	int64 ret=0;
	REP(md,MOD) if (md<=w2)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			for (;at>=SIZE(b);b.push_back(two(MOD)-1));
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok)
			ret+=solve(b,(w1<md)?-1:(w1-md)/m,(w2-md)/m);
	}
	return ret;
}
int64 solve(int64 w1,int64 w2)
{
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w1,w2);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
		REP(i,n) cin>>a[i];
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(l-1,(r-n+1));
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];
map<pair<int64,vector<int64>>,int64> htable;

void prepare()
{
	htable.clear();
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}
int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int> digits;
	for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
	int64 ret=0;
	REP(i,SIZE(digits))
	{
		int s=0;
		FOR(j,i+1,SIZE(digits)) s+=gen[digits[j]];
		REP(d,digits[i]) REP(w,MOD) if (contain(mask,(s+d+w)%MOD)) ret+=cnt[i][w];
	}
	assert(ret<=w+1);
	return ret;
}

int64 solve(vector<int64> a,int64 w)
{
	auto it=htable.find(MP(w,a));
	if (it!=htable.end()) return it->second;
	int64& ret=htable[MP(w,a)];
	if (w<0) return 0;
	if (w==0 && SIZE(a)<=m)
	{
		REP(i,SIZE(a)) if (!contain(a[i],gen[i])) return ret=0;
		return ret=1;
	}
	if (SIZE(a)==1) return ret=calc(w,a[0]);
	vector<int64> b;
	ret=0;
	REP(md,m) if (md<=w)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			for (;at>=SIZE(b);b.push_back(two(MOD)-1));
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok) ret+=solve(b,(w-md)/m);
	}
	assert(ret<=w+1);
	return ret;
}
int64 solve(int64 w)
{
	if (w<0) return 0;
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
		REP(i,n) cin>>a[i];
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(r-n+1)-solve(l-1);
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];
map<pair<int64,vector<int64>>,int64> htable;

void prepare()
{
	htable.clear();
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}
int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int> digits;
	for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
	int64 ret=0;
	REP(i,SIZE(digits))
	{
		int s=0;
		FOR(j,i+1,SIZE(digits)) s+=gen[digits[j]];
		REP(d,digits[i]) REP(w,MOD) if (contain(mask,(s+d+w)%MOD)) ret+=cnt[i][w];
	}
	assert(ret<=w+1);
	return ret;
}

int64 solve(vector<int64> a,int64 w)
{
	auto it=htable.find(MP(w,a));
	if (it!=htable.end()) return it->second;
	int64& ret=htable[MP(w,a)];
	if (w<0) return 0;
	if (SIZE(a)==1) return ret=calc(w,a[0]);
	vector<int64> b;
	ret=0;
	REP(md,m) if (md<=w)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			for (;at>=SIZE(b);b.push_back(two(MOD)-1));
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok) ret+=solve(b,(w-md)/m);
	}
	assert(ret<=w+1);
	return ret;
}
int64 solve(int64 w)
{
	if (w<0) return 0;
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
		REP(i,n) cin>>a[i];
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(r-n+1)-solve(l-1);
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#ifdef _MSC_VER
#define _CRT_SECURE_NO_WARNINGS
#endif

#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <cassert>
#include <string.h>
#include <unordered_set>
#include <unordered_map>

using namespace std;

typedef long long int64;
typedef unsigned long long uint64;
#define two(X) (((int64)(1))<<(X))
#define contain(S,X) (((S)&two(X))!=0)
const double pi=acos(-1.0);
const double eps=1e-11;
template<class T> inline void ckmin(T &a,T b){if(b<a) a=b;}
template<class T> inline void ckmax(T &a,T b){if(b>a) a=b;}
template<class T> inline T sqr(T x){return x*x;}
typedef pair<int,int> ipair;
#define SIZE(A) ((int)A.size())
#define LENGTH(A) ((int)A.length())
#define MP(A,B) make_pair(A,B)
#define PB(X) push_back(X)
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,a) for(int i=0;i<(a);++i)
#define ALL(A) A.begin(),A.end()

int MOD;
int m;
vector<int> gen;
int n;
vector<int> a;
int64 cnt[256][64];

void prepare()
{
	memset(cnt,0,sizeof(cnt));
	cnt[0][0]=1;
	REP(i,250) REP(j,MOD) if (cnt[i][j]) REP(k,m) cnt[i+1][(j+gen[k])%MOD]+=cnt[i][j];
}
inline int64 circular_shift_right(int64 s,int d)
{
	return (s>>d)|((s&(two(d)-1))<<(MOD-d));
}
int64 calc(int64 w,int64 mask)
{
	if (w<0) return 0;
	vector<int> digits;
	for (int64 t=w+1;t>0;t/=m) digits.push_back(t%m);
	int64 ret=0;
	REP(i,SIZE(digits))
	{
		int s=0;
		FOR(j,i+1,SIZE(digits)) s+=gen[digits[j]];
		REP(d,digits[i]) REP(w,MOD) if (contain(mask,(s+d+w)%MOD)) ret+=cnt[i][w];
	}
	return ret;
}

int64 solve(vector<int64> a,int64 w)
{
	if (w<0) return 0;
	if (SIZE(a)==1) return calc(w,a[0]);
	vector<int64> b;
	int64 ret=0;
	REP(md,m) if (md<=w)
	{
		b.clear();
		bool ok=true;
		REP(i,SIZE(a))
		{
			int at=(i+md)/m;
			int pos=(i+md)%m;
			while (at>=SIZE(b)) b.push_back(two(MOD)-1);
			b[at]&=circular_shift_right(a[i],gen[pos]);
			if (b[at]==0) { ok=false; break; }
		}
		if (ok) ret+=solve(b,(w-md)/m);
	}
	return ret;
}
int64 solve(int64 w)
{
	if (w<0) return 0;
	vector<int64> mask(n);
	REP(i,n) REP(k,a[i]+1) mask[i]|=two(k);
	return solve(mask,w);
}

int main()
{
#ifdef _MSC_VER
	freopen("input.txt","r",stdin);
#endif
	std::ios::sync_with_stdio(false);
	while (cin>>m>>MOD)
	{
		gen=vector<int>(m);
		REP(i,m) cin>>gen[i];
		cin>>n;
		a=vector<int>(n);
		REP(i,n) cin>>a[i];
		int64 l,r;
		cin>>l>>r; --l; --r;
		prepare();
		int64 ret=solve(r-n+1)-solve(l-1);
		cout<<ret<<endl;
#ifndef _MSC_VER
		break;
#endif
	}
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=30005;
int d,m,n,lm,i,j,b[N],gen[25];
ll L,R;
struct atom{
	bitset<N>pr,sf,all;
	ll ans,l;
	void set(int v){
		if(v<=b[n])pr.set(n);if(v<=b[1])sf.set(1);
		for(int i=1;i<=n;++i)if(v<=b[i])all.set(i);
		ans=n==1 && v<=b[1];l=1;
	}
}a[65][65];
inline atom uni(const atom&a,const atom&b){
	static atom ret;
	ret.l=a.l+b.l;
	ret.pr=a.pr;if(a.l<n)ret.pr|=(a.all<<a.l&b.pr)>>a.l;
	ret.sf=b.sf;if(b.l<n)ret.sf|=(b.all>>1&a.sf)<<b.l;
	if(a.l+b.l<=n)ret.all=b.all>>a.l&a.all;else ret.all.reset();
	ret.ans=a.ans+b.ans+(a.sf<<1&b.pr).count();
	return ret;
}
inline ll calc(ll x){
	ll y=0,pr=0;
	static atom ans;bool fl=0;
	for(i=lm-1;i>=0;--i){
		for(j=0;y+a[i][(pr+gen[j])%m].l<=x;++j){
			if(!fl)ans=a[i][(pr+gen[j])%m],fl=1;else ans=uni(ans,a[i][(pr+gen[j])%m]);
			y+=a[i][(pr+gen[j])%m].l;
		}
		pr=(pr+gen[j])%m;
	}
	return ans.ans;
}
int main(){
	scanf("%d%d",&d,&m);for(i=0;i<d;++i)scanf("%d",gen+i);
	scanf("%d",&n);for(i=1;i<=n;++i)scanf("%d",b+i);scanf("%lld%lld",&L,&R);
	for(i=0;i<m;++i)a[0][i].set(i);
	for(lm=1;a[lm-1][0].l<=R/d;++lm)for(i=0;i<m;++i){
		a[lm][i]=a[lm-1][(i+gen[0])%m];
		for(j=1;j<d;++j)a[lm][i]=uni(a[lm][i],a[lm-1][(i+gen[j])%m]);
	}
	printf("%lld\n",calc(R)-calc(L+n-2));
	return 0;
}

#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
int gcd(int a,int b) { return b==0?a:gcd(b,a%b); }

const int MAXBASE=20;
const int MAXB=30000;
const int MAXLG=100;
const int MAXMOD=60;

int base,MOD;
int gen[MAXBASE];
int nb;
int b[MAXB];
ll ql,qr;

int bfcalc(int na) {
	vector<int> a(na,0); REP(i,na) { int x=i; while(x!=0) a[i]+=gen[x%base],x/=base; a[i]%=MOD; }
	printf("a:"); REPSZ(i,a) printf(" %d",a[i]); puts("");
	int ret=0; REPE(i,SZ(a)-nb) { bool ok=true; REP(j,nb) if(b[j]<a[i+j]) { ok=false; break; } if(ok) ++ret; } return ret;
}

int d[MAXLG],nd;
ll dp[MAXLG+1][MAXMOD]; // with i freedigits, make j
ll dpsum[MAXLG+1][MAXMOD][MAXMOD]; // with i free digits and one less than k, make j

ll calc(ll len,int want) {
	nd=0; for(ll x=len;x!=0;x/=base) d[nd++]=x%base; reverse(d,d+nd);
	//printf("len:%lld want:%d, d:",len,want); REP(i,nd) printf(" %d",d[i]); puts("");
	int have=0; REP(i,nd) have+=gen[d[i]]; have%=MOD;
	ll ret=0; ll chk=0;
	for(int i=nd-1;i>=0;--i) {
		have-=gen[d[i]]; if(have<0) have+=MOD;
		/*REP(j,d[i]) {
			int cur=have+gen[j]; if(cur>=MOD) cur-=MOD;
			int need=want-cur; if(need<0) need+=MOD;
			//printf("\tneed %d with %d free digits\n",need,nd-i-1);
			ret+=dp[nd-i-1][need];
		}*/
		int need=want-have; if(need<0) need+=MOD; ret+=dpsum[nd-i-1][need][d[i]];
	}
	//printf("=>%lld\n",ret);
	return ret;
}

ll rec(ll len,vector<ll> mask,int dep=0) {
	//REP(rep,dep) printf("  "); printf("len=%lld mask:",len); REPSZ(i,mask) { printf(" ["); bool fst=true; REP(j,MOD) if(mask[i]&(1LL<<j)) { if(fst) fst=false; else printf(","); printf("%d",j); } printf("]"); } puts("");
	if(len==1) return SZ(mask)==1&&((mask[0]&1)!=0)?1:0;
	if(SZ(mask)==1) { ll ret=0; REP(i,MOD) if((mask[0]&(1LL<<i))!=0) ret+=calc(len,i); return ret; }
	ll ret=0;
	REP(offset,base) if(offset+SZ(mask)<=len) {
		vector<ll> nmask; bool ok=true;
		REPSZ(i,mask) {
			// l[i]<=a[x*base+offset+i]<=r[i] -> l[i]<=gen[(offset+i)%base]+a[x+(offset+i)/base] mod MOD<=r[i] -> l[i]-gen[(offset+i)%base]+x*MOD<=a[x+(offset+i)/base]<=r[i]-gen[(offset+i)%base]+y*MOD
			// nl[(offset+i)/base]>=l[i]-gen[(offset+i)%base]+x*MOD and nr[(offset+i)/base]<=r[i]-gen[(offset+i)%base]+y*MOD
			int idx=(offset+i)/base,delta=gen[(offset+i)%base];
			ll cmask=(mask[i]>>delta)|((mask[i]&((1LL<<delta)-1))<<(MOD-delta));
			//printf("offset=%d i=%d idx=%d delta=%d omask=%lld cmask=%lld\n",offset,i,idx,delta,mask[i],cmask);
			if(idx>=SZ(nmask)) nmask.PB(cmask); else { nmask[idx]&=cmask; if(nmask[idx]==0) { ok=false; break; } }
		}
		if(!ok) continue;
		//REP(rep,dep) printf("  "); printf("%d:",offset); REPSZ(i,nmask) { printf(" ["); bool fst=true; REP(j,MOD) if(nmask[i]&(1LL<<j)) { if(fst) fst=false; else printf(","); printf("%d",j); } printf("]"); } puts("");
		// x*base+offset+SZ(mask)<=len
		// x+SZ(nmask)<=(len-SZ(mask)-offset)/base+SZ(nmask)
		ll nlen=(len-SZ(mask)-offset)/base+SZ(nmask);
		if(nlen>=len) { REP(rep,dep) printf("  "); printf("len does not decrease (len=%lld nlen=%lld SZ(mask)=%d SZ(nmask)=%d offset\n",len,nlen,SZ(mask),SZ(nmask),offset); continue; }
		ret+=rec(nlen,nmask,dep+1);
	}
	return ret;
}

ll calc(ll na) {
	//int want=na<1000?bfcalc(na):-1;
	vector<ll> smask(nb); REP(i,nb) smask[i]=(2LL<<b[i])-1;
	return rec(na,smask);
}

ll solve() {
	REP(j,MOD) dp[0][j]=j==0?1:0;
	FORE(i,1,MAXLG) REP(j,MOD) { dp[i][j]=0; REP(k,base) dp[i][j]+=dp[i-1][(j+MOD-gen[k])%MOD]; }
	REPE(i,MAXLG) REP(j,MOD) { dpsum[i][j][0]=0; REP(k,base) dpsum[i][j][k+1]=dpsum[i][j][k]+dp[i][(j+MOD-gen[k])%MOD]; }
	return calc(qr+1)-calc(ql+nb);
}

void run() {
	scanf("%d%d",&base,&MOD);
	REP(i,base) scanf("%d",&gen[i]);
	scanf("%d",&nb);
	REP(i,nb) scanf("%d",&b[i]);
	scanf("%lld%lld",&ql,&qr),--ql,--qr;
	printf("%lld\n",solve());
}

void stress() {
	REP(rep,100) {
		base=2; //rand()%(20-2+1)+2;
		MOD=60; //rand()%(60-2+1)+2;
		REP(i,base) gen[i]=MOD-1; //rand()%MOD;
		nb=MAXB; REP(i,nb) b[i]=rand()%MOD;
		ql=rand()%1000*1000000000000000LL+rand()%1000*1000000000000LL+rand()%1000*1000000000LL+rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		qr=rand()%1000*1000000000000000LL+rand()%1000*1000000000000LL+rand()%1000*1000000000LL+rand()%1000*1000000+rand()%1000*1000+rand()%1000+1;
		if(ql>qr) swap(ql,qr);
		printf("base=%d MOD=%d ql=%lld qr=%lld\n",base,MOD,ql,qr);
		ll have=solve();
	}
}

int main() {
	run();
	//stress();
	return 0;
}

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int d, m;
vector<int> gen;
vector<int> b;

LL cnt(LL S, vector<LL> masks){
	assert(masks.size() > 0);
	if(S == 0) return 0;
	if(masks.size() == 1){
		vector<LL> digits;
		while(S > 0){
			digits.push_back(S % d);
			S /= d;
		}
		reverse(digits.begin(), digits.end());
		vector<LL> dp(m, 0);

		LL cursum = 0;
		for(LL digit : digits){
			vector<LL> newdp(m, 0);
			for(int i = 0; i < m; i++){
				for(int j = 0; j < d; j++){
					newdp[(i + gen[j]) % m] += dp[i];
				}
			}
			for(int j = 0; j < digit; j++){
				newdp[(cursum + j) % m] ++;
			}
			dp = newdp;
			cursum += gen[digit];
		}

		LL ret = 0;
		for(int i = 0; i < m; i++){
			if(masks[0] & (1LL << i)){
				ret += dp[i];
			}
		}
		return ret;
	} else {
		LL ret = 0;
		for(int xres = 0; xres < d; xres ++){
			LL len = masks.size();
			LL newlen = (len - 1 + xres) / d + 1;
			vector<LL> newmasks(newlen, (1LL << m) - 1);
			for(LL i = 0; i < len; i++){
				LL newidx = (i + xres) / d;
				LL diff = gen[(i + xres) % d];
				newmasks[newidx] &= (masks[i] >> diff) | (masks[i] << (m - diff));
			}
			LL newS = (S - xres + d - 1) / d;
			ret += cnt(newS, newmasks);
		}
		return ret;
	}
}

LL solve(LL maxs){
	// s in [0, maxs)
	vector<LL> masks;
	for(int r : b){
		LL mask = (1LL << m) - 1;
		for(int z = 0; z < m; z++){
			if(z > r){
				mask &= ~(1LL << z);
			}
		}
		masks.push_back(mask);
	}
	return cnt(maxs, masks);
}
int main(){
	cin >> d >> m;
	gen.resize(d);
	for(int i = 0; i < d; i++){
		cin >> gen[i];
	}
	int n;
	cin >> n;
	b.resize(n);
	for(int i = 0; i < n; i++){
		cin >> b[i];
	}
	LL l, r;
	cin >> l >> r;
	l--; r--;
	LL ans = solve(r-n+2) - solve(l);
	cout << ans << endl;
}

#include<bits/stdc++.h>
using namespace std;

int D , M , N , G[60] , B[30003] , pos; unsigned long long pw[64] , L , R;
struct data{
	bitset < 30003 > pre , suf; long long cnt; int len;
	void create(int val){
		len = 1; cnt = 0;
		if(N == 1) cnt = val <= B[0];
		else{for(int i = 0 ; i < N ; ++i) pre[i] = B[i] >= val; suf = pre;}
	}
	friend data operator +(data &p , data q){
		data x; x.len = p.len + q.len; int d1 = max(0 , 30003 - q.len) , d2 = max(0 , N - p.len);
		x.suf = (q.suf << d1 >> d1) | ((q.suf >> q.len & p.suf) << q.len);
		x.pre = (p.pre >> d2 << d2) | ((p.pre << p.len & q.pre) >> p.len);
		d1 = max(0 , 30003 - p.len); d2 = max(0 , N - q.len);
		x.cnt = p.cnt + q.cnt + ((p.suf << d1 >> d1) << 1 & (q.pre >> d2 << d2)).count();
		return x;
	}
}now[64][60];

void init(){
	pw[0] = 1; for(pos = 1 ; pw[pos - 1] < 1e18 ; ++pos) pw[pos] = pw[pos - 1] * D;
	for(int i = 0 ; i < M ; ++i) now[0][i].create(i);
	for(int i = 1 ; i < pos ; ++i)
		for(int j = 0 ; j < M ; ++j){
			now[i][j] = now[i - 1][j];
			for(int k = 1 ; k < D ; ++k)
				now[i][j] = now[i][j] + now[i - 1][(j + G[k]) % M];
		}
}

data solve(int bit , long long val , int delt){
	if(val < pw[bit]) return solve(bit - 1 , val , delt);
	data cur = now[bit][delt]; val -= pw[bit];
	for(int i = 1 ; val && i < D ; ++i)
		if(val < pw[bit]){cur = cur + solve(bit - 1 , val , (delt + G[i]) % M); val = 0;}
		else{cur = cur + now[bit][(delt + G[i]) % M]; val -= pw[bit];}
	return cur;
}

int main(){
	cin >> D >> M; for(int i = 0 ; i < D ; ++i) cin >> G[i];
	cin >> N; for(int i = 0 ; i < N ; ++i) cin >> B[i];
	cin >> L >> R; init(); --L; --R;
	cout << solve(pos - 1 , R , 0).cnt - solve(pos - 1 , L + N - 2 , 0).cnt << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

int D , M , N , G[60] , B[30003] , pos; unsigned long long pw[64] , L , R;
struct data{
	bitset < 30003 > pre , suf; long long cnt; int len;
	void create(int val){
		len = 1; cnt = 0;
		if(N == 1) cnt = val <= B[0];
		else{for(int i = 0 ; i < N ; ++i) pre[i] = B[i] >= val; suf = pre;}
	}
	friend data operator +(data &p , data q){
		data x; x.len = p.len + q.len; int d1 = max(0 , 30003 - q.len) , d2 = max(0 , N - p.len);
		x.suf = (q.suf << d1 >> d1) | ((q.suf >> q.len & p.suf) << q.len);
		x.pre = (p.pre >> d2 << d2) | ((p.pre << p.len & q.pre) >> p.len);
		d1 = max(0 , 30003 - p.len); d2 = max(0 , N - q.len);
		x.cnt = p.cnt + q.cnt + ((p.suf << d1 >> d1) << 1 & (q.pre >> d2 << d2)).count();
		return x;
	}
}now[64][60];

void init(){
	pw[0] = 1; for(pos = 1 ; pw[pos - 1] < 1e18 ; ++pos) pw[pos] = pw[pos - 1] * D;
	for(int i = 0 ; i < M ; ++i) now[0][i].create(i);
	for(int i = 1 ; i < pos ; ++i)
		for(int j = 0 ; j < M ; ++j){
			now[i][j] = now[i - 1][j];
			for(int k = 1 ; k < D ; ++k)
				now[i][j] = now[i][j] + now[i - 1][(j + G[k]) % M];
		}
}

data solve(int bit , long long val , int delt){
	if(val < pw[bit]) return solve(bit - 1 , val , delt);
	data cur = now[bit][delt]; val -= pw[bit];
	for(int i = 1 ; val && i < D ; ++i)
		if(val < pw[bit]){cur = cur + solve(bit - 1 , val , (delt + G[i]) % M); val = 0;}
		else{cur = cur + now[bit][(delt + G[i]) % M]; val -= pw[bit];}
	return cur;
}

int main(){
	cin >> D >> M; for(int i = 0 ; i < D ; ++i) cin >> G[i];
	cin >> N; for(int i = 0 ; i < N ; ++i) cin >> B[i];
	cin >> L >> R; init(); cout << solve(pos - 1 , R , 0).cnt - solve(pos - 1 , L + N - 1 , 0).cnt << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

int D , M , N , G[60] , B[30003] , pos; unsigned long long pw[64] , L , R;
struct data{
	bitset < 30003 > pre , suf; long long cnt , len;
	void create(int val){
		len = 1; cnt = 0;
		if(N == 1) cnt = val <= B[0];
		else{for(int i = 0 ; i < N ; ++i) pre[i] = B[i] >= val; suf = pre;}
	}
	friend data operator +(data &p , data q){
		data x; x.len = p.len + q.len; int d1 = max(0ll , 30003 - q.len) , d2 = max(0ll , N - p.len);
		x.suf = (q.suf << d1 >> d1) | ((q.suf >> q.len & p.suf) << q.len);
		x.pre = (p.pre >> d2 << d2) | ((p.pre << p.len & q.pre) >> p.len);
		d1 = max(0ll , 30003 - p.len); d2 = max(0ll , N - q.len);
		x.cnt = p.cnt + q.cnt + ((p.suf << d1 >> d1) << 1 & (q.pre >> d2 << d2)).count();
		return x;
	}
}now[64][60];

void init(){
	pw[0] = 1; for(pos = 1 ; pw[pos - 1] < 1e18 ; ++pos) pw[pos] = pw[pos - 1] * D;
	for(int i = 0 ; i < M ; ++i) now[0][i].create(i);
	for(int i = 1 ; i < pos ; ++i)
		for(int j = 0 ; j < M ; ++j){
			now[i][j] = now[i - 1][j];
			for(int k = 1 ; k < D ; ++k)
				now[i][j] = now[i][j] + now[i - 1][(j + G[k]) % M];
		}
}

data solve(int bit , long long val , int delt){
	if(val < pw[bit]) return solve(bit - 1 , val , delt);
	data cur = now[bit][delt]; val -= pw[bit];
	for(int i = 1 ; val && i < D ; ++i)
		if(val < pw[bit]){cur = cur + solve(bit - 1 , val , (delt + G[i]) % M); val = 0;}
		else{cur = cur + now[bit][(delt + G[i]) % M]; val -= pw[bit];}
	return cur;
}

int main(){
	cin >> D >> M; for(int i = 0 ; i < D ; ++i) cin >> G[i];
	cin >> N; for(int i = 0 ; i < N ; ++i) cin >> B[i];
	cin >> L >> R; init();
	cout << solve(pos - 1 , R , 0).cnt - (N == 1 ? 0 : solve(pos - 1 , L + N - 2 , 0).cnt) << endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;

int D , M , N , G[60] , B[30003] , pos; unsigned long long pw[64] , L , R;
struct data{
	bitset < 30003 > pre , suf; long long cnt; int len;
	void create(int val){
		len = 1; cnt = 0;
		if(N == 1) cnt = val <= B[0];
		else{for(int i = 0 ; i < N ; ++i) pre[i] = B[i] >= val; suf = pre;}
	}
	friend data operator +(data &p , data q){
		data x; x.len = p.len + q.len; int d1 = max(0 , 30003 - q.len) , d2 = max(0 , N - p.len);
		x.suf = (q.suf << d1 >> d1) | ((q.suf >> q.len & p.suf) << q.len);
		x.pre = (p.pre >> d2 << d2) | ((p.pre << p.len & q.pre) >> p.len);
		d1 = max(0 , 30003 - p.len); d2 = max(0 , N - q.len);
		x.cnt = p.cnt + q.cnt + ((p.suf << d1 >> d1) << 1 & (q.pre >> d2 << d2)).count();
		return x;
	}
}now[64][60];

void init(){
	pw[0] = 1; for(pos = 1 ; pw[pos - 1] < 1e18 ; ++pos) pw[pos] = pw[pos - 1] * D;
	for(int i = 0 ; i < M ; ++i) now[0][i].create(i);
	for(int i = 1 ; i < pos ; ++i)
		for(int j = 0 ; j < M ; ++j){
			now[i][j] = now[i - 1][j];
			for(int k = 1 ; k < D ; ++k)
				now[i][j] = now[i][j] + now[i - 1][(j + G[k]) % M];
		}
}

data solve(int bit , long long val , int delt){
	if(val < pw[bit]) return solve(bit - 1 , val , delt);
	data cur = now[bit][delt]; val -= pw[bit];
	for(int i = 1 ; val && i < D ; ++i)
		if(val < pw[bit]){cur = cur + solve(bit - 1 , val , (delt + G[i]) % M); val = 0;}
		else{cur = cur + now[bit][(delt + G[i]) % M]; val -= pw[bit];}
	return cur;
}

int main(){
	cin >> D >> M; for(int i = 0 ; i < D ; ++i) cin >> G[i];
	cin >> N; for(int i = 0 ; i < N ; ++i) cin >> B[i];
	cin >> L >> R; init(); cout << solve(pos - 1 , R , 0).cnt - solve(pos - 1 , L + N - 2 , 0).cnt << endl;
	return 0;
}

#include<bits/stdc++.h>
#define mkp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f,N=3e4+10,M=65;
int n,m,d,tot,gen[M],b[M];
ll ql,qr,len[M];
bitset<N>all,tmp;

int read()
{
	int ret=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=0;c=getchar();}
	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
	return f?ret:-ret;
}

struct data
{
	ll len,ans;
	bitset<N>pre,suf;
}f[M][M];
data operator +(const data&a,const data&b)
{
	if(!a.len) return b;
	data res;
	res.len=a.len+b.len;res.ans=a.ans+b.ans;
	res.pre=a.pre;res.suf=b.suf;
	if(a.len<=n-2) res.pre&=(b.pre>>a.len)|(all<<(n-a.len-1));
	if(b.len<=n-2) res.suf&=(a.suf<<b.len)|(all>>(n-b.len-1));
	if(a.len+b.len>=n)
	{
		tmp=a.suf&b.pre;
		if(a.len<=n-2) tmp&=all>>(n-a.len-1);
		if(b.len<=n-2) tmp&=all<<(n-b.len-1);
		res.ans+=tmp.count();
	}
	return res;
}
ll solve(ll x)
{
	data res;int delta=0;
	res.ans=res.len=0;
	res.pre.reset();res.suf.reset();
	for(int i=tot;~i;--i) for(int j=1;j<=d;++j)
	{
		if(x>=len[i]) x-=len[i],res=res+f[i][(delta+gen[j])%m];
		else {delta=(delta+gen[j])%m;break;}
	}
	return res.ans;
}
void init()
{
	d=read();m=read();
	for(int i=1;i<=d;++i) gen[i]=read();
	n=read();
	for(int i=1;i<=n;++i) b[i]=read();
	for(int i=1;i<n;++i) all.set(i);
	len[0]=1;
	for(int i=0;i<m;++i)
	{
		f[0][i].len=1;
		if(n==1) f[0][i].ans=i<=b[1];
		else
		{
			for(int j=1;j<n;++j)
			{
				f[0][i].pre[j]=i<=b[j+1];
				f[0][i].suf[j]=i<=b[j];
			}
		}
	}
}
void work()
{
	ql=read();qr=read();
	while(len[tot]<=qr/d)
	{
		++tot;len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j)
			f[tot][i]=f[tot][i]+f[tot-1][(i+gen[j])%m];
	}
	printf("%lld\n",solve(qr)-solve(ql+n-2));
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("H.in","r",stdin);
	freopen("H.out","w",stdout);
#endif
	init();work();
	return 0;
}

#include<bits/stdc++.h>
#define mkp make_pair
#define pb push_back
#define fi first
#define se second
using namespace std;

typedef double db;
typedef long long ll;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f,N=3e4+10,M=65;
int n,m,d,tot,gen[M],b[M];
ll ql,qr,len[M];
bitset<N>all,tmp;

ll read()
{
	ll ret=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=0;c=getchar();}
	while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
	return f?ret:-ret;
}

struct data
{
	ll len,ans;
	bitset<N>pre,suf;
}f[M][M];
data operator +(const data&a,const data&b)
{
	if(!a.len) return b;
	data res;
	res.len=a.len+b.len;res.ans=a.ans+b.ans;
	res.pre=a.pre;res.suf=b.suf;
	if(a.len<=n-2) res.pre&=(b.pre>>a.len)|(all<<(n-a.len-1));
	if(b.len<=n-2) res.suf&=(a.suf<<b.len)|(all>>(n-b.len-1));
	if(a.len+b.len>=n)
	{
		tmp=a.suf&b.pre;
		if(a.len<=n-2) tmp&=all>>(n-a.len-1);
		if(b.len<=n-2) tmp&=all<<(n-b.len-1);
		res.ans+=tmp.count();
	}
	return res;
}
ll solve(ll x)
{
	data res;int delta=0;
	res.ans=res.len=0;
	res.pre.reset();res.suf.reset();
	for(int i=tot;~i;--i) for(int j=1;j<=d;++j)
	{
		if(x>=len[i]) x-=len[i],res=res+f[i][(delta+gen[j])%m];
		else {delta=(delta+gen[j])%m;break;}
	}
	return res.ans;
}
void init()
{
	d=read();m=read();
	for(int i=1;i<=d;++i) gen[i]=read();
	n=read();
	for(int i=1;i<=n;++i) b[i]=read();
	for(int i=1;i<n;++i) all.set(i);
	len[0]=1;
	for(int i=0;i<m;++i)
	{
		f[0][i].len=1;
		if(n==1) f[0][i].ans=i<=b[1];
		else
		{
			for(int j=1;j<n;++j)
			{
				f[0][i].pre[j]=i<=b[j+1];
				f[0][i].suf[j]=i<=b[j];
			}
		}
	}
}
void work()
{
	ql=read();qr=read();
	while(len[tot]<=qr/d)
	{
		++tot;len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j)
			f[tot][i]=f[tot][i]+f[tot-1][(i+gen[j])%m];
	}
	printf("%lld\n",solve(qr)-solve(ql+n-2));
}

int main()
{
#ifndef ONLINE_JUDGE
	freopen("H.in","r",stdin);
	freopen("H.out","w",stdout);
#endif
	init();work();
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n,m,d;
#define lld I64d
bitset<30001> all;
struct ooxx{
	long long ans,len;
	bitset<30001> pre,nxt;
	ooxx operator + (const ooxx &emm) {
		if (!len) return emm;
		ooxx ret;
		ret.ans=ans+emm.ans,ret.len=len+emm.len;
		ret.pre=pre,ret.nxt=emm.nxt;
		if (len<n-1) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
		if (emm.len<n-1) ret.nxt&=((nxt<<emm.len)|(all>>(n-emm.len-1)));
		if (len+emm.len>=n){
			bitset<30001> res=nxt&emm.pre;
			if(len<n-1) res&=(all>>(n-1-len));
			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
			ret.ans+=res.count();
		}
		return ret;
	}
//	void operator += (const ooxx &b) {*this = !len ? b : *this + b;}
}dp[100][100];
//struct ooxx{
//	int ans,len;
//	bitset<30001> pre,nxt;
//	ooxx operator + (const ooxx &emm) {
//		if (!len) return emm;
//		ooxx ret;
//		ret.ans=ans+emm.ans,ret.len=len+emm.len;
//		ret.pre=pre,ret.nxt=emm.nxt;
//		if (len<n) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
//		if (emm.len<n) ret.nxt&=((nxt<<emm.len)|(all>>(n-len-1)));
//		if (len+emm.len>=n){
//			bitset<30001> res=nxt&emm.pre;
//			if(len<n-1) res&=(all>>(n-1-len));
//			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
//			ret.ans+=res.count();
//		}
//		return ret;
//	}
//}dp[100][100];
int tot,a[100];
long long len[100];
inline long long query(long long x)
{
	ooxx ret;ret.ans=ret.len=0,ret.nxt.reset(),ret.pre.reset();
	long long now=0;
	for (int i=tot;i>=0;--i)
	{
		for (int j=1;j<=d;++j)
		{
			if (len[i]>x) {now+=a[j];now%=m;break;}
			else
			{
				ret=(ret+dp[i][(a[j]+now)%m]);
				x-=len[i];
			}
		}
	}
	return ret.ans;
}
int b[100000];
int main()
{
	scanf("%d%d",&d,&m);
	for (int i=1;i<=d;++i) scanf("%d",&a[i]);
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d",&b[i]);
	for (int i=1;i<n;++i) all.set(i);//[i]=1;
	for (int i=0;i<m;++i)
	{
		dp[0][i].len=1;
		if (n==1) dp[0][i].ans=(i<=b[i]);
		else
		{
			for (int j=1;j<n;++j)
			{
				dp[0][i].pre[j]=i<=b[j+1];
				dp[0][i].nxt[j]=i<=b[j];
			}
		}
	}
	len[0]=1;
	for (;len[tot]<=1000000000000000000ll/d;){
		++tot,len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j) dp[tot][i]=(dp[tot][i]+dp[tot-1][(i+a[j])%m]);
	}
	long long l,r;
	scanf("%lld%lld",&l,&r);
	printf("%lld\n",query(r)-query(l+n-2));
	return 0;
}

#include<bits/stdc++.h>
const int N = 3e4 + 1;
using namespace std;
#define lld I64d
typedef std::bitset<N> BI;
long long ri() {
	char c = getchar(); long long x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct ooxx{
	long long ans,len;
	bitset<30001> pre,nxt;
	ooxx operator + (const ooxx &emm) {
		if (!len) return emm;
		ooxx ret;
		ret.ans=ans+emm.ans,ret.len=len+emm.len;
		ret.pre=pre,ret.nxt=emm.nxt;
		if (len<n-1) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
		if (emm.len<n-1) ret.nxt&=((nxt<<emm.len)|(all>>(n-len-1)));
		if (len+emm.len>=n){
			bitset<30001> res=nxt&emm.pre;
			if(len<n-1) res&=(all>>(n-1-len));
			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
			ret.ans+=res.count();
		}
		return ret;
	}
//	void operator += (const ooxx &b) {*this = !len ? b : *this + b;}
}f[100][100];
inline long long query(long long x)
{
	ooxx ret;ret.ans=ret.len=0,ret.nxt.reset(),ret.pre.reset();
	long long now=0;
	for (int i=tot;i>=0;--i)
	{
		for (int j=1;j<=d;++j)
		{
			if (len[i]>x) {now+=gen[j];now%=m;break;}
			else
			{
				ret=(ret+f[i][(gen[j]+now)%m]);
				x-=len[i];
			}
		}
	}
	return ret.ans;
}
int main() {
	d = ri(); m = ri();
	for(int i = 1;i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1;i <= n; ++i)
		b[i] = ri();
	for(int i = 1;i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0;i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1;j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[j + 1];
				f[0][i].nxt[j] = i <= b[j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(;len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0;i < m; ++i)
			for(int j = 1;j <= d; ++j)
				f[tot][i] = (f[tot][i]+f[tot - 1][(i + gen[j]) % m]);
//				f[tot][i]+= f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", query(R) - query(L + n - 2));
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
int n,m,d;
bitset<30001> all;
#define lld I64d
struct ooxx{
	long long ans,len;
	bitset<30001> pre,nxt;
	ooxx operator + (const ooxx &emm) {
		if (!len) return emm;
		ooxx ret;
		ret.ans=ans+emm.ans,ret.len=len+emm.len;
		ret.pre=pre,ret.nxt=emm.nxt;
		if (len<n-1) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
		if (emm.len<n-1) ret.nxt&=((nxt<<emm.len)|(all>>(n-len-1)));
		if (len+emm.len>=n){
			bitset<30001> res=nxt&emm.pre;
			if(len<n-1) res&=(all>>(n-1-len));
			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
			ret.ans+=res.count();
		}
		return ret;
	}
//	void operator += (const ooxx &b) {*this = !len ? b : *this + b;}
}dp[100][100];
//struct ooxx{
//	int ans,len;
//	bitset<30001> pre,nxt;
//	ooxx operator + (const ooxx &emm) {
//		if (!len) return emm;
//		ooxx ret;
//		ret.ans=ans+emm.ans,ret.len=len+emm.len;
//		ret.pre=pre,ret.nxt=emm.nxt;
//		if (len<n) ret.pre&=((emm.pre>>len)|(all<<(n-len-1)));
//		if (emm.len<n) ret.nxt&=((nxt<<emm.len)|(all>>(n-len-1)));
//		if (len+emm.len>=n){
//			bitset<30001> res=nxt&emm.pre;
//			if(len<n-1) res&=(all>>(n-1-len));
//			if(emm.len<n-1) res&=(all<<(n-1-emm.len));
//			ret.ans+=res.count();
//		}
//		return ret;
//	}
//}dp[100][100];
int tot,a[100];
long long len[100];
inline long long query(long long x)
{
	ooxx ret;ret.ans=ret.len=0,ret.nxt.reset(),ret.pre.reset();
	long long now=0;
	for (int i=tot;i>=0;--i)
	{
		for (int j=1;j<=d;++j)
		{
			if (len[i]>x) {now+=a[j];now%=m;break;}
			else
			{
				ret=(ret+dp[i][(a[j]+now)%m]);
				x-=len[i];
			}
		}
	}
	return ret.ans;
}
int b[100000];
int main()
{
	scanf("%d%d",&d,&m);
	for (int i=1;i<=d;++i) scanf("%d",&a[i]);
	scanf("%d",&n);
	for (int i=1;i<=n;++i) scanf("%d",&b[i]);
	for (int i=1;i<n;++i) all.set(i);//[i]=1;
	for (int i=0;i<m;++i)
	{
		dp[0][i].len=1;
		if (n==1) dp[0][i].ans=(i<=b[i]);
		else
		{
			for (int j=1;j<n;++j)
			{
				dp[0][i].pre[j]=i<=b[j+1];
				dp[0][i].nxt[j]=i<=b[j];
			}
		}
	}
	len[0]=1;
	for (;len[tot]<=1000000000000000000ll/d;){
		++tot,len[tot]=len[tot-1]*d;
		for(int i=0;i<m;++i) for(int j=1;j<=d;++j) dp[tot][i]=(dp[tot][i]+dp[tot-1][(i+a[j])%m]);
	}
	long long l,r;
	scanf("%lld%lld",&l,&r);
	printf("%lld\n",query(r)-query(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[15][M];
ll pw[15];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	for (int i=max(n-b.len,1ll);i<=a.len && i<n;++i)
		c.ans+=(a.s[i]&b.p[i]);
	for (int i=1;i<n;++i)
		c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	for (int i=1;i<n;++i)
		c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (!r)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[15][M];
ll pw[15];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
		c.ans+=(a.s[i]&b.p[i]);
	for (int i=1;i<n;++i)
		c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	for (int i=1;i<n;++i)
		c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=!(a.s[i]|b.p[i]);
	else
		c.ans+=n-1-(a.s|b.p).count();
	static bitset<N+1> tmp;
	if (n-1-a.len>0){
		c.p=a.p|b.p<<a.len;
		for (int i=n;i<=n+a.len-1 && i<=N;++i)
			c.p.reset(i);
	}
	else
		c.p=a.p;
	c.s=b.s|a.s>>b.len;
	c.s.reset(0);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (!(b[n-i]>=v))
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (!(b[i-1]>=v))
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[20][M];
ll pw[20];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
		c.ans+=(a.s[i]&b.p[i]);
	for (int i=1;i<n;++i)
		c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	for (int i=1;i<n;++i)
		c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[70][M];
ll pw[70];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	if (n-a.len>1 || b.len<n-1)
		for (int i=max(n-a.len,1ll);i<=b.len && i<n;++i)
			c.ans+=!(a.s[i]|b.p[i]);
	else
		c.ans+=n-1-(a.s|b.p).count();
	static bitset<N+1> tmp;
	if (n-1-a.len>0){
		c.p=a.p|b.p<<a.len;
		for (int i=n;i<=n+a.len-1 && i<=N;++i)
			c.p.reset(i);
	}
	else
		c.p=a.p;
	c.s=b.s|a.s>>b.len;
	c.s.reset(0);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (r<=0)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
//	freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	if (r-l+1<n){
		printf("0\n");
		return 0;
	}
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=!(b[0]>=v);
		for (int i=1;i<n;++i)
			if (!(b[n-i]>=v))
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (!(b[i-1]>=v))
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l+n-2));
	return 0;
}

using namespace std;
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cassert>
#include <bitset>
#define D 20
#define M 60
#define N 30000
#define ll long long
int d,m,n;
int gen[D];
int b[N];
ll l,r;
struct Info{
	ll len,ans;
	bitset<N+1> p,s;
} dp[15][M];
ll pw[15];
void merge(Info &c,Info &a,Info &b){
	if (a.len==0){
		c=b;
		return;
	}
	c.ans=a.ans+b.ans;
	for (int i=max(n-b.len,1ll);i<=a.len && i<n;++i)
		c.ans+=(a.s[i]&b.p[i]);
	for (int i=1;i<n;++i)
		c.p[i]=a.p[i]&(i-a.len>0?b.p[i-a.len]:1);
	for (int i=1;i<n;++i)
		c.s[i]=b.s[i]&(i+b.len<n?a.s[i+b.len]:1);
	c.len=a.len+b.len;
}
ll calc(ll r){
	if (!r)
		return 0;
	static Info res;
	res.len=0;
	res.ans=0;
	ll p=1,w=0;
	for (;p<=r;p*=d,++w);
	--w;
	int v=0;
	for (;w>=0;--w){
		for (int i=0;i<r/pw[w];++i)
			merge(res,res,dp[w][(v+gen[i])%m]);
		v=(v+gen[r/pw[w]])%m;
		r%=pw[w];
	}
	return res.ans;
}
int main(){
	//freopen("in.txt","r",stdin);
	scanf("%d%d",&d,&m);
	for (int i=0;i<d;++i)
		scanf("%d",&gen[i]);
	scanf("%d",&n);
	for (int i=0;i<n;++i)
		scanf("%d",&b[i]);
	scanf("%lld%lld",&l,&r);
	for (int v=0;v<m;++v){
		dp[0][v].len=1;
		if (n==1)
			dp[0][v].ans=(b[0]>=v);
		for (int i=1;i<n;++i)
			if (b[n-i]>=v)
				dp[0][v].p[i]=1;
		for (int i=1;i<n;++i)
			if (b[i-1]>=v)
				dp[0][v].s[n-i]=1;
	}
	pw[0]=1;
	ll p=d;
	for (int i=1;p<=r;++i,p*=d){
		pw[i]=p;
		for (int v=0;v<m;++v){
			dp[i][v]=dp[i-1][v];
			for (int j=1;j<d;++j)
				merge(dp[i][v],dp[i][v],dp[i-1][(v+gen[j])%m]);
		}
	}
	printf("%lld\n",calc(r)-calc(l-1));
	return 0;
}

#include <iostream>
#include <cstdio>

#include <bitset>
#include <vector>

#include <cassert>

using namespace std;

using ll = long long;
#define tl(X) static_cast<ll>(X)

const int MD = 22;
const int MM = 65;
const int MN = 3e4 + 100;
const ll INF = 1e18;

using vb = bitset<MN>;
vb F[MN];

int D, M, N;
int g[MD], b[MN];

int md(int x) {
	if(x >= M) x -= M;
	assert(x < M);
	return x;
}

struct DAT {
	vb p, s;
	ll l, c;
	DAT() {
		p.reset(), s.reset();
		l = c = 0LL;
	}
	DAT operator + (const DAT& o) const {
		DAT r;
		r.c = c+o.c, r.l = l+o.l;
		if(l + 1 < N) r.p = p&o.p>>l|p>>N-l-1<<N-l-1; else r.p = p;
		if(o.l + 1< N) r.s = o.s&s<<o.l|o.s&F[o.l]; else r.s = o.s;
		if(r.l >= N) {
			vb q = s&o.p;
			if(l < N) q &= F[l];
			if(o.l < N) q >>= N-o.l-1;
			r.c += q.count();
		}
		return r;
	}
};

DAT d[100][MM];

using vi = vector<int>;
#define pb push_back

ll solve(ll v) {
	vi x(0);
	for(;v;v/=D)
		x.pb(v%D);
	DAT c;
	for(int i = x.size() - 1, r = 0;i >= 0;i--) {
		for(int j = 0;j < x[i];j++)
			c = c + d[i][md(r+g[j])];
		r = md(r + g[x[i]]);
	}
	return c.c;
}

int main() {
	F[0].reset();
	for(int i = 0;i < MN - 1;i++) F[i+1] = F[i], F[i+1][i] = 1;

	scanf("%d%d", &D, &M);
	for(int i = 0;i < D;i++) scanf("%d", g + i);
	scanf("%d", &N);
	for(int i = 0;i < N;i++) scanf("%d", b + i);
	b[N] = -1;

	for(int i = 0;i < M;i++) {
		d[0][i].l = 1;
		if(N > 1)
			for(int j = 0;j < N-1;j++)
				d[0][i].s[j] = i <= b[j], d[0][i].p[j] = i <= b[j + 1];
		else
			d[0][i].c = i <= b[0];
	}

	ll x = 1;
	for(int i = 1;x <= INF/D;i++, x *= D)
		for(int j = 0;j < M;j++) {
			d[i][j] = d[i-1][j];
			for(int k = 1;k < D;k++) d[i][j] = d[i][j] + d[i-1][md(j+g[k])];
		}

	ll A, B;
	scanf("%lld%lld", &A, &B);
	printf("%lld\n", solve(B) - solve(A+N-1));

	return 0;
}

#include <iostream>
#include <cstdio>

#include <bitset>
#include <vector>

#include <cassert>

using namespace std;

using ll = long long;
#define tl(X) static_cast<ll>(X)

const int MD = 22;
const int MM = 65;
const int MN = 3e4 + 100;
const ll INF = 1e18;

using vb = bitset<MN>;
vb F[MN];

int D, M, N;
int g[MD], b[MN];

int md(int x) {
	if(x >= M) x -= M;
	assert(x < M);
	return x;
}

struct DAT {
	vb p, s;
	ll l, c;
	DAT() {
		p.reset(), s.reset();
		l = c = 0LL;
	}
	DAT operator + (const DAT& o) const {
		DAT r;
		r.c = c+o.c, r.l = l+o.l;
		r.p = p, r.s = o.s;
		if(l < N) r.p = r.p&o.p>>l|r.p>>(N-l-1)<<(N-l-1);
		if(o.l < N) r.s = r.s&s<<o.l|r.s&F[o.l];
		if(r.l >= N) {
			vb q = s&o.p;
			if(N > l) q &= F[l];
			if(N > o.l) q>>=N-o.l-1;
			r.c += q.count();
		}
		return r;
	}
};

DAT d[100][MM];

using vi = vector<int>;
#define pb push_back

ll solve(ll v) {
	vi x(0);
	for(;v;v/=D)
		x.pb(v%D);
	DAT c;
	for(int i = x.size() - 1, r = 0;i >= 0;i--) {
		for(int j = 0;j < x[i];j++)
			c = c + d[i][r = md(r+g[j])];
		r = md(r + g[x[i]]);
	}
	return c.c;
}

int main() {
	F[0].reset();
	for(int i = 0;i < MN - 1;i++) F[i+1] = F[i], F[i+1][i] = 1;

	scanf("%d%d", &D, &M);
	for(int i = 0;i < D;i++) scanf("%d", g + i);
	scanf("%d", &N);
	for(int i = 0;i < N;i++) scanf("%d", b + i);
	b[N] = -1;

	for(int i = 0;i < M;i++) {
		d[0][i].l = 1;
		if(N > 1)
			for(int j = 0;j < N-1;j++)
				d[0][i].s[j] = i <= b[j], d[0][i].p[j] = i <= b[j + 1];
		else
			d[0][i].c = i <= b[0];
	}

	ll x = 1;
	for(int i = 1;x <= INF/D;i++, x *= D)
		for(int j = 0;j < M;j++) {
			d[i][j] = d[i-1][j];
			for(int k = 1;k < D;k++) d[i][j] = d[i][j] + d[i-1][md(j+g[k])];
		}

	ll A, B;
	scanf("%lld%lld", &A, &B);
	printf("%lld\n", solve(B) - solve(A+N-1));

	return 0;
}

#include <iostream>
#include <cstdio>

#include <bitset>
#include <vector>

#include <cassert>

using namespace std;

using ll = long long;
#define tl(X) static_cast<ll>(X)

const int MD = 22;
const int MM = 65;
const int MN = 3e4 + 100;
const ll INF = 1e18;

using vb = bitset<5>;
vb F[MN];

int D, M, N;
int g[MD], b[MN];

int md(int x) {
	if(x >= M) x -= M;
	assert(x < M);
	return x;
}

struct DAT {
	vb p, s;
	ll l, c;
	DAT() {
		p.reset(), s.reset();
		l = c = 0LL;
	}
	DAT operator + (const DAT& o) const {
		DAT r;
		r.c = c+o.c, r.l = l+o.l;
		r.p = p, r.s = o.s;
		if(l < N) r.p = r.p&o.p>>l|r.p>>(N-l-1)<<(N-l-1);
		if(o.l < N) r.s = r.s&s<<o.l|r.s&F[o.l];
		if(r.l >= N) {
			vb q = s&o.p;
			if(N > l) q &= F[l];
			if(N > o.l) q>>=N-o.l-1;
			r.c += q.count();
		}
		return r;
	}
};

DAT d[100][MM];

using vi = vector<int>;
#define pb push_back

ll solve(ll v) {
	vi x(0);
	for(;v;v/=D)
		x.pb(v%D);
	DAT c;
	for(int i = x.size() - 1, r = 0;i >= 0;i--) {
		for(int j = 0;j < x[i];j++)
			c = c + d[i][r = md(r+g[j])];
		r = md(r + g[x[i]]);
	}
	return c.c;
}

int main() {
	F[0].reset();
	for(int i = 0;i < MN - 1;i++) F[i+1] = F[i], F[i+1][i] = 1;

	scanf("%d%d", &D, &M);
	for(int i = 0;i < D;i++) scanf("%d", g + i);
	scanf("%d", &N);
	for(int i = 0;i < N;i++) scanf("%d", b + i);
	b[N] = -1;

	for(int i = 0;i < M;i++) {
		d[0][i].l = 1;
		if(N > 1)
			for(int j = 0;j < N-1;j++)
				d[0][i].s[j] = i <= b[j], d[0][i].p[j] = i <= b[j + 1];
		else
			d[0][i].c = i <= b[0];
	}

	ll x = 1;
	for(int i = 1;x <= INF/D;i++, x *= D)
		for(int j = 0;j < M;j++) {
			d[i][j] = d[i-1][j];
			for(int k = 1;k < D;k++) d[i][j] = d[i][j] + d[i-1][md(j+g[k])];
		}

	ll A, B;
	scanf("%lld%lld", &A, &B);
	printf("%lld\n", solve(B)-solve(A+N-1));

	return 0;
}

#include<bits/stdc++.h>
const int N = 3e4 + 10;
typedef std::bitset<N> BI;
int ri() {
	char c = getchar(); int x = 0, f = 1; for(;c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(;c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct info {
	long long ans, len;
	BI pre, suf;
	info operator + (const info &b) { //Merge this and b
		info c;
		c.ans = ans + b.ans;
		c.len = len + b.len;
		c.pre = pre; c.suf = b.suf;
		if(len < n - 1) c.pre &= (b.pre >> len) | (all << n - 1 - len);
		if(b.len < n - 1) c.suf &= (suf << b.len) | (all >> n - 1 - b.len);
		if(len + b.len >= n) {
			BI res = suf & b.pre;
			if(len < n - 1) res &= (all >> n - 1 - len);
			if(b.len < n - 1) res &= (all << n - 1 - b.len);
			c.ans += res.count();
		}
		return c;
	}
	void operator += (const info &b) {*this = !len ? b : *this + b;}
}f[66][66];
long long Query(long long x) {
	info res; res.ans = res.len = 0;
	int add = 0;
	for(int i = tot; ~i; --i)
		for(int j = 1;j <= d; ++j) {
			if(x >= len[i]) {
				x -= len[i];
				res += f[i][(add + gen[j]) % m];
			}
			else {
				(add += gen[j]) %= m;
				break;
			}
		}
	return res.ans;
}
int main() {
	d = ri(); m = ri();
	for(int i = 1;i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1;i <= n; ++i)
		b[i] = ri();
	for(int i = 1;i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0;i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1;j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[j + 1];
				f[0][i].suf[j] = i <= b[j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(;len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0;i < m; ++i)
			for(int j = 1;j <= d; ++j)
				f[tot][i] += f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", Query(R) - Query(L + n - 2));
	return 0;
}

#include<bits/stdc++.h>
#define ll long long
#define BI bitset<N>

using namespace std;
const int N=3e4+10;
int n,m,d,tot,gen[30],b[N];
ll len[70],l,r;
BI full;

template<typename T>inline void read(T &x){
    x=0; bool f=0;
    char ch=getchar();
    while(!isdigit(ch)){if(ch=='-') f=1;ch=getchar();}
    while(isdigit(ch)){x=x*10+(ch^48);ch=getchar();}
    if(f) x=-x;
}

struct node{
    ll ans,len;
    BI pre,suf;
    node operator + (const node &a){
        node b;
        b.ans=ans+a.ans;
        b.len=len+a.len;
        b.pre=pre; b.suf=a.suf;
        if(len<n-1) b.pre&=(a.pre>>len)|(full<<n-1-len);
        if(a.len<n-1) b.suf&=(suf<<a.len)|(full>>n-1-a.len);
        if(len+a.len>=n){
            BI res=suf&a.pre;
            if(len<n-1) res&=(full>>n-1-len);
            if(a.len<n-1) res&=(full<<n-1-a.len);
            b.ans+=res.count();
        }
        return b;
    }
    void operator += (const node &a){*this=!len?a:*this+a;}
}f[70][70];

ll query(ll x){
    node res;
    res.ans=res.len=0;
    int tmp=0;
    for(int i=tot;~i;--i)
        for(int j=1;j<=d;j++){
            if(x>=len[i]){
                x-=len[i];
                res+=f[i][(tmp+gen[j])%m];
            }
            else{
                tmp=(tmp+gen[j])%m;
                break;
            }
        }
    return res.ans;
}

int main(){
    read(d); read(m);
    for(int i=1;i<=d;i++) read(gen[i]);
    read(n);
    for(int i=1;i<=n;i++) read(b[i]);
    for(int i=1;i<n;i++) full.set(1);
    len[tot]=1;
    for(int i=0;i<m;i++){
        f[0][i].len=1;
        if(n==1) f[0][i].ans= i<=b[1];
        else{
            for(int j=1;j<=n-1;j++){
                f[0][i].pre[j]= i<=b[j+1];
                f[0][i].suf[j]= i<=b[j];
            }
        }
    }
    read(l); read(r);
    for(;len[tot]<=r/d;){
        ++tot; len[tot]=len[tot-1]*d;
        for(int i=0;i<m;i++)
            for(int j=1;j<=d;j++)
                f[tot][i]+=f[tot-1][(i+gen[j])%m];
    }
    printf("%lld\n",query(r)-query(l+n-2));
    return 0;
}

#include<bits/stdc++.h>

#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)

using namespace std;

typedef long long LL;
typedef double db;

int get(){
	char ch;
	while(ch=getchar(),(ch<'0'||ch>'9')&&ch!='-');
	if (ch=='-'){
		int s=0;
		while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
		return -s;
	}
	int s=ch-'0';
	while(ch=getchar(),ch>='0'&&ch<='9')s=s*10+ch-'0';
	return s;
}

const int N = 3e4+5;
const int M = 65;

int d,m;
int g[25];
int b[N],n;
bool can[N][16][M];
LL mi[N];
LL L,R;
LL f[M][M][M];
int digi[M],a[M];
int sum[N*20];
int sec[N],k,start[N],val[N];
bool yes1[M],yes2[M];

LL solve(LL r){
	if (r<0)return 0;
	for(LL i=0,x=r;i<=60;x/=d,i++)digi[i]=x%d;
	int L=0;
	for(;mi[L]<=n;L++);
	L--;
	fo(i,0,60)fo(p,0,m-1)fo(u,0,m-1)f[i][p][u]=0;
	int pp=0,uu=g[1];
	fd(i,60,1){
		fo(x,0,digi[i]-1){
			int p=(pp+g[x])%m;
			int u;
			if (x==d-1)u=(uu+m-g[x])%m;else u=(g[x+1]+m-g[x])%m;
			f[i][p][u]++;
		}
		pp=(pp+g[digi[i]])%m;
		if (digi[i]==d-1)uu=(uu+m-g[d-1])%m;
		else uu=(g[digi[i]+1]+m-g[digi[i]])%m;
		fo(p,0,m-1)
			fo(u,0,m-1)
			if (f[i][p][u]){
				fo(x,0,d-1){
					int p_=(p+g[x])%m;
					int u_;
					if (x==d-1)u_=(u+m-g[x])%m;
					else u_=(g[x+1]+m-g[x])%m;
					f[i-1][p_][u_]+=f[i][p][u];
				}
			}
	}
	LL ret=0;
	int p1=0,u1=g[1];
	fd(i,60,L){
		p1=(p1+g[digi[i]])%m;
		if (digi[i]==d-1)u1=(u1+m-g[d-1])%m;
		else u1=(g[digi[i]+1]+m-g[digi[i]])%m;
	}
	fo(i,0,mi[L]-1){
		sum[i]=0;
		for(int x=i;x;x/=d)sum[i]+=g[x%d];
		sum[i]%=m;
	}
	int cnt=0;
	fo(st,0,mi[L]-1){
		k=0;
		int mid=-1;
		for(int x=1,now=st;x<=n;){
			int w1=0,w2=0;
			for(;x+mi[w1+1]-1<=n;w1++);
			for(;w2<L&&now%mi[w2+1]==0;w2++);
			int w=min(w1,w2);
			sec[++k]=w;
			start[k]=x;
			val[k]=now;
			x+=mi[w];
			now+=mi[w];
			if (now>=mi[L])mid=k+1,now-=mi[L];
		}
		if (mid==-1)mid=k+1;
		fo(i,0,m-1)yes1[i]=yes2[i]=1;
		fo(i,1,mid-1)
			fo(p,0,m-1)yes1[p]&=can[start[i]][sec[i]][(p+sum[val[i]])%m];
		fo(i,mid,k)
			fo(p,0,m-1)yes2[p]&=can[start[i]][sec[i]][(p+sum[val[i]])%m];
		fo(p,0,m-1)
		if (yes1[p])
			fo(u,0,m-1)
			if (yes2[(p+u)%m]){
				ret=ret+f[L][p][u];
				cnt++;
			}
		if (yes1[p1]&&yes2[(p1+u1)%m]&&r%mi[L]>=st)ret++;
	}
	return ret;
}

int main(){
	d=get();m=get();
	fo(i,0,d-1)g[i]=get();
	n=get();
	fo(i,1,n)b[i]=get();
	mi[0]=1;
	fo(i,1,16)mi[i]=mi[i-1]*d;
	fd(i,n,1){
		fo(p,0,b[i])can[i][0][p]=1;
		for(int j=1;i+mi[j]-1<=n;j++)
			fo(p,0,m-1){
				can[i][j][p]=1;
				fo(x,0,d-1)can[i][j][p]&=can[i+x*mi[j-1]][j-1][(p+g[x])%m];
			}
	}
	cin>>L>>R;
	R=R-n+1;
	L--,R--;
	LL vr=solve(R);
	LL vl=solve(L-1);
	cout<<vr-vl<<endl;
	return 0;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[65][65]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
	if(d==4&&m==2){
		for(int i=1;i<=n;i++) if(w[i]!=1) cout<<i<<","<<w[i]<<endl; cout<<endl;
	}
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[65][65]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
	if(d==4&&m==2) cout<<solve(r)<<","<<solve(l+n-2)<<endl;
	cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<d;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<d;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
	if(d==4&&m==2){
		for(int i=1;i<=n;i++) if(w[i]==0) cout<<i<<","; cout<<endl;
	}
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
	if(d==4&&m==2){
		for(int i=1;i<=n;i++) if(w[i]!=0) cout<<i<<","<<w[i]<<endl; cout<<endl;
	}
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[100][100]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		if(d==4&&m==2){
			cout<<f[i][0].sum<<" "; if(i%6==0) cout<<endl;
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
//	if(d==4&&m==2) cout<<solve(r)<<","<<solve(l+n-2)<<endl;
	cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[65][65]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		if(d==4&&m==2) cout<<ans.sum<<"wwww"<<endl;
		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
//	if(d==4&&m==2) cout<<solve(r)<<","<<solve(l+n-2)<<endl;
	cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[65][65]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		if(d==4&&m==2) cout<<ans.sum<<"wwww"<<endl;
		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
//	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
//	if(d==4&&m==2) cout<<solve(r)<<","<<solve(l+n-2)<<endl;
	cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r;
	cout<<solve(r)-solve(l+n-2)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[65][65]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	freopen("in.txt","r",stdin);
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
	if(d==4&&m==2){
		cout<<l<<","<<r<<endl;
	}
}

#include<bits/stdc++.h>
using namespace std;
const int N=30007;
int d,m,n,g[N],w[N],st[N]; long long l,r;
struct node{
	bitset<30007>a,b; long long len,sum;
}f[70][70]; bitset<30007>all,opt;
inline node merge(node a,node b){
	node c; c.len=a.len+b.len,c.sum=a.sum+b.sum;
	c.a=(a.a&((all>>a.len)^all))|((b.a>>a.len)&a.a);
	c.b=(b.b&((all<<b.len)^all))|((a.b<<b.len)&b.b);
	opt=(a.b&(b.a>>1));
	opt=(opt&((all<<(a.len))^all));
	opt=(opt&((all>>(b.len+1))^all));
	c.sum=c.sum+opt.count(); return c;
}
inline long long solve(long long len){
	int c=0,k=1; st[0]=0;
	while(len>0) st[++st[0]]=len%d,len/=d;
	for(int i=1;i<=st[0];i++){
		if(i>1){
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
		else{
			for(int j=0;j<m;j++){
				f[i][j]=f[i-1][j];
				for(int x=1;x<d;x++){
					f[i][j]=merge(f[i][j],f[i-1][(j+g[x])%m]);
				}
			}
		}
	}
	int opt=0; bool fl=0; node ans;
	for(int i=st[0];i>=1;i--){
		if(i>1){
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[i-1][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}
		else{
			for(int j=0;j<st[i];j++){
				if(!fl) ans=f[0][(g[j]+opt)%m],fl=1;
				else ans=merge(ans,f[i-1][(g[j]+opt)%m]);
			}
		}

		opt+=g[st[i]];
	}
	if(!fl) return 0; return ans.sum;
}
int main(){
	cin>>d>>m; for(int i=0;i<d;i++) scanf("%d",&g[i]);
	cin>>n; for(int i=1;i<=n;i++) scanf("%d",&w[i]),all[i]=1;
	for(int i=1;i<=n;i++)
		for(int j=0;j<=w[i];j++){
			f[0][j].a[i]=f[0][j].b[i]=1; if(n==1) f[0][j].sum++;
		}
	for(int i=0;i<m;i++) f[0][i].len=1;
	cin>>l>>r; cout<<solve(r)-solve(l+n-2ll)<<endl;
}

#include<bits/stdc++.h>
const int N = 3e4 + 10;
typedef std::bitset<N> BI;
long long ri() {
	char c = getchar(); long long x = 0, f = 1; for(; c < '0' || c > '9'; c = getchar()) if(c == '-') f  = -1;
	for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) - '0' + c; return x * f;
}
long long len[66];
int n, d, m, tot, gen[25], b[N];
BI all;
struct info {
	long long ans, len;
	BI pre, suf;
	info operator + (const info &b) { //Merge this and b
		info c;
		c.ans = ans + b.ans;
		c.len = len + b.len;
		c.pre = pre; c.suf = b.suf;
		if(len < n - 1) c.pre &= (b.pre << len) | (all >> n - 1 - len);
		if(b.len < n - 1) c.suf &= (suf >> b.len) | (all << n - 1 - b.len);
		if(len + b.len >= n) {
			BI res = suf & b.pre;
			if(len < n - 1) res &= (all >> n - 1 - len);
			if(b.len < n - 1) res &= (all << n - 1 - b.len);
			c.ans += res.count();
		}
		return c;
	}
	void operator += (const info &b) {*this = !len ? b : *this + b;}
} f[66][66];
long long Query(long long x) {
	info res; res.ans = res.len = 0;
	int add = 0;
	for(int i = tot; ~i; --i)
		for(int j = 1; j <= d; ++j) {
			if(x >= len[i]) {
				x -= len[i];
				res += f[i][(add + gen[j]) % m];
			}
			else {
				(add += gen[j]) %= m;
				break;
			}
		}
	return res.ans;
}
int main() {
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	d = ri(); m = ri();
	for(int i = 1; i <= d; ++i)
		gen[i] = ri();
	n = ri();
	for(int i = 1; i <= n; ++i)
		b[i] = ri();
	for(int i = 1; i < n; ++i)
		all.set(i);
	len[tot = 0] = 1;
	for(int i = 0; i < m; ++i) { //init
		f[0][i].len = 1;
		if(n == 1) f[0][i].ans = i <= b[1];
		else {
			for(int j = 1; j <= n - 1; ++j) {
				f[0][i].pre[j] = i <= b[ n - j + 1];
				f[0][i].suf[j] = i <= b[ n - j];
			}
		}
	}
	long long L = ri(), R = ri();
	for(; len[tot] <= R / d;) { //transformation
		++tot; len[tot] = len[tot - 1] * d;
		for(int i = 0; i < m; ++i)
			for(int j = 1; j <= d; ++j)
				f[tot][i] += f[tot - 1][(i + gen[j]) % m];
	}
	printf("%lld\n", Query(R) - Query(L + n - 2));
	return 0;
}

#pragma region
#include <bits/stdc++.h>
using namespace std;
#define ri register int
#define il inline
#define LL long long
#define uint unsigned int
#define ull unsigned long long
#define solid const auto &
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define pll pair<LL,LL>
#define fi first
#define se second
#define gm int mid((l+r)/2)
#define space putchar(' ')
#define enter putchar('\n')
#define rd() ({ri t;in(t);t;})
#define Size(x) ((int)x.size())
#define mem(x,y) memset(x,y,sizeof(x))
template<class T>il void in(T &x)
{
	x=0; char c=getchar(); bool f=0;
	while(!isdigit(c)) f|=(c=='-'),c=getchar();
	while(isdigit(c)) x=x*10+(c^'0'),c=getchar();
	f?x=-x:0;
}
template<class T>il void out(T x,const char c='\n')
{
	static short st[30]; short m=0;
	if(x<0) {if(x==-2147483648) {printf("-2147483648"); return;} putchar('-'),x=-x;}
	do st[++m]=x%10,x/=10; while(x);
	while(m) putchar(st[m--]|'0');
	putchar(c);
}
template<class T,class ...Args>il void in(T &x,Args &...args) {in(x); in(args...);}
template<class T,class ...Args>il void out(const T &x,const Args &...args) {out(x,' '); out(args...);}
template<class T>il void prt(T a[],int n) {for(ri i=0; i<n; ++i) out(a[i],' '); enter;}
template<class T>il void clr(T a[],int n) {memset(a,0,sizeof(T)*n);}
template<class T>il void clr(T *a,T *b) {memset(a,0,sizeof(T)*(b-a));}
template<class T>il bool ckmax(T &a,const T &b) {return a<b?a=b,1:0;}
template<class T>il bool ckmin(T &a,const T &b) {return a>b?a=b,1:0;}
namespace MOD_CALC
{
const int md=1e9+7;
il int add(const int a,const int b) {return a+b>=md?a+b-md:a+b;}
il int sub(const int a,const int b) {return a-b<0?a-b+md:a-b;}
il int mul(const int a,const int b) {return (LL)a*b%md;}
il void inc(int &a,const int b) {(a+=b)>=md?a-=md:0;}
il void dec(int &a,const int b) {(a-=b)<0?a+=md:0;}
il int qpow(int a,int b) {int r=1; for(; b; b>>=1,a=mul(a,a)) if(b&1) r=mul(r,a); return r;}
il int qpow(int a,int b,const int p) {int r=1; for(; b; b>>=1,a=(LL)a*a%p) if(b&1) r=(LL)r*a%p; return r;}
il int mdinv(const int a) {return qpow(a,md-2);}
template<class ...Args>il int add(const int a,const int b,const Args &...args) {return add(add(a,b),args...);}
template<class ...Args>il int mul(const int a,const int b,const Args &...args) {return mul(mul(a,b),args...);}
} using namespace MOD_CALC;
namespace i207M
{
#pragma endregion
typedef bitset<30005> B;
int n;
B all;
struct Data
{
	LL len,ans;
	B pre,suf;
	il friend Data operator+(const Data &a,const Data &b)
	{
		Data c; c.len=a.len+b.len,c.ans=a.ans+b.ans;
		c.pre=a.pre,c.suf=b.suf;
		if(a.len<n-1) c.pre&=(b.pre<<a.len)|(all>>(n-a.len-1));
		if(b.len<n-1) c.suf&=(a.suf>>b.len)|(all<<(n-b.len-1));
		if(c.len>=n)
		{
			B t=a.suf&b.pre;
			if(a.len<n-1) t&=(all<<(n-a.len-1));
			if(b.len<n-1) t&=(all>>(n-b.len-1));
			c.ans+=t.count();
		}
		return c;
	}
	il void operator+=(const Data &v)
	{
		if(!len) *this=v;
		else *this=*this+v;
	}
} f[65][65];
int d,m;
int gen[25];
LL len[65],tot;
LL query(LL R)
{
	Data res; res.len=0;
	int tag=0;
	for(ri i=tot; i>=0; --i)
		for(ri j=1; j<=d; ++j)
			if(R>=len[i])
			{
				res+=f[i][(tag+gen[j])%m];
				R-=len[i];
			}
			else {(tag+=gen[j])%=m; break;}
	return res.ans;
}
int b[30005];
LL L,R;
signed main()
{
#ifdef M207
	freopen("in.in","r",stdin);
	// freopen("ot.out","w",stdout);
#endif
	in(d,m);
	for(ri i=1; i<=d; ++i) in(gen[i]);
	in(n);
	for(ri i=1; i<=n; ++i) in(b[i]);
	for(ri i=1; i<n; ++i) all[i]=1;
	len[0]=1;
	for(ri i=0; i<m; ++i)
	{
		f[0][i].len=1;
		if(n==1) f[0][i].ans=(i<=b[i]);
		else
		{
			for(ri j=1; j<n; ++j)
			{
				f[0][i].pre[j]=(i<=b[n-j+1]);
				f[0][i].suf[j]=(i<=b[n-j]);
			}
		}
	}
	in(L,R);
	while(len[tot]<=R/d)
	{
		++tot,len[tot]=len[tot-1]*d;
		for(ri i=0; i<m; ++i)
			for(ri j=1; j<=d; ++j)
				f[tot][i]+=f[tot-1][(i+gen[j])%m];
	}
	LL ans=query(R)-query(L+n-2);
	out(ans);
	return 0;
}
#pragma region
}
signed main()
{
	i207M::main();
	return 0;
}
#pragma endregion

#include <bits/stdc++.h>
#ifdef local
#define Auto "%lld"
#else
#define Auto "%I64d"
#endif
using namespace std;
typedef bool boolean;

const int N = 3e4 + 5;

#define ll long long

typedef class Data {
	public:
		ll ans, len;
		bitset<N> pre, suf;
		// pre_i : first (n - i - 1) characters
		// suf_i : last (i + 1) characters

		Data() : ans(0), len(0) {	}
} Data;

bitset<N> msk;

void debug(const bitset<N>& bs, int lim) {
	for (int i = lim - 1; ~i; i--) {
		putchar('0' + bs.test(i));
	}
}

int n, d, m;
int cnt = 1;
int *gen, *a;
Data f[66][65];
ll len[65], L, R;

ostream& operator << (ostream& os, const bitset<N>& bs) {
	debug(bs, n - 1);
	return os;
}

bitset<N> reserve(const bitset<N>& bs, int l, int r) {
	assert(l <= r);
	r++;
	return ((bs >> l) << (N - (r - l))) >> (N - r);;
}

Data operator + (const Data& a, const Data& b) {
	Data rt;
	rt.pre = a.pre, rt.suf = b.suf;
	rt.ans = a.ans + b.ans, rt.len = a.len + b.len;
	if (a.len < n - 1)
		rt.pre = ((b.pre >> a.len) & a.pre) | reserve(a.pre, n - a.len - 1, n);
	if (b.len < n - 1)
		rt.suf = ((a.suf << b.len) & b.suf) | reserve(b.suf, 0, b.len - 1);
	if (a.len + b.len > n - 1) {
// i <= a.len, n - i <= b.len
// i <= a.len, i >= n - b.len
		int l = max(1ll, n - b.len) - 1, r = min((ll) n, a.len) - 1;
		if (l <= r) {
			rt.ans += (reserve(a.suf, l, r) & b.pre).count();
		}
	}
	return rt;
}

inline void init() {
	scanf("%d%d", &d, &m);
	gen = new int[(d + 1)];
	for (int i = 0; i < d; i++) {
		scanf("%d", gen + i);
	}
	scanf("%d", &n);
	a = new int[(n + 1)];
	for (int i = 0; i < n; i++) {
		scanf("%d", a + i);
	}
	scanf(Auto""Auto, &L, &R);
}

ll Solve(ll L) {
	Data rt;
	rt.pre = msk, rt.suf = msk;
	int add = 0;
	for (int i = cnt; ~i; i--) {
		int dif = 0;
		for (int j = 0; L >= len[i]; j++, L -= len[i]) {
			dif = gen[j + 1];
			rt = rt + f[i][(add + gen[j]) % m];
		}
		add = (add + dif) % m;
	}
	return rt.ans;
}

inline void solve() {
	for (int i = 0; i < n - 1; i++)
		msk.set(i);
	len[0] = 1, len[1] = d;
	for (int i = 0; i < m; i++) {
		f[0][i].len = 1, f[0][i].ans = (n == 1 && i <= a[0]);
		for (int j = 0; j < n - 1; j++) {
			f[0][i].pre[j] = (i <= a[n - j]);
			f[0][i].suf[j] = (i <= a[j]);
		}
	}
	for (int i = 0; i < m; i++) {
		f[1][i].len = d, f[1][i].ans = 0;
		if (d >= n) {
			for (int s = 0; s <= d - n; s++) {
				int dif = 1;
				for (int j = 0; j < n && dif == 1; j++) {
					dif -= (((gen[s + j] + i) % m) > a[j]);
				}
				f[1][i].ans += dif;
			}
		}
		for (int l = 0; l < n - 1; l++) {
			int sgn_pre = 1, sgn_suf = 1;
			for (int j = 0; j < d && j <= l && (sgn_pre + sgn_suf); j++) {
				sgn_suf = sgn_suf && (((gen[d - j - 1] + i) % m) <= a[l - j]);
				sgn_pre = sgn_pre && (((gen[j] + i) % m) <= a[n - l - 1 + j]);
			}
			f[1][i].suf[l] = sgn_suf;
			f[1][i].pre[n - l - 2] = sgn_pre;
		}
//		cerr << "> " << 1 << " " << i << '\n';
//		cerr << ">> ans: " << f[1][i].ans << '\n';
//		cerr << ">> pre: " << f[1][i].pre << '\n';
//		cerr << ">> suf: " << f[1][i].suf << '\n';
	}
	while (len[cnt] < R) {
		len[cnt + 1] = len[cnt] * d, cnt++;
		for (int i = 0; i < m; i++) {
			Data& F = f[cnt][i];
			F.pre = msk, F.suf = msk;
			for (int j = 0; j < d; j++) {
				F = F + f[cnt - 1][(i + gen[j]) % m];
			}
//			cerr << "> " << cnt << " " << i << '\n';
//			cerr << ">> ans: " << F.ans << '\n';
//			cerr << ">> pre: " << F.pre << '\n';
//			cerr << ">> suf: " << F.suf << '\n';
		}
	}
	ll _ = Solve(R);
	ll __ = Solve(L + n - 2);
//	cerr << _ << " " << __ << '\n';
	printf(Auto, _ - __);
}

int main() {
	init();
	solve();
	return 0;
}