2 10 1 1 1
1
10
1
1 5 1 8
 4 4 1 0 1
1

1
1 2 1 4
 2 5 1 0 1
2

1
1 4 1 5
 10 10 1 8 4
10
2 3 4 5 6 7 8 9
10
1 1 3 1
2 1 7 1
1 1 9 1
7 1 4 1
10 1 7 1
2 1 7 1
3 1 2 1
5 1 2 1
10 1 5 1
6 1 9 1
 2 4 1 1 1
1
4
1
1 2 1 3
 2 2 0 1 1

1
1
1 2 2 2
 1000 1000 1 1 10
1
2
1
1 900 1 1000
 5 5 1 1 1
3
2
1
1 5 1 1
 2 4 1 1 1
1
2
1
2 3 2 4
 4 4 1 0 1
4

5
1 1 2 2
1 3 2 2
3 3 4 3
3 2 2 2
1 2 2 3

3
 2
 1
 3
4
4
3
3
4
3
3
4
3
 1
 3
 100
 4
 1
 6
4
3
5
4

#include <bits/stdc++.h>
using namespace std;
namespace rnd {
unsigned int seed = static_cast<unsigned int>(
    std::chrono::system_clock::now().time_since_epoch().count());
std::mt19937 gen(seed);
std::uniform_int_distribution<> distribution(INT_MIN, INT_MAX);
int randint() { return distribution(gen); }
}  // namespace rnd
class CartesianTree {
 private:
  struct Node {
    Node() = delete;
    explicit Node(int key)
        : key(key),
          priority(rnd::randint()),
          count(0),
          left(nullptr),
          right(nullptr){};
    int key, priority, count;
    Node *left, *right;
  };
  using Pointer = Node *;
  Pointer root{};
  int count(Pointer node) { return node ? node->count : 0; }
  int update(Pointer node) {
    if (node) {
      node->count = count(node->left) + count(node->right) + 1;
    }
  }
  void split(Pointer tree, int key, Pointer &left, Pointer &right) {
    if (!tree) {
      left = right = nullptr;
    } else {
      if (key < tree->key) {
        split(tree->left, key, left, tree->left);
        right = tree;
      } else {
        split(tree->right, key, tree->right, right);
        left = tree;
      }
      update(tree);
    }
  }
  void merge(Pointer &tree, Pointer left, Pointer right) {
    if (!left || !right) {
      tree = left ? left : right;
    } else {
      if (left->priority > right->priority) {
        merge(left->right, left->right, right);
        tree = left;
      } else {
        merge(right->left, left, right->left);
        tree = right;
      }
    }
    update(tree);
  }
  int get_key(Pointer tree, int position) {
    if (position < count(tree->left)) {
      return get_key(tree->left, position);
    } else if (position == count(tree->left)) {
      return tree->key;
    } else {
      return get_key(tree->right, position - count(tree->left) - 1);
    }
  }

 public:
  CartesianTree() : root(nullptr){};
  void insert(int key) {
    Pointer left, right;
    split(root, key, left, right);
    merge(left, left, new Node(key));
    merge(root, left, right);
  }
  void remove(int key) {
    Pointer left, mid, right;
    split(root, key, left, right);
    split(left, key - 1, left, mid);
    merge(root, left, right);
  }
  int right(int key) {
    Pointer left, right;
    split(root, key, left, right);
    int res = right ? right->key : -1;
    merge(root, left, right);
    return res;
  }
  int left(int key) {
    Pointer left, right;
    split(root, key, left, right);
    int res = left ? left->key : -1;
    merge(root, left, right);
    return res;
  }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  unsigned int n, m, cl, ce, v;
  cin >> n >> m >> cl >> ce >> v;
  CartesianTree ladders, elevators;
  for (int i = 0; i < cl; i++) {
    int l;
    cin >> l;
    ladders.insert(l);
  }
  for (int i = 0; i < ce; i++) {
    int e;
    cin >> e;
    elevators.insert(e);
  }
  unsigned int q;
  cin >> q;
  for (int i = 0; i < q; i++) {
    unsigned int x1, y1, x2, y2;
    cin >> x1 >> y1 >> x2 >> y2;
    if (y1 > y2) {
      unsigned int tmp = y1;
      y1 = y2;
      y2 = tmp;
    }
    int result = 0, dx = max(x1, x2) - min(x1, x2);
    int r1 = elevators.right(y1);
    if (r1 < y2 && r1 != -1) {
      result = y2 - y1 + (dx + v - 1) / v;
    } else {
      int r2 = ladders.right(y1), r3 = elevators.left(y1),
          r4 = elevators.right(y2), r5 = ladders.left(y1),
          r6 = ladders.right(y2);
      int res1 = r2 != -1 ? y1 - r2 + y2 - r2 + dx : INT_MAX,
          res2 = r3 != -1 ? y1 - r3 + y2 - r3 + (dx + v - 1) / v : INT_MAX,
          res3 = r4 != -1 ? r4 - y1 + r4 - y2 + (dx + v - 1) / v : INT_MAX,
          res4 = r5 != -1 ? y1 - r5 + y2 - r5 + dx : INT_MAX,
          res5 = r6 != -1 ? r6 - y1 + r6 - y2 + dx : INT_MAX;
      result = min(res1, min(min(res2, res3), min(res4, res5)));
    }
    cout << result << '\n';
  }
  return 0;
}
