Development of Small Flying Robots

<image>

You are developing small flying robots in your laboratory.

The laboratory is a box-shaped building with K levels, each numbered 1 through K from bottom to top. The floors of all levels are square-shaped with their edges precisely aligned east-west and north-south. Each floor is divided into R × R cells. We denote the cell on the z-th level in the x-th column from the west and the y-th row from the south as (x, y, z). (Here, x and y are one-based.) For each x, y, and z (z > 1), the cell (x, y, z) is located immediately above the cell (x, y, z − 1).

There are N robots flying in the laboratory, each numbered from 1 through N. Initially, the i-th robot is located at the cell (xi, yi, zi).

By your effort so far, you successfully implemented the feature to move each flying robot to any place that you planned. As the next step, you want to implement a new feature that gathers all the robots in some single cell with the lowest energy consumption, based on their current locations and the surrounding environment.

Floors of the level two and above have several holes. Holes are rectangular and their edges align with edges of the cells on the floors. There are M holes in the laboratory building, each numbered 1 through M. The j-th hole can be described by five integers u1j, v1j, u2j, v2j, and wj. The j-th hole extends over the cells (x, y, wj) where u1j ≤ x ≤ u2j and v1j ≤ y ≤ v2j.

Possible movements of robots and energy consumption involved are as follows.

* You can move a robot from one cell to an adjacent cell, toward one of north, south, east, or west. The robot consumes its energy by 1 for this move.
* If there is a hole to go through immediately above, you can move the robot upward by a single level. The robot consumes its energy by 100 for this move.



The robots never fall down even if there is a hole below. Note that you can move two or more robots to the same cell.

Now, you want to gather all the flying robots at a single cell in the K-th level where there is no hole on the floor, with the least energy consumption. Compute and output the minimum total energy required by the robots.

Input

The input consists of at most 32 datasets, each in the following format. Every value in the input is an integer.

> N
>  M K R
>  x1 y1 z1
>  ...
>  xN yN zN
>  u11 v11 u21 v21 w1
>  ...
>  u1M v1M u2M v2M wM
>

N is the number of robots in the laboratory (1 ≤ N ≤ 100). M is the number of holes (1 ≤ M ≤ 50), K is the number of levels (2 ≤ K ≤ 10), and R is the number of cells in one row and also one column on a single floor (3 ≤ R ≤ 1,000,000).

For each i, integers xi, yi, and zi represent the cell that the i-th robot initially located at (1 ≤ xi ≤ R, 1 ≤ yi ≤ R, 1 ≤ zi ≤ K). Further, for each j, integers u1j, v1j, u2j, v2j, and wj describe the position and the extent of the j-th hole (1 ≤ u1j ≤ u2j ≤ R, 1 ≤ v1j ≤ v2j ≤ R, 2 ≤ wj ≤ K).

The following are guaranteed.

* In each level higher than or equal to two, there exists at least one hole.
* In each level, there exists at least one cell not belonging to any holes.
* No two holes overlap. That is, each cell belongs to at most one hole.



Two or more robots can initially be located at the same cell. Also note that two neighboring cells may belong to different holes.

The end of the input is indicated by a line with a single zero.

Output

For each dataset, print the minimum total energy consumption in a single line.

Sample Input


2
1 2 8
1 1 1
8 8 1
3 3 3 3 2
3
3 2 3
1 1 2
1 1 2
1 1 2
1 1 1 1 2
1 2 1 2 2
2 1 2 1 2
2
2 3 100
100 50 1
1 50 3
100 1 100 100 3
1 1 1 100 2
5
6 7 60
11 11 1
11 51 1
51 11 1
51 51 1
31 31 1
11 11 51 51 2
11 11 51 51 3
11 11 51 51 4
11 11 51 51 5
18 1 54 42 6
1 43 59 60 7
5
6 4 9
5 5 3
1 1 1
1 9 1
9 1 1
9 9 1
3 3 7 7 4
4 4 6 6 2
1 1 2 2 3
1 8 2 9 3
8 1 9 2 3
8 8 9 9 3
5
10 5 50
3 40 1
29 13 2
39 28 1
50 50 1
25 30 5
3 5 10 10 2
11 11 14 14 2
15 15 20 23 2
40 40 41 50 2
1 49 3 50 2
30 30 50 50 3
1 1 10 10 4
1 30 1 50 5
20 30 20 50 5
40 30 40 50 5
15
2 2 1000000
514898 704203 1
743530 769450 1
202298 424059 1
803485 898125 1
271735 512227 1
442644 980009 1
444735 799591 1
474132 623298 1
67459 184056 1
467347 302466 1
477265 160425 2
425470 102631 2
547058 210758 2
52246 779950 2
291896 907904 2
480318 350180 768473 486661 2
776214 135749 872708 799857 2
0


Output for the Sample Input


216
6
497
3181
1365
1930
6485356






Example

Input

2
1 2 8
1 1 1
8 8 1
3 3 3 3 2
3
3 2 3
1 1 2
1 1 2
1 1 2
1 1 1 1 2
1 2 1 2 2
2 1 2 1 2
2
2 3 100
100 50 1
1 50 3
100 1 100 100 3
1 1 1 100 2
5
6 7 60
11 11 1
11 51 1
51 11 1
51 51 1
31 31 1
11 11 51 51 2
11 11 51 51 3
11 11 51 51 4
11 11 51 51 5
18 1 54 42 6
1 43 59 60 7
5
6 4 9
5 5 3
1 1 1
1 9 1
9 1 1
9 9 1
3 3 7 7 4
4 4 6 6 2
1 1 2 2 3
1 8 2 9 3
8 1 9 2 3
8 8 9 9 3
5
10 5 50
3 40 1
29 13 2
39 28 1
50 50 1
25 30 5
3 5 10 10 2
11 11 14 14 2
15 15 20 23 2
40 40 41 50 2
1 49 3 50 2
30 30 50 50 3
1 1 10 10 4
1 30 1 50 5
20 30 20 50 5
40 30 40 50 5
15
2 2 1000000
514898 704203 1
743530 769450 1
202298 424059 1
803485 898125 1
271735 512227 1
442644 980009 1
444735 799591 1
474132 623298 1
67459 184056 1
467347 302466 1
477265 160425 2
425470 102631 2
547058 210758 2
52246 779950 2
291896 907904 2
480318 350180 768473 486661 2
776214 135749 872708 799857 2
0


Output

216
6
497
3181
1365
1930
6485356
#include <bits/stdc++.h>
using namespace std;
const int INF = INT_MAX;

template <class T>
pair<vector<T>, map<T, int> > compress(vector<T>& a) {
	vector<T> v;
	for(int i = 0; i < a.size(); i++) v.push_back(a[i]);
	sort(v.begin(), v.end());
	v.erase(unique(v.begin(), v.end()), v.end());
	map<T, int> m;
	for(int i = 0; i < v.size(); i++) m[v[i]] = i;
	return { v, m };
}

struct edge {
	int x, y, z;
	int cost;
};

struct S {
	int x, y, z;
	int cost;

	bool operator <(const S& x) const{
		return cost > x.cost;
	}
};

using P = pair<int, int>;
vector<edge> G[300][300][11];
int dist[300][300][11];
int sum[300][300];

int dx[4] = { 1, 0, -1, 0 }, dy[4] = { 0, 1, 0, -1 };

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N, M, K, R;
	vector<int> X(100), Y(100), Z(100), xl(50), xr(50), yt(50), yb(50), h(50);
	while(cin >> N, N) {
		cin >> M >> K >> R;

		vector<int> xs, ys;
		for(int i = 0; i < N; i++) {
			cin >> X[i] >> Y[i] >> Z[i];
			xs.push_back(X[i]);
			ys.push_back(Y[i]);
		}
		for(int i = 0; i < M; i++) {
			cin >> xl[i] >> yt[i] >> xr[i] >> yb[i] >> h[i];
			xs.push_back(xl[i]);
			xs.push_back(xr[i]);
			ys.push_back(yt[i]);
			ys.push_back(yb[i]);
			if(h[i] == K) {
				if(xl[i] - 1 >= 1) xs.push_back(xl[i] - 1);
				if(xr[i] + 1 <= R) xs.push_back(xr[i] + 1);
				if(yt[i] - 1 >= 1) ys.push_back(yt[i] - 1);
				if(yb[i] + 1 <= R) ys.push_back(yb[i] + 1);
			}
		}

		auto zipX = compress(xs);
		auto zipY = compress(ys);

		int XN = zipX.first.size();
		int YN = zipY.first.size();

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					G[i][j][k].clear();
				}
			}
		}

		for(int k = 1; k <= K; k++) {
			for(int i = 0; i < XN; i++) {
				for(int j = 0; j < YN; j++) {
					int cx = zipX.first[i];
					int cy = zipY.first[j];
					if(k == K) {
						for(int l = 0; l < 4; l++) {
							if(i + dx[l] < 0 || XN <= i + dx[l]) continue;
							if(j + dy[l] < 0 || YN <= j + dy[l]) continue;
							int nx = zipX.first[i + dx[l]];
							int ny = zipY.first[j + dy[l]];
							int cost = abs(cx - nx) + abs(cy - ny);
							G[i][j][k].push_back({ i + dx[l], j + dy[l], k, cost });
						}
					}
					else {
						for(int m = 0; m < M; m++) {
							if(k + 1 != h[m]) continue;
							int cost = INF;
							int ii = 0, jj = 0;
							int li = zipX.second[xl[m]];
							int ri = zipX.second[xr[m]];
							int tj = zipY.second[yt[m]];
							int bj = zipY.second[yb[m]];
							if(li <= i && i <= ri && tj <= j && j <= bj) {
								if(cost > 100) {
									cost = 100;
									ii = i, jj = j;
								}
							}
							else if(li <= i && i <= ri) {
								if(cost > 100 + abs(cy - yt[m])){
									cost = 100 + abs(cy - yt[m]);
									ii = i, jj = tj;
								}
								if(cost > 100 + abs(cy - yb[m])) {
									cost = 100 + abs(cy - yb[m]);
									ii = i, jj = bj;
								}
							}
							else if(tj <= j && j <= bj) {
								if(cost > 100 + abs(cx - xl[m])){
									cost = 100 + abs(cx - xl[m]);
									ii = li, jj = j;
								}
								if(cost > 100 + abs(cx - xr[m])) {
									cost = 100 + abs(cx - xr[m]);
									ii = ri, jj = j;
								}
							}
							else {
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yt[m]);
									ii = li, jj = tj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yt[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yt[m]);
									ii = ri, jj = tj;
								}
								if(cost > 100 + abs(cx - xl[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xl[m]) + abs(cy - yb[m]);
									ii = li, jj = bj;
								}
								if(cost > 100 + abs(cx - xr[m]) + abs(cy - yb[m])){
									cost = 100 + abs(cx - xr[m]) + abs(cy - yb[m]);
									ii = ri, jj = bj;
								}
							}
							G[i][j][k].push_back({ ii, jj, k + 1, cost });
						}
					}
				}
			}
		}

		vector<P> goal;
		for(int i = 0; i < XN; i++) {
			for(int j = 0; j < YN; j++) {
				int cx = zipX.first[i];
				int cy = zipY.first[j];
				bool ok = true;
				for(int m = 0; m < M; m++) {
					if(K == h[m] && xl[m] <= cx && cx <= xr[m] && yt[m] <= cy && cy <= yb[m]) {
						ok = false;
						break;
					}
				}
				if(ok) goal.push_back({ i, j });
			}
		}

		memset(sum, 0, sizeof sum);
		for(int n = 0; n < N; n++) {
			fill((int*)begin(dist), (int*)end(dist), INF);
			dist[zipX.second[X[n]]][zipY.second[Y[n]]][Z[n]] = 0;
			priority_queue<S> q;
			q.push({ zipX.second[X[n]],zipY.second[Y[n]], Z[n], 0 });
			while(q.size()) {
				S s = q.top();
				q.pop();
				if(dist[s.x][s.y][s.z] < s.cost) continue;
				for(auto& e : G[s.x][s.y][s.z]) {
					int ncost = s.cost + e.cost;
					if(dist[e.x][e.y][e.z] > ncost){
						dist[e.x][e.y][e.z] = ncost;
						q.push({ e.x, e.y, e.z, ncost });
					}
				}
			}
			for(auto& g : goal) {
				sum[g.first][g.second] += dist[g.first][g.second][K];
			}
		}
		int ans = INF;
		for(auto& g : goal) {
			ans = min(ans, sum[g.first][g.second]);
		}
		cout << ans << endl;
	}
}