#include <bits/stdc++.h>   using namespace std;   void DEBUG(vector<long long> a) {     printf( { );     for (long long x : a) printf( %lld  , x);     printf( } n );   }   int mod;   void DEBUG(long long mask) {     printf( mask:  );     for (int i = 0; i < mod; ++i) printf( %d , (mask >> i) & 1);     printf(  n );   }   struct TorSum {     int n, m;     long long** a;     long long** pref;     TorSum(){};     TorSum(long long** _a) : n(mod), m(mod) {       a = new long long*[n];       for (int i = 0; i < n; ++i) {         a[i] = new long long[m];         for (int j = 0; j < m; ++j) a[i][j] = _a[i][j];       }       pref = new long long*[n + 1];       for (int i = 0; i <= n; ++i) {         pref[i] = new long long[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];     }     long long stupid(int lx, int rx, int ly, int ry) {       if (lx == -1 || rx == -1 || ly == -1 || ry == -1) return 0;       long long 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;     }     long long get_sum_safe(int lx, int rx, int ly, int ry) {       return pref[rx][ry] - pref[rx][ly] - pref[lx][ry] + pref[lx][ly];     }     long long get_sum(int lx, int rx, int ly, int ry) {       if (lx == -1 || rx == -1 || ly == -1 || ry == -1) return 0;       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(long long r, long long d) {     int k = 0;     for (long long pw = 1; pw <= r / d; ++k) pw *= d;     return k;   }   long long mpow(long long x, int k) {     long long res = 1;     while (k--) res *= x;     return res;   }   int a[66];   vector<pair<int, int>> split_segment(long long 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<pair<int, int>> 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 = long long*;   int d;   int logn;   int gen[D];   vector<int> big_gen;   long long pwd[66];   long long jump[N][LOG];   pair<vector<pair<int, int>>, vector<pair<int, int>>> 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<long long, Zet> cnt;   Zet get_cnt(long long r) {     if (r <= 0) return zeroes;     if (cnt.count(r)) return cnt[r];     Zet res = new long long[mod];     for (int x = 0; x < mod; ++x) res[x] = 0;     int k = mlog(r, d);     long long 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(long long& mask1, long long mask2, int shift) {     long long shift_mask = mask2 & ((1LL << shift) - 1);     mask1 &= ((mask2 >> shift) | (shift_mask << (mod - shift)));   }   long long query(int l, int r, int pos) {     long long 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<long long, TorSum> solver;   long long get_sum(long long 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 long long[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] = TorSum(a);     }     return solver[R].get_sum(lx, rx, ly, ry);   };   long long solve(long long R) {     long long res = 0;     for (int rem = 0; rem < pwd[logn] && rem <= R; ++rem) {       vector<pair<int, int>>& v1 = segments[rem].first;       vector<pair<int, int>>& 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() {     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 (; (int)(big_gen).size() < 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] < (long long)4e17) {       long long 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]);       }     }     end = clock();     start = clock();     for (int rem = 0; rem <= pwd[logn] - n; ++rem) {       long long draw = query(rem, rem + n, 0);       segments[rem] = {split_segment(draw), {{0, mod - 1}}};     }     end = clock();     start = clock();     for (int rem = pwd[logn] - n + 1; rem < pwd[logn]; ++rem) {       long long draw1 = query(rem, pwd[logn], 0);       long long draw2 = query(0, n - (pwd[logn] - rem), pwd[logn] - rem);       segments[rem] = {split_segment(draw1), split_segment(draw2)};     }     end = clock();     zeroes = new long long[mod];     for (int x = 0; x < mod; ++x) zeroes[x] = 0;     cnt[0] = zeroes;     Zet ozero = new long long[mod];     for (int x = 0; x < mod; ++x) ozero[x] = 0;     ozero[0] = 1;     cnt[1] = ozero;     start = clock();     long long l, r;     scanf( %lld %lld , &l, &r);     --l;     --r;     printf( %lld n , solve(r - n + 1) - solve(l - 1));     end = clock();   }