#include <iostream>
#include <vector>
#include <algorithm>
#include <queue>
#include <functional>
#include <map>
#include <climits>
#include <stack>
#include <string>
#include <random>
#include<set>
#include <iomanip>
#include <climits>
#include <memory>
#include <cassert>
struct Point {
	int x, y;
	int manhattan_distance(const Point &other) const { return std::abs(x - other.x) + std::abs(y - other.y); }
};
struct Key_with_value {
	int key, value;
	bool operator>(const Key_with_value &kv) const { return key > kv.key; }
};
struct Edge {
	int to, cost, pair;
	bool can_use;
};
std::vector<std::vector<Edge>> make_graph(const std::vector<Point> &person, const std::vector<Point> &hall) {
	std::vector<std::vector<Edge>> result(person.size() + hall.size() + 2);
	const int start = 0;
	const int goal = result.size() - 1;
	result[start] = std::vector<Edge>(person.size());
	result[goal] = std::vector<Edge>(hall.size());
	for (auto i = 0; i < person.size(); ++i) {
		result[i + 1] = std::vector<Edge>(hall.size() + 1);
		result[i + 1][0] = Edge{ start, 0, i, false };
		result[start][i] = Edge{ i + 1, 0, 0, true};
	}
	for (auto i = 0; i < hall.size(); ++i) {
		result[i + person.size() + 1] = std::vector<Edge>(person.size() + 1);
		result[i + person.size() + 1][0] = Edge{ goal, 0, i, true };
		result[goal][i] = Edge{ i + (int)person.size() + 1, 0, 0, false };
	}
	for (auto p = 0; p < person.size(); ++p) {
		for (auto h = 0; h < hall.size(); ++h) {
			auto distance = person[p].manhattan_distance(hall[h]);
			result[p + 1][h + 1] = Edge{ h + (int)person.size() + 1, distance, p + 1, true };
			result[h + person.size() + 1][p + 1] = { p + 1, -distance, h + 1, false};
		}
	}
	return result;
}
int min_cost_max_flow(std::vector<std::vector<Edge>> nodes, std::vector<int> capacities, const int distance) {
	std::vector<int> potential(nodes.size(), 0);
	std::vector<int> min_cost(nodes.size(), 0);
	std::vector<Edge*> prev_edge(nodes.size(), nullptr);
	const int start = 0;
	const int goal = nodes.size() - 1;
	const int separation = nodes.size() - 1 - capacities.size();
	int result = 0;
	for (auto &line : nodes) for (auto &cell : line) {
		if (cell.cost > distance) cell.cost -= distance;
		else if (cell.cost < -distance) cell.cost += distance;
		else cell.cost = 0;
	}
	std::priority_queue<Key_with_value, std::vector<Key_with_value>, std::greater<Key_with_value>> queue;
	while (true) {
		for (auto i = 1; i < min_cost.size(); ++i) min_cost[i] = INT_MAX;
		queue.push(Key_with_value{ 0, start });
		while (!queue.empty()) {
			auto top = queue.top(); queue.pop();
			if (min_cost[top.value] == top.key) {
				for (const auto &next : nodes[top.value]) {
					if (!next.can_use) continue;
					if (min_cost[next.to] > top.key + next.cost + potential[top.value] - potential[next.to]) {
						min_cost[next.to] = top.key + next.cost + potential[top.value] - potential[next.to];
						prev_edge[next.to] = &nodes[next.to][next.pair];
						if (next.to != goal) queue.push({ min_cost[next.to], next.to });
					}
				}
			}
		}
		if (min_cost[goal] != INT_MAX) {
			result += min_cost[goal];
			--capacities[prev_edge[goal]->to - separation];
			if (capacities[prev_edge[goal]->to - separation] == 0) {
				nodes[prev_edge[goal]->to][prev_edge[goal]->pair].can_use = false;
			}
			auto last = prev_edge[goal]->to;
			while (last != start) {
				prev_edge[last]->can_use = true;
				nodes[prev_edge[last]->to][prev_edge[last]->pair].can_use = false;
				last = prev_edge[last]->to;
			}
			for (auto i = 1; i < potential.size() - 1; ++i) potential[i] += min_cost[i];
		}
		else {
			break;
		}
	}
	return result;
}
void solve() {
	int n, m, b; std::cin >> n >> m >> b;
	if (n == 0) return;
	std::vector<Point> persons(n); for (auto &person : persons) std::cin >> person.x >> person.y;
	std::vector<Point> halls(m); std::vector<int> capacities(m); std::vector<int> fees(m);
	for (auto i = 0; i < m; ++i) std::cin >> halls[i].x >> halls[i].y >> capacities[i] >> fees[i];
	int min = INT_MAX;
	for (auto usage = 1; usage < (1 << m); ++usage) {
		std::vector<Point> use_hall;
		std::vector<int> use_capacities;
		int sum_capacity = 0;
		int sum_fee = 0;
		for (auto i = 0; i < m; ++i) {
			if (((1 << i) & usage) != 0) {
				use_hall.push_back(halls[i]);
				use_capacities.push_back(capacities[i]);
				sum_capacity += capacities[i];
				sum_fee += fees[i];
			}
		}
		if (sum_capacity >= n) {
			auto nodes = make_graph(persons, use_hall);
			auto left = 0;
			auto right = 4000;
			while (left < right) {
				auto mid = (left + right) / 2;
				auto c = min_cost_max_flow(nodes, use_capacities, mid + 1) - min_cost_max_flow(nodes, use_capacities, mid) + b * (int)use_hall.size();
				if (c < 0) {
					left = mid + 1;
				}
				else {
					right = mid;
				}
			}
			auto c = min_cost_max_flow(nodes, use_capacities, right);
			if (min > c + right * b * use_hall.size() + sum_fee) {
				min = c + right * b * use_hall.size() + sum_fee;
			}
		}
	}
	std::cout << min << std::endl;
	solve();
}
int main() {
	solve();
}


Measured memory_bytes: 3248