#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;

#define NUM 150

struct Info{
	int x,y,capacity,fee;
};


//辺を表す構造体{行先、容量、コスト、逆辺のインデックス}
struct Edge{
	Edge(int arg_to,int arg_capacity,int arg_cost,int arg_rev_index){
		to = arg_to;
		capacity = arg_capacity;
		cost = arg_cost;
		rev_index = arg_rev_index;
	}

	int to,capacity,cost,rev_index;
};

int N,M,B;
int V; //頂点数
int POW[6];
vector<Edge> G[NUM]; //グラフの隣接リスト表現
int dist[NUM]; //最短距離
int pre_node[NUM],pre_edge[NUM]; //直前の頂点と辺
Info student[100],house[5];


//fromからtoへ向かう容量capacity,コストcostの辺をグラフに追加する
void add_edge(int from,int to,int capacity,int cost){
	G[from].push_back(Edge(to,capacity,cost,G[to].size()));
	G[to].push_back(Edge(from,0,-cost,G[from].size()-1));
}

//sourceからsinkへの、流量flowの最小費用流を求める
//流せない場合は-1を返す
int min_cost_flow(int source,int sink,int flow){
	int ret = 0;
	while(flow > 0){
		//ベルマンフォード方により、source-sink間最短経路を求める
		for(int i = 0; i < V; i++)dist[i] = BIG_NUM;
		dist[source] = 0;
		bool update = true;
		while(update){
			update = false;
			for(int node_id = 0; node_id < V; node_id++){
				if(dist[node_id] == BIG_NUM)continue;
				for(int i = 0; i < G[node_id].size(); i++){
					Edge &e = G[node_id][i];
					if(e.capacity > 0 && dist[e.to] > dist[node_id]+e.cost){
						dist[e.to] = dist[node_id]+e.cost; //node_idを経由した方が早い場合
						pre_node[e.to] = node_id;
						pre_edge[e.to] = i;
						update = true;
					}
				}
			}
		}

		if(dist[sink] == BIG_NUM){
			//これ以上流せない
			return -1;
		}

		//source-sink間最短路に沿って目いっぱい流す
		int tmp_flow = flow;
		for(int node_id = sink; node_id != source; node_id = pre_node[node_id]){
			tmp_flow = min(tmp_flow,G[pre_node[node_id]][pre_edge[node_id]].capacity);
		}

		flow -= tmp_flow;
		ret += tmp_flow*dist[sink];
		for(int node_id = sink; node_id != source; node_id = pre_node[node_id]){
			Edge &e = G[pre_node[node_id]][pre_edge[node_id]];
			e.capacity -= tmp_flow;
			G[node_id][e.rev_index].capacity += tmp_flow;
		}
	}
	return ret;
}

void func(){

	for(int i = 0; i < N; i++){
		scanf("%d %d",&student[i].x,&student[i].y);
	}

	for(int i = 0; i < M; i++){
		scanf("%d %d %d %d",&house[i].x,&house[i].y,&house[i].capacity,&house[i].fee);
	}

	int ans = BIG_NUM;
	vector<int> HOUSE;

	int left,right,m;
	int cap_sum,fee_sum,house_num;
	int tmp_min,result1,result2;
	int source,sink;

	for(int state = 1; state < POW[M]; state++){

		HOUSE.clear();

		cap_sum = 0,fee_sum = 0,house_num = 0;
		for(int loop = 0; loop < M; loop++){
			if(state & (1 << loop)){
				cap_sum += house[loop].capacity;
				fee_sum += house[loop].fee;
				HOUSE.push_back(loop);
				house_num++;
			}
		}

		if(cap_sum < N)continue; //そもそもN人収容できなければSKIP

		//Dの仮定値
		left = 0,right = 4000,m = (left+right)/2;
		tmp_min = BIG_NUM;

		source = 0,sink = N+house_num+1,V = N+house_num+2;

		while(left <= right){

			//D == m+1の時の金額を求める
			for(int i = 0; i < NUM; i++)G[i].clear();

			for(int i = 1; i <= N; i++){
				add_edge(source,i,1,0); //sourceから各生徒に辺を張る
			}

			for(int i = N+1; i <= N+house_num; i++){
				add_edge(i,sink,house[HOUSE[i-(N+1)]].capacity,0); //各会場からsinkへエッジを張る
			}

			for(int i = 1; i <= N; i++){ //各生徒から会場へ辺を張る
				for(int k = N+1; k <= N+house_num; k++){
					add_edge(i,k,1,max(0,abs(student[i-1].x-house[HOUSE[k-(N+1)]].x)
							+abs(student[i-1].y-house[HOUSE[k-(N+1)]].y)-(m+1)));
				}
			}



			result1 = min_cost_flow(source,sink,N);
			result1 += fee_sum + (m+1)*B*house_num; //会場使用料+シャトルバスの使用料を加算

			//D == mの時の金額を求める

			for(int i = 0; i < NUM; i++)G[i].clear();

			for(int i = 1; i <= N; i++){
				add_edge(source,i,1,0); //sourceから各生徒に辺を張る
			}

			for(int i = N+1; i <= N+house_num; i++){
				add_edge(i,sink,house[HOUSE[i-(N+1)]].capacity,0); //各会場からsinkへエッジを張る
			}

			for(int i = 1; i <= N; i++){ //各生徒から会場へ辺を張る
				for(int k = N+1; k <= N+house_num; k++){
					add_edge(i,k,1,max(0,abs(student[i-1].x-house[HOUSE[k-(N+1)]].x)
							+abs(student[i-1].y-house[HOUSE[k-(N+1)]].y)-m));
				}
			}

			result2 = min_cost_flow(source,sink,N);
			result2 += fee_sum + m*B*house_num;

			tmp_min = min(tmp_min,min(result1,result2));

			if(result1 >= result2){ //Dの仮定値が最適値以上
				right = m-1; //より小さく
			}else{
				left = m+1;
			}
			m = (left+right)/2;
		}

		ans = min(ans,tmp_min);
	}

	printf("%d\n",ans);

}

int main(){

	for(int i = 0; i < 6; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d %d",&N,&M,&B);
		if(N == 0 && M == 0 && B == 0)break;

		func();
	}

	return 0;
}



Measured memory_bytes: 3444