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

int N, M, X, Y;
vector<int> A, B;
int D[6001], E[6001][6001];

int combination(auto n, auto r) {
  if(n < r) return 0;
  auto res = 1;
  for(auto i = 0; i < r; ++i) res *= n - i;
  for(auto i = 0; i < r; ++i) res /= i + 1;
  return res;
}

int straight() {
  auto four = 0, eight = 0, twelve = 0;
  for(auto i: D) {
    if(12 <= i) ++twelve;
    if( 8 <= i) ++eight;
    if( 4 <= i) ++four;
  }
  return combination(four, 3) + combination(eight, 1) * combination(four - 1, 1) + combination(twelve, 1);
}

vector<vector<int>> split() {
  static vector<vector<int>> memo;
  if(!memo.empty()) return memo;
  vector<vector<int>> res;
  vector<int> v(3);
  function<void(int, int)> dfs = [&](auto x, auto d) {
    if(d == 3) {
      if(x == 0) res.emplace_back(v);
      return;
    }
    for(auto i = 0; i <= min(4, x); ++i) {
      v[d] = i;
      dfs(x - i, d + 1);
    }
  };
  dfs(X, 0);
  return memo = res;
}

bool cube(auto x) {
  if(E[x][x] < X) return false;
  if(2 * X + D[x] < 12) return false;
  return true;
}

bool cuboidA(auto x, auto y) {
  if(E[x][x] + E[x][y] < X) return false;
  if(2 * E[x][x] + E[x][y] + D[x] < 8) return false;
  if(E[x][y] + D[y] < 4) return false;
  for(auto i = 0; i <= X; ++i) {
    auto j = X - i;
    if(E[x][x] < i) continue;
    if(E[x][y] < j) continue;
    if(8 < 2 * i + j) continue;
    if(4 < j) continue;
    if(8 <= 2 * i + j + D[x] && 4 <= j + D[y]) return true;
  }
  return false;
}

bool cuboidB(auto x, auto y) {
  if(E[x][y] + E[y][y] < X) return false;
  if(E[x][y] + D[x] < 4) return false;
  if(E[x][y] + 2 * E[y][y] + D[y] < 8) return false;
  for(auto i = 0; i <= X; ++i) {
    auto j = X - i;
    if(E[x][y] < i) continue;
    if(E[y][y] < j) continue;
    if(4 < i) continue;
    if(8 < i + 2 * j) continue;
    if(4 <= i + D[x] && 8 <= i + 2 * j + D[y]) return true;
  }
  return false;
}

bool cuboidC(auto x, auto y, auto z) {
  if(E[x][y] + E[x][z] + E[y][z] < X) return false;
  if(E[x][y] + E[x][z] + D[x] < 4) return false;
  if(E[x][z] + E[y][z] + D[z] < 4) return false;
  if(E[x][y] + E[y][z] + D[y] < 4) return false;
  for(auto v: split()) {
    if(E[x][y] < v[0]) continue;
    if(E[x][z] < v[1]) continue;
    if(E[y][z] < v[2]) continue;
    auto a = v[0] + v[1];
    auto b = v[0] + v[2];
    auto c = v[1] + v[2];
    if(4 < a || 4 < b || 4 < c) continue;
    if(4 <= a + D[x] && 4 <= b + D[y] && 4 <= c + D[z]) return true;
  }
  return false;
}

int solve() {
  auto res = 0;
  set<long long> used;
  auto memo = [](const auto& L) {return L[0] + 1e4*L[1] + 1e8*L[2];};
  for(auto i = 0; i < M; ++i) for(auto j = 1; j <= 6000; ++j) {
    vector<int> L = {A[i], B[i], j};
    sort(begin(L), end(L));

    bool ok;
    if(L[0] == L[2])      ok = cube(L[0]);
    else if(L[0] == L[1]) ok = cuboidA(L[0], L[2]);
    else if(L[1] == L[2]) ok = cuboidB(L[0], L[1]);
    else                  ok = cuboidC(L[0], L[1], L[2]);

    if(!ok) continue;
    if(used.count(memo(L))) continue;
    used.emplace(memo(L));
    ++res;
  }
  return res;
}

int main() {
  cin >> N >> M >> X >> Y;
  A.resize(N);
  for(auto& i: A) cin >> i;
  B.resize(M);
  for(auto& i: B) cin >> i;

  for(auto i = 0; i < N; ++i) {
    if(i < M) {
      A[i] -= B[i];
      if(A[i] > B[i]) swap(A[i], B[i]);
      ++E[A[i]][B[i]];
    } else {
      ++D[A[i]];
    }
  }

  if(X) cout << solve() << endl;
  else  cout << straight() << endl;
}



Measured memory_bytes: 9616