#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const double EPS = 1e-8;

typedef complex<double> P;
namespace std{
	bool operator < (const P& a, const P& b){
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
double cross(const P& a, const P& b){
	return imag(conj(a)*b);
}
double dot(const P& a, const P& b){
	return real(conj(a)*b);
}

int ccw(P a, P b, P c){
	b -= a; c -= a;
	if(cross(b, c) > 0)   return +1;       // counter clockwise
	if(cross(b, c) < 0)   return -1;       // clockwise
	if(dot(b, c) < 0)     return +2;       // c--a--b on line
	if(norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0;
}

struct L : public vector<P>{
	L(){}
	L(const P &a, const P &b){
		push_back(a); push_back(b);
	}
};


bool intersectLL(const L &l, const L &m){
	return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS || // non-parallel
		abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;   // same line
}

bool intersectSS(const L &s, const L &t){
	return ccw(s[0], s[1], t[0])*ccw(s[0], s[1], t[1]) <= 0 &&
		ccw(t[0], t[1], s[0])*ccw(t[0], t[1], s[1]) <= 0;
}

P crosspointLL(const L &l, const L &m){
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if(abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

bool intersectSP(const L &s, const P &p){
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS; // triangle inequality
}

struct Edge{
	int from, to;
	double cost;
};

typedef vector<vector<Edge>> Graph;

Graph segment_arrangement(const std::vector<L> &ss, std::vector<P> &ps){
	for(int i = 0; i < (int)ss.size(); ++i){  // O(n^2)
		ps.push_back(ss[i][0]);
		ps.push_back(ss[i][1]);
		for(int j = i + 1; j < (int)ss.size(); ++j)
			if(intersectSS(ss[i], ss[j])) ps.push_back(crosspointLL(ss[i], ss[j]));
	}
	std::sort(ps.begin(), ps.end());
	ps.erase(std::unique(ps.begin(), ps.end()), ps.end());
	Graph g(ps.size());
	for(int i = 0; i < (int)ss.size(); ++i){
		std::vector<std::pair<double, int>> list;
		for(int j = 0; j < (int)ps.size(); ++j)
			if(intersectSP(ss[i], ps[j]))
				list.push_back(std::make_pair(norm(ss[i][0] - ps[j]), j));
		std::sort(list.begin(), list.end());
		for(int j = 0; j + 1 < (int)list.size(); ++j){
			int a = list[j].second, b = list[j + 1].second;
			double len = abs(ps[a] - ps[b]);
			g[a].push_back({ a, b, len });
			g[b].push_back({ b, a, len });
		}
	}
	return g;
}

typedef pair<double, int> State;
const double INF = 1e18;
bool sign[200];

int main(){
	cin.tie(0);
	ios::sync_with_stdio(false);
#ifdef LOCAL
	std::ifstream in("in");
	std::cin.rdbuf(in.rdbuf());
#endif

	int n;
	while(cin >> n, n){
		P start, goal;
		{
			int x, y;
			cin >> x >> y;
			start = P(x, y);
			cin >> x >> y;
			goal = P(x, y);
		}
		vector<L> ls(n);
		for(int i = 0; i < n; i++){
			int x1, y1, x2, y2;
			cin >> x1 >> y1 >> x2 >> y2;
			ls[i] = L(P(x1, y1), P(x2, y2));
		}
		vector<L> seg;
		for(int i = 0; i < n; i++){
			sign[i] = 0;
			int intersect[2] = { 0 };
			for(int j = 0; j < n; j++){
				if(i == j) continue;
				if(intersectSP(ls[j], ls[i][0])) intersect[0] = 1;
				if(intersectSP(ls[j], ls[i][1])) intersect[1] = 1;
			}
			assert(intersect[0] + intersect[1] >= 1);
			if(intersect[0] + intersect[1] == 1){
				sign[i] = 1;
				//cout << "sign " << i << endl;
			}
			else{
				seg.push_back(ls[i]);
			}
		}

		vector<P> ps;
		auto G = segment_arrangement(seg, ps);
		map<P, int> idxMap;
		for(int i = 0; i < ps.size(); i++){
			idxMap[ps[i]] = i;
		}

		set<pair<int, int>> NG;
		for(int i = 0; i < ps.size(); i++){
			for(auto e : G[i]){
				int u = i, v = e.to;
				P p0 = ps[u], p1 = ps[v];
				for(int j = 0; j < n; j++){
					if(!sign[j]) continue;
					int onIdx = -1;
					for(int k = 0; k < 2; k++){
						P sp = ls[j][k];
						if(ccw(p0, sp, p1) == -2 || ccw(p1, sp, p0) == -2){
							onIdx = k;
							break;
						}
					}
					if(onIdx == -1) continue;

					P sp0 = ls[j][onIdx], sp1 = ls[j][1 - onIdx];
					P v1 = p1 - p0, v2 = sp1 - sp0;
					int d = dot(v1, v2);
					if(d >= 0){
						NG.insert({ u, v });
						//cout << "NG " << (int)ps[u].real() << " " << (int)ps[u].imag() << " -> "
						//<< (int)ps[v].real() << " " << (int)ps[v].imag() << endl;
					}
				}
			}
		}

		vector<double> dist(ps.size(), INF);
		vector<int> pre(ps.size(), -1);
		priority_queue<State, vector<State>, greater<State>> q;
		q.push({ 0, idxMap[start] });
		dist[idxMap[start]] = 0;
		while(q.size()){
			int v = q.top().second;
			double d = q.top().first;
			q.pop();
			if(dist[v] < d) continue;
			for(auto e : G[v]){
				if(NG.count({ v,e.to })) continue;
				double nd = d + abs(ps[e.to] - ps[v]);
				if(dist[e.to] > nd){
					dist[e.to] = nd;
					pre[e.to] = v;
					q.push({ nd, e.to });
				}
			}
		}

		if(dist[idxMap[goal]] == INF){
			cout << -1 << endl;
			continue;
		}

		int cur = idxMap[goal];
		vector<int> path;
		while(true){
			path.push_back(cur);
			if(cur == idxMap[start]) break;
			cur = pre[cur];
		}
		reverse(path.begin(), path.end());
		for(auto pp : path){
			cout << (int)ps[pp].real() << " " << (int)ps[pp].imag() << endl;
		}
		cout << 0 << endl;
	}
}

Measured memory_bytes: 3344