#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
using namespace std;
template <class T>
bool ckmin(T &a, const T &b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T &a, const T &b) {
  return a < b ? a = b, 1 : 0;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MOD = 998244353;
const char nl = '\n';
const int MX = 300001;
long long modExp(long long base, long long power) {
  if (power == 0) {
    return 1;
  } else {
    long long cur = modExp(base, power / 2);
    cur = cur * cur;
    cur = cur % MOD;
    if (power % 2 == 1) cur = cur * base;
    cur = cur % MOD;
    return cur;
  }
}
long long inv(long long base) {
  int g = MOD, r = base, x = 0, y = 1;
  while (r != 0) {
    int q = g / r;
    g %= r;
    swap(g, r);
    x -= q * y;
    swap(x, y);
  }
  return x < 0 ? x + MOD : x;
}
long long mul(long long A, long long B) { return (A * B) % MOD; }
long long add(long long A, long long B) { return (A + B) % MOD; }
long long dvd(long long A, long long B) { return mul(A, inv(B)); }
long long sub(long long A, long long B) { return (A - B + MOD) % MOD; }
namespace NTT {
vector<long long> roots = {0, 1};
vector<int> bit_reverse;
int max_size = -1;
long long root;
bool is_power_of_two(int n) { return (n & (n - 1)) == 0; }
int round_up_power_two(int n) {
  while (n & (n - 1)) n = (n | (n - 1)) + 1;
  return max(n, 1);
}
int get_length(int n) {
  assert(is_power_of_two(n));
  return __builtin_ctz(n);
}
void bit_reorder(int n, vector<long long> &values) {
  if ((int)bit_reverse.size() != n) {
    bit_reverse.assign(n, 0);
    int length = get_length(n);
    for (int i = 0; i < n; i++)
      bit_reverse[i] = (bit_reverse[i >> 1] >> 1) + ((i & 1) << (length - 1));
  }
  for (int i = 0; i < n; i++)
    if (i < bit_reverse[i]) swap(values[i], values[bit_reverse[i]]);
}
void find_root() {
  max_size = 1 << __builtin_ctz(MOD - 1);
  root = 2;
  while (!(modExp(root, max_size) == 1 && modExp(root, max_size / 2) != 1))
    root++;
}
void prepare_roots(int n) {
  if (max_size < 0) find_root();
  assert(n <= max_size);
  if ((int)roots.size() >= n) return;
  int length = get_length(roots.size());
  roots.resize(n);
  while (1 << length < n) {
    long long z = modExp(root, max_size >> (length + 1));
    for (int i = 1 << (length - 1); i < 1 << length; i++) {
      roots[2 * i] = roots[i];
      roots[2 * i + 1] = (roots[i] * z) % MOD;
    }
    length++;
  }
}
void fft_iterative(int N, vector<long long> &values) {
  assert(is_power_of_two(N));
  prepare_roots(N);
  bit_reorder(N, values);
  for (int n = 1; n < N; n *= 2)
    for (int start = 0; start < N; start += 2 * n)
      for (int i = 0; i < n; i++) {
        long long even = values[start + i];
        long long odd = values[start + n + i] * roots[n + i];
        odd %= MOD;
        values[start + n + i] = even - odd + MOD;
        values[start + i] = even + odd;
        values[start + n + i] %= MOD;
        values[start + i] %= MOD;
      }
}
const int FFT_CUTOFF = 150;
vector<long long> mod_multiply(vector<long long> left,
                               vector<long long> right) {
  int n = left.size();
  int m = right.size();
  if (min(n, m) < FFT_CUTOFF) {
    const uint64_t ULL_BOUND =
        numeric_limits<uint64_t>::max() - (uint64_t)MOD * MOD;
    vector<uint64_t> result(n + m - 1, 0);
    for (int i = 0; i < n; i++)
      for (int j = 0; j < m; j++) {
        result[i + j] += (uint64_t)((int)left[i]) * ((int)right[j]);
        if (result[i + j] > ULL_BOUND) result[i + j] %= MOD;
      }
    for (uint64_t &x : result)
      if (x >= MOD) x %= MOD;
    return vector<long long>(result.begin(), result.end());
  }
  int N = round_up_power_two(n + m - 1);
  left.resize(N);
  right.resize(N);
  bool equal = left == right;
  fft_iterative(N, left);
  if (equal)
    right = left;
  else
    fft_iterative(N, right);
  long long inv_N = inv(N);
  for (int i = 0; i < N; i++) {
    left[i] *= (right[i] * inv_N) % MOD;
    left[i] %= MOD;
  }
  reverse(left.begin() + 1, left.end());
  fft_iterative(N, left);
  left.resize(n + m - 1);
  return left;
}
vector<long long> mod_power(const vector<long long> &v, int exponent) {
  assert(exponent >= 0);
  vector<long long> result = {1};
  if (exponent == 0) return result;
  for (int k = 31 - __builtin_clz(exponent); k >= 0; k--) {
    result = mod_multiply(result, result);
    if (exponent >> k & 1) result = mod_multiply(result, v);
  }
  return result;
}
vector<long long> mod_multiply_all(
    const vector<vector<long long>> &polynomials) {
  if (polynomials.empty()) return {1};
  struct compare_size {
    bool operator()(const vector<long long> &x, const vector<long long> &y) {
      return x.size() > y.size();
    }
  };
  priority_queue<vector<long long>, vector<vector<long long>>, compare_size> pq(
      polynomials.begin(), polynomials.end());
  while (pq.size() > 1) {
    vector<long long> a = pq.top();
    pq.pop();
    vector<long long> b = pq.top();
    pq.pop();
    pq.push(mod_multiply(a, b));
  }
  return pq.top();
}
}  // namespace NTT
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int N, K;
  cin >> N >> K;
  int cnt[MX];
  for (int i = 0; i < (MX); i++) cnt[i] = 0;
  for (int i = 0; i < (N); i++) {
    int X;
    cin >> X;
    cnt[X]++;
  }
  vector<long long> B(K);
  for (int i = 0; i < (K); i++) cin >> B[i];
  vector<vector<long long>> poly;
  for (int it = 0; it < (K); it++) {
    vector<vector<long long>> polys;
    for (int i = 0; i < (B[it]); i++) {
      if (cnt[i] == 1) {
        polys.push_back({1, 2});
      } else if (cnt[i] >= 2) {
        polys.push_back({1, 2, 1});
      }
    }
    poly.push_back(NTT::mod_multiply_all(polys));
  }
  int Q;
  cin >> Q;
  while (Q--) {
    int Q;
    cin >> Q;
    int ans = 0;
    for (int i = 0; i < (K); i++) {
      int cur = (Q - B[i] * 2 - 2) / 2;
      if (cur < 0 || cur >= (int)(poly[i]).size()) continue;
      ans += poly[i][cur];
      ans %= MOD;
    }
    cout << ans << nl;
  }
  return 0;
}
