Nathan O. Davis is challenging a kind of shooter game. In this game, enemies emit laser beams from outside of the screen. A laser beam is a straight line with a certain thickness. Nathan moves a circular-shaped machine within the screen, in such a way it does not overlap a laser beam. As in many shooters, the machine is destroyed when the overlap happens.

Nathan is facing an uphill stage. Many enemies attack simultaneously in this stage, so eventually laser beams fill out almost all of the screen. Surprisingly, it is even possible he has no "safe area" on the screen. In other words, the machine cannot survive wherever it is located in some cases.

The world is as kind as it is cruel! There is a special item that helps the machine to survive any dangerous situation, even if it is exposed in a shower of laser beams, for some seconds. In addition, another straight line (called "a warning line") is drawn on the screen for a few seconds before a laser beam is emit along that line.

The only problem is that Nathan has a little slow reflexes. He often messes up the timing to use the special item. But he knows a good person who can write a program to make up his slow reflexes - it's you! So he asked you for help.

Your task is to write a program to make judgement whether he should use the item or not, for given warning lines and the radius of the machine.



Input

The input is a sequence of datasets. Each dataset corresponds to one situation with warning lines in the following format:

W H N R
x1,1 y1,1 x1,2 y1,2 t1
x2,1 y2,1 x2,2 y2,2 t2
...
xN,1 yN,1 xN,2 yN,2 tN


The first line of a dataset contains four integers W, H, N and R (2 < W ≤ 640, 2 < H ≤ 480, 0 ≤ N ≤ 100 and 0 < R < min{W, H}/2). The first two integers W and H indicate the width and height of the screen, respectively. The next integer N represents the number of laser beams.

The last integer R indicates the radius of the machine. It is guaranteed that the output would remain unchanged if the radius of the machine would become larger by 10-5 than R.

The following N lines describe the N warning lines. The (i+1)-th line of the dataset corresponds to the i-th warning line, which is represented as a straight line which passes through two given different coordinates (xi,1, yi,1 ) and (xi,2 , yi,2 ). The last integer ti indicates the thickness of the laser beam corresponding to the i-th warning line.

All given coordinates (x, y) on the screen are a pair of integers (0 ≤ x ≤ W, 0 ≤ y ≤ H). Note that, however, the machine is allowed to be located at non-integer coordinates during the play.

The input is terminated by a line with four zeros. This line should not be processed.

Output

For each case, print "Yes" in a line if there is a safe area, or print "No" otherwise.

Example

Input

100 100 1 1
50 0 50 100 50
640 480 1 1
0 0 640 480 100
0 0 0 0


Output

No
Yes
////////////////////////////////////////
///  tu3 pro-con template            ///
////////////////////////////////////////
#include <cassert>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <numeric>
#include <functional>
#include <vector>
#include <queue>
#include <string>
#include <complex>
#include <stack>
#include <set>
#include <map>
#include <list>
#include <unordered_map>
#include <unordered_set>
#include <bitset>
#include <regex>
using namespace std;

//// MACRO ////
#define countof(a) (sizeof(a)/sizeof(a[0]))

#define REP(i,n) for (int i = 0; i < (n); i++)
#define RREP(i,n) for (int i = (n)-1; i >= 0; i--)
#define FOR(i,s,n) for (int i = (s); i < (n); i++)
#define RFOR(i,s,n) for (int i = (n)-1; i >= (s); i--)
#define pos(c,i) c.being() + (i)
#define allof(c) c.begin(), c.end()
#define aallof(a) a, countof(a)
#define partof(c,i,n) c.begin() + (i), c.begin() + (i) + (n)
#define apartof(a,i,n) a + (i), a + (i) + (n)
#define long long long

#define EPS 1e-9
#define INF (1L << 30)
#define LINF (1LL << 60)

#define PREDICATE(t,a,exp) [&](const t & a) -> bool { return exp; }
#define COMPARISON_T(t) bool(*)(const t &, const t &)
#define COMPARISON(t,a,b,exp) [&](const t & a, const t & b) -> bool { return exp; }
#define CONVERTER(TSrc,t,TDest,exp) [&](const TSrc &t)->TDest { return exp; }

inline int sign(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }

//// i/o helper ////

struct _Reader { template <class T> _Reader operator ,(T &rhs) { cin >> rhs; return *this; } };
struct _Writer { bool f; _Writer() : f(false) { } template <class T> _Writer operator ,(const T &rhs) { cout << (f ? " " : "") << rhs; f = true; return *this; } };
#define READ(t,...) t __VA_ARGS__; _Reader(), __VA_ARGS__
#define WRITE(...) _Writer(), __VA_ARGS__; cout << endl

template <class T> struct vevector : public vector<vector<T>> { vevector(int n = 0, int m = 0, const T &initial = T()) : vector<vector<T>>(n, vector<T>(m, initial)) { } };
template <class T> struct vevevector : public vector<vevector<T>> { vevevector(int n = 0, int m = 0, int l = 0, const T &initial = T()) : vector<vevector<T>>(n, vevector<T>(m, l, initial)) { } };
template <class T> struct vevevevector : public vector<vevevector<T>> { vevevevector(int n = 0, int m = 0, int l = 0, int k = 0, const T &initial = T()) : vector<vevevector<T>>(n, vevevector<T>(m, l, k, initial)) { } };
template <class T> T read() { T t; cin >> t; return t; }
template <class T> vector<T> read(int n) { vector<T> v; REP(i, n) { v.push_back(read<T>()); } return v; }
template <class T> vevector<T> read(int n, int m) { vevector<T> v; REP(i, n) v.push_back(read<T>(m)); return v; }
template <class T> vevector<T> readjag() { return read<T>(read<int>()); }
template <class T> vevector<T> readjag(int n) { vevector<T> v; REP(i, n) v.push_back(readjag<T>()); return v; }

template <class T1, class T2> inline istream & operator >> (istream & in, pair<T1, T2> &p) { in >> p.first >> p.second; return in; }
template <class T1, class T2> inline ostream & operator << (ostream &out, pair<T1, T2> &p) { out << p.first << p.second; return out; }
template <class T> inline ostream & operator << (ostream &out, vector<T> &v)
{
	ostringstream ss;
	for (auto x : v) ss << x << ' ';
	auto s = ss.str();
	out << s.substr(0, s.length() - 1) << endl;
	return out;
}

/// 2次元
struct P2
{
	double x, y;
	P2(double x = 0, double y = 0) : x(x), y(y) { }
	P2(complex<double> c) : x(c.real()), y(c.imag()) { }
	P2 operator +() const { return *this; }
	P2 operator +(const P2 &_) const { return P2(x + _.x, y + _.y); }
	P2 operator -() const { return P2(-x, -y); }
	P2 operator -(const P2 &_) const { return *this + -_; }
	P2 operator *(double _) const { return P2(x*_, y*_); }
	P2 operator /(double _) const { return P2(x / _, y / _); }
	double dot(const P2 &_) const { return x*_.x + y*_.y; } // 内積
	double cross(const P2 &_) const { return x*_.y - y*_.x; } // 外積
	double sqlength() const { return x*x + y*y; } // 二乗長さ
	double length() const { return sqrt(sqlength()); } // 長さ
	P2 orthogonal() const { return P2(y, -x); }
	P2 direction() const { return *this / length(); } // 方向ベクトル
};
inline istream & operator>>(istream & in, P2 & p) { in >> p.x >> p.y; return in; }
inline ostream & operator<<(ostream & out, const P2 & p) { out << p.x << ' ' << p.y; return out; }
inline double abs(P2 p2) { return p2.length(); }
inline P2 orthogonal(P2 p) { return p.orthogonal(); }
inline complex<double> orthogonal(complex<double> c) { return  c * complex<double>(0, 1); }

// a,b から ちょうど d だけ離れた点。aとbを円周に持つ円の半径。
inline pair<P2, P2> get_same_distance_points(P2 a, P2 b, double d)
{
	assert(abs(a - b) <= 2 * d + EPS);
	auto v = (a + b) / 2.0 - a; // a から aとbの中点
	auto vl = abs(v);
	auto wl = sqrt(d*d - vl*vl); // 直行Vの大きさ
	auto w = orthogonal(v) * (wl / vl); // 直行V
	return make_pair(a + v + w, a + v - w);
}

// a から b に向かって、cが右手か左手か。
inline int clockwise(P2 a, P2 b, P2 c)
{
	const P2 u = b - a, v = c - a;
	if (u.cross(v) > EPS) { return 1; }
	if (u.cross(v) < -EPS) { return -1; }
	if (u.dot(v) < -EPS) { return -1; }
	if (u.sqlength() < v.sqlength() - EPS) { return 1; }
	return 0;
}

/// 直線
struct Line
{
	P2 p, d;
	explicit Line(P2 pos = P2(), P2 dir = P2()) : p(pos), d(dir) { }
	static Line FromPD(P2 pos, P2 dir) { return Line(pos, dir); }
	static Line From2Point(P2 a, P2 b) { return Line(a, b - a); }
};

/// 線分
struct LineSeg
{
	P2 p, d;
	explicit LineSeg(P2 pos = P2(), P2 dir = P2()) : p(pos), d(dir) { }
	static LineSeg FromPD(P2 pos, P2 dir) { return LineSeg(pos, dir); }
	static LineSeg From2Point(P2 a, P2 b) { return LineSeg(a, b - a); }
	operator Line() { return Line(p, d); }
};

inline P2 projective(P2 a, P2 b) { return a * (a.dot(b) / a.length()); }
inline P2 perpendicular_foot(P2 a, Line b) { Line l = Line(b.p - a, b.d); return a + l.p - projective(l.p, l.d); }
inline LineSeg projective(LineSeg a, Line b) { return LineSeg(perpendicular_foot(a.p, b), projective(a.d, b.d)); }

// 交点
inline P2 crossPoint(Line a, Line b) { return a.p + a.d * (b.d.cross(b.p - a.p) / b.d.cross(a.d)); }

// 包括判定
inline bool contains(LineSeg a, P2 p) { return abs(a.p - p) + abs(a.p + a.d - p) - abs(a.d) < EPS; }

// 交差判定
inline bool isCross(Line a, Line b) { return abs(a.d.cross(b.d)) > EPS; }
inline bool isCross(Line a, LineSeg b) { return sign(a.d.cross(b.p - a.p)) * sign(a.d.cross(b.p + b.d - a.d)) <= 0; }
inline bool isCross(LineSeg a, Line b) { return isCross(b, a); }
inline bool isCross(LineSeg a, LineSeg b)
{
	P2 ae = a.p + a.d, be = b.p + b.d;
	return clockwise(a.p, ae, b.p) * clockwise(a.p, ae, be) <= 0
		&& clockwise(b.p, be, a.p) * clockwise(b.p, be, ae) <= 0;
}

// 重なり判定
inline bool isOverlap(Line a, Line b) { return abs(a.d.cross(b.p - a.p)) < EPS; }
inline bool isOverlap(Line a, LineSeg b) { return isOverlap(a, Line(b.p, b.d)); }
inline bool isOverlap(LineSeg a, Line b) { return isOverlap(b, a); }
inline bool isOverlap(LineSeg a, LineSeg b)
{
	return contains(a, b.p) || contains(a, b.p + b.d)
		|| contains(b, a.p) || contains(b, a.p + a.d);
}

// 距離
inline double getDistance(P2 a, P2 b) { return (a - b).length(); }
inline double getDistance(P2 a, Line b) { return abs(b.d.cross(a - b.p) / b.d.length()); }
inline double getDistance(P2 a, LineSeg b) { return min(getDistance(perpendicular_foot(a, (Line)b), a), min(getDistance(b.p, a), getDistance(b.p + b.d, a))); }
inline double getDistance(Line a, P2 b) { return getDistance(b, a); }
inline double getDistance(Line a, Line b) { return isCross(a, b) ? 0 : getDistance(a, b.p); }
inline double getDistance(Line a, LineSeg b) { return isCross(a, b) ? 0 : min(getDistance(a, b.p), getDistance(a, b.p + b.d)); }
inline double getDistance(LineSeg a, P2 b) { return getDistance(b, a); }
inline double getDistance(LineSeg a, Line b) { return getDistance(b, a); }
inline double getDistance(LineSeg a, LineSeg b) { return isCross(a, b) ? 0 : min(min(getDistance(a.p, b.p), getDistance(a.p, b.p + b.d)), min(getDistance(a.p + a.d, b.p), getDistance(a.p + a.d, b.p + b.d))); }

// a から ta, bから tb だけ離れた点。ta=tb=r なら aとbに内接する円
inline pair<pair<P2, P2>, pair<P2, P2>> get_distance_points(Line a, double ta, Line b, double tb)
{
	assert(isCross(a, b));

	P2 va = a.d.orthogonal().direction() * ta;
	P2 vb = b.d.orthogonal().direction() * tb;
	return make_pair(
		make_pair(
			crossPoint(Line(a.p + va, a.d), Line(b.p + vb, b.d)),
			crossPoint(Line(a.p + va, a.d), Line(b.p - vb, b.d))
		), make_pair(
			crossPoint(Line(a.p - va, a.d), Line(b.p + vb, b.d)),
			crossPoint(Line(a.p - va, a.d), Line(b.p - vb, b.d))
		));
}

/// 円
struct Circle
{
	P2 c;
	double r;
	Circle() : c(), r() { }
	Circle(double x, double y, double r) : c(x, y), r(r) { }
	Circle(P2 c, double r) : c(c), r(r) { }
	bool IntersectWith(const Circle &rhs) const { return abs(c - rhs.c) - (r + rhs.r) < EPS; } // 接してても真。
	bool Contains(const P2 &p) const { return abs(p - c) - r < EPS; } // 接してても真。
};
inline istream & operator>>(istream & in, Circle & c) { in >> c.c >> c.r; return in; }

// 交差している2円の交点を求める。角度の小さい方から出る(右下方向が正なら時計回り)
inline pair<P2, P2> crossPoint(Circle A, Circle B)
{
	P2 v = B.c - A.c;
	P2 dir = v.direction(); // 他方の中心への方向
	double d = v.length(); // 他方の中心への距離
	double lh = (A.r*A.r + d*d - B.r*B.r) / (2 * d); // 垂線の足までの距離
	P2 h = A.c + dir * lh; // 垂線の足
	double lp = sqrt(A.r*A.r - lh*lh); // 垂線の足から交点までの距離
	P2 p = dir.orthogonal() * lp; // 垂線の足から交点へのベクトル
	return make_pair(h + p, h - p); // 交点の組。
}

/// 長方形
struct Rect
{
	P2 l, s;
	Rect() : l(), s() { }
	Rect(double x, double y, double w, double h) : l(x, y), s(w, h) { }
	Rect(P2 location, P2 size) : l(location), s(size) { }
	bool Contains(const P2 &p) const { return p.x - l.x > -EPS && p.y - l.y > -EPS && p.x - (l.x + s.x) < EPS && p.y - (l.y + s.y) < EPS; } // 接してても真。
};

//// start up ////
void solve();
int main()
{
	solve();
	return 0;
}


////////////////////
/// template end ///
////////////////////

void solve()
{
	int cases = INF;
	REP(_, cases)
	{
		READ(int, W, H, N, R);
		if (!W) { break; }

		struct Laser { Line line; double thick; };
		vector<Laser> beams;
		REP(i, N)
		{
			READ(double, x, y, z, w, t);
			beams.push_back({ Line::From2Point(P2(x, y), P2(z, w)), t });
		}
		
		// 画面端も死ぬ
		beams.push_back({ Line::From2Point(P2(0, 0), P2(W, 0)), 0 });
		beams.push_back({ Line::From2Point(P2(W, 0), P2(W, H)), 0 });
		beams.push_back({ Line::From2Point(P2(W, H), P2(0, H)), 0 });
		beams.push_back({ Line::From2Point(P2(0, H), P2(0, 0)), 0 });

		// 移動可能範囲
		Rect screen(R, R, W - R, H - R);
		
		bool ok = false;
		for (auto i : beams) for (auto j : beams)
		{
			//WRITE("i:", i.line.p, i.thick, "j:", j.line.p, j.thick);
			if (isCross(i.line, j.line))
			{
				// 点の候補
				auto cand = get_distance_points(i.line, i.thick + R, j.line, j.thick + R);
				P2 ps[] = { cand.first.first, cand.first.second, cand.second.first, cand.second.second, };

				for (auto p : ps)
				{
					
					// その位置は、移動可能でかつすべてのレーザーに当たらない？
					bool test = true;
					test &= screen.Contains(p);
					if (!test) continue;
					
					//WRITE(p);
					for (auto k : beams)
					{
						//WRITE("k:", k.line.p, k.thick, 
						//	"distance:", getDistance(k.line, p),
						//	"need:", (k.thick + R),
						//	"is ok? ", (getDistance(k.line, p) - (k.thick + R) > -EPS));
						test &= (getDistance(k.line, p) - (k.thick + R) > -EPS);
					}
					ok |= test;
					//WRITE(p, "ok? ", ok);
					if (ok) break;
				}
			}
			else
			{
				// 平行……。今回は画面端があるので、平行は考えなくてよい。
			}
		}

		WRITE(ok ? "Yes" : "No");
	}
}