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


#define NUM 250

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
		x_int = y_int = 0;
	}

	Point(){
		x = y = 0.0;
		x_int = y_int = 0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	double x,y;
	int x_int,y_int;
};
typedef Point Vector;

struct Line{
public:
	Point p[2];
	Line(Point p1,Point p2){
		p[0] = p1;
		p[1] = p2;
	}
	Line(){
	}
};

struct Info{
	Info(Point arg_cross_point,int arg_index){

		cross_point.x = arg_cross_point.x;
		cross_point.y = arg_cross_point.y;
		index = arg_index;
	}
	bool operator<(const struct Info &arg) const{
		return cross_point < arg.cross_point;
	}
	bool operator==(const struct Info &arg) const{
		return cross_point == arg.cross_point && index == arg.index;
	}

	Point cross_point;
	int index;
};

struct State{
	void set(int arg_node_id,double arg_sum_dist,vector<int> arg_LOG){

		node_id = arg_node_id;
		sum_dist = arg_sum_dist;
		LOG = arg_LOG;
	}
	bool operator<(const struct State &arg) const{

		return sum_dist > arg.sum_dist; //総コストの昇順(PQ)
	}

	int node_id;
	double sum_dist;
	vector<int> LOG;
};

struct Edge{
	Edge(int arg_to, double arg_cost){

		to = arg_to;
		cost = arg_cost;
	}
	int to;
	double cost;
};

int N;
int num_nodes;
Point start,goal;
vector<Point> NODES;
vector<Info> on_segment[NUM];
bool can_go[NUM][NUM];
double min_dist[NUM];
Line LINE[NUM];
vector<Edge> G[NUM];
vector<Line> SIGNAL;
map<pair<int,int>,int> MAP;
map<pair<int,int>,bool> SIG_POINT;


double calc_dist(Line a){
	return sqrt((a.p[0].x-a.p[1].x)*(a.p[0].x-a.p[1].x)+(a.p[0].y-a.p[1].y)*(a.p[0].y-a.p[1].y));
}

double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}

int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}

bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(A.p[0] == B.p[0] || A.p[0] == B.p[1]){

		return A.p[0];
	}else if(A.p[1] == B.p[0] || A.p[1] == B.p[1]){

		return A.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}

bool calc_arg(Point A,Point B, Point C){

	double a = calc_dist(B,C);
	double b = calc_dist(C,A);
	double c = calc_dist(A,B);

	double cos_theta = (b*b+c*c-a*a)/(2*b*c);
	return cos_theta > EPS;
}

bool check_SIGNAL(Point from,Point to){

	Line tmp_line = Line(from,to);

	for(int i = 0; i < SIGNAL.size(); i++){

		if(!is_Cross(tmp_line,SIGNAL[i]))continue;
		Point A = calc_Cross_Point(tmp_line,SIGNAL[i]);
		Point B = from;
		if(A == B)continue;

		Point C;
		if(A == SIGNAL[i].p[0]){

			C = SIGNAL[i].p[1];
		}else{

			C = SIGNAL[i].p[0];
		}

		if(!calc_arg(A,B,C))return false;
	}

	return true;
}

void solve(){

	NODES.clear();
	SIGNAL.clear();
	MAP.clear();
	SIG_POINT.clear();

	for(int i = 0; i < NUM; i++){

		G[i].clear();
		on_segment[i].clear();
	}

	scanf("%lf %lf",&start.x,&start.y);
	scanf("%lf %lf",&goal.x,&goal.y);

	for(int i = 0; i < N; i++){

		scanf("%d %d %d %d",&LINE[i].p[0].x_int,&LINE[i].p[0].y_int,&LINE[i].p[1].x_int,&LINE[i].p[1].y_int);

		LINE[i].p[0].x = LINE[i].p[0].x_int;
		LINE[i].p[0].y = LINE[i].p[0].y_int;

		LINE[i].p[1].x = LINE[i].p[1].x_int;
		LINE[i].p[1].y = LINE[i].p[1].y_int;
	}

	num_nodes = 0;

	vector<Point> info;

	int start_index,goal_index;


	for(int i = 0; i < N; i++){

		info.clear();

		for(int k = 0; k < N; k++){
			if(k == i)continue;

			if(is_Cross(LINE[i],LINE[k])){
				info.push_back(Point(calc_Cross_Point(LINE[i],LINE[k])));
			}
		}

		sort(info.begin(),info.end());
		info.erase(unique(info.begin(),info.end()),info.end());

		if(info.size() != 1){ //道になる辺

			for(int k = 0; k < info.size(); k++){

				Point point = info[k];
				for(int a = 0; a < N; a++){
					if(point == LINE[a].p[0]){

						point.x_int = LINE[a].p[0].x_int;
						point.y_int = LINE[a].p[0].y_int;
						break;
					}else if(point == LINE[a].p[1]){
						point.x_int = LINE[a].p[1].x_int;
						point.y_int = LINE[a].p[1].y_int;
						break;
					}
				}

				auto at = MAP.find(make_pair(point.x_int,point.y_int));


				if(at == MAP.end()){ //新しいノード


					NODES.push_back(point);
					int tmp_index = num_nodes++;
					MAP[make_pair(point.x_int,point.y_int)] = tmp_index;

					on_segment[i].push_back(Info(info[k],tmp_index));//辺ごとに、辺の上にある交点とそのインデックスを保存

					if(info[k] == start){
						start_index = tmp_index;

					}else if(info[k] == goal){

						goal_index = tmp_index;
					}

				}else{

					on_segment[i].push_back(Info(info[k],MAP[make_pair(point.x_int,point.y_int)]));//辺ごとに、辺の上にある交点とそのインデックスを保存
				}
			}

		}else{ //シグナルになる辺

			if(LINE[i].p[0] == info[0]){

				SIG_POINT[make_pair(LINE[i].p[0].x_int,LINE[i].p[0].y_int)] = true;

			}else{

				SIG_POINT[make_pair(LINE[i].p[1].x_int,LINE[i].p[1].y_int)] = true;
			}

			SIGNAL.push_back(LINE[i]);
		}
	}

	//★★辺を分割し、エッジを作成する★★
	for(int i = 0; i < N; i++){

		if(on_segment[i].size() == 0)continue;

		sort(on_segment[i].begin(),on_segment[i].end());
		on_segment[i].erase(unique(on_segment[i].begin(),on_segment[i].end()),on_segment[i].end());

		for(int k = 0; k < on_segment[i].size()-1; k++){

			int from = on_segment[i][k].index;
			int to = on_segment[i][k+1].index;

			double tmp_dist = calc_dist(on_segment[i][k].cross_point,on_segment[i][k+1].cross_point);

			G[from].push_back(Edge(to,tmp_dist));
			G[to].push_back(Edge(from,tmp_dist));
		}
	}

	for(int i = 0; i < num_nodes; i++){

		min_dist[i] = BIG_NUM;
	}
	min_dist[start_index] = 0;

	priority_queue<State> Q;

	State first_state;
	vector<int> first_LOG;
	first_LOG.push_back(start_index);

	first_state.set(start_index,0,first_LOG);
	Q.push(first_state);

	int next_node;
	double next_cost;

	while(!Q.empty()){

		if(Q.top().sum_dist > min_dist[Q.top().node_id]){

			Q.pop();
		}else if(Q.top().node_id == goal_index){

			for(int i = 0; i < Q.top().LOG.size(); i++){

				printf("%d %d\n",NODES[Q.top().LOG[i]].x_int,NODES[Q.top().LOG[i]].y_int);
			}
			printf("0\n");

			return;

		}else{

			for(int i = 0; i < G[Q.top().node_id].size(); i++){

				next_node = G[Q.top().node_id][i].to;
				if(!check_SIGNAL(NODES[Q.top().node_id],NODES[next_node])){

					continue; //通れないならSKIP
				}

				State next_state;

				next_cost = Q.top().sum_dist+G[Q.top().node_id][i].cost;
				vector<int> next_LOG = Q.top().LOG;

				auto at = SIG_POINT.find(make_pair(NODES[next_node].x_int,NODES[next_node].y_int));

				//シグナルと接続するノードでなければ記録
				if(at == SIG_POINT.end()){
					next_LOG.push_back(next_node);
				}

				next_state.set(next_node,next_cost,next_LOG);

				if(min_dist[next_node] > next_cost){

					min_dist[next_node] = next_cost;
					Q.push(next_state);
				}
			}

			Q.pop();
		}
	}

	printf("-1\n");
}


int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		solve();
	}

	return 0;
}



Measured memory_bytes: 3360