#include <map>
#include <queue>
#include <algorithm>
#include <vector>
#include <complex>
#include <cmath>
#include <cassert>
using namespace std;

#define EPS 1e-10

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 dot(const P& a, const P& b) {
  return real(conj(a)*b);
}

double cross(const P& a, const P& b) {
  return imag(conj(a)*b);
}

double dist(const P& a, const P& b)
{
	return (a.real()-b.real())*(a.real()-b.real())+(a.imag()-b.imag())*(a.imag()-b.imag());
}

class L : public vector<P>
{
public:
	bool x[2];
	double length;
	
	L(const P &a, const P &b)
	{
		x[0]=0,x[1]=0;
		push_back(a); push_back(b);
	}
};

class Node
{
public:
	int px, py;
	vector<int> to;
	
	Node()
	:px(-1),py(-1)
	{}
};

class Pos
{
public:
	int x, y;
	Pos(int x, int y)
	:x(x),y(y)
	{}
};

class Trl
{
public:
	int x,y,p,px,py,r;
	double c;
	Trl(int p, int x, int y, int px, int py, double c, int r)
	:p(p),x(x),y(y),c(c),px(px),py(py),r(r)
	{}
	
	bool operator<(const Trl& a) const
	{
		if(c!=a.c) return c>a.c;
		return r<a.r;

	}
};

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;
}

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;
}
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
}

P crosspoint(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 P(-1,-1); // same line
  if (abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
  return m[0] + B / A * (m[1] - m[0]);
}

int access(const L& p, const L& s)
{
	double Dac,Dad,Dbc,Dbd,pa,pb;
	
	bool xp=intersectSP(p,s[0]);
	Dac = dist(p[0],s[xp]);
	Dad = dist(p[0],s[!xp]);
	Dbc = dist(p[1],s[xp]);
	Dbd = dist(p[1],s[!xp]);
	
	pa=Dac-Dbc;
	pb=Dad-Dbd;
	
	if(pa-pb < EPS && pb-pa < EPS) return 0; //both cant access
	if(pa-pb > EPS) return -1; // a-b
	return 1;
}

int main()
{
	int sx,sy,gx,gy,N;
	while(scanf("%d", &N), N)
	{
		int cnt=0;
		Node node[500];
		vector<L> Lines;
		vector<int> graph,sign;
		map<P, int> pt;
		scanf("%d%d%d%d",&sx,&sy,&gx,&gy);
		
		while(N--)
		{
			int x1,x2,y1,y2;
			scanf("%d%d%d%d", &x1,&y1,&x2,&y2);
			Lines.push_back(L(P(x1,y1),P(x2,y2)));
			pt.insert(make_pair<P,int>(P(x1,y1), cnt));
			cnt++;
			pt.insert(make_pair<P,int>(P(x2,y2), cnt));
			cnt++;
		}
		
		for(int i=0; i<Lines.size(); i++)
		{
			Lines[i].length=sqrt(dist(Lines[i][0],Lines[i][1]));
			
			bool x[2]={0};
			for(int j=0; j<Lines.size(); j++)
			{
				if(i==j) continue;
				for(int k=0; k<2; k++)
				{
					if(intersectSP(Lines[j], Lines[i][k]))
					{
						x[k]=1;
					}
				}
			}

			if(x[0]&&x[1]) 
			{
				graph.push_back(i);
				
			}
			else sign.push_back(i);
		}
		
		int pn=0;
		while(1)
		{
			int tsize=graph.size();
			for(int i=pn; i<tsize; i++)
			for(int j=0; j<tsize; j++)
			{
				if(i<=j) continue;
				if(intersectSS(Lines[graph[i]], Lines[graph[j]]))
				{
					P xp=crosspoint(Lines[graph[i]], Lines[graph[j]]);
					if(xp.real()==-1) continue;
					
					bool f1=false, f2=false;
					for(int k=0; k<2; k++)
					{
						if(xp==Lines[graph[i]][k]) f1=true;
						if(xp==Lines[graph[j]][k]) f2=true;
					}
					
					if(f1&&f2) continue; // cut error line
					
					pt.insert(make_pair<P,int>(xp, cnt));
					cnt++;
					
					int gr=(f1?graph[j]:graph[i]);
					
					for(int k=0; k<2; k++)
					{
						Lines.push_back(L(Lines[gr][k], xp));
						Lines[Lines.size()-1].length=sqrt(dist(Lines[Lines.size()-1][0],Lines[Lines.size()-1][1]));
						graph.push_back(Lines.size()-1);
					}
				}
			}
			pn=tsize;
			if(tsize==graph.size()) break;
		}
		
		
		for(int i=0; i<graph.size(); i++)
		for(int j=0; j<sign.size(); j++)
		{
			int gr=graph[i], si=sign[j];
			if(intersectSS(Lines[gr], Lines[si]))
			{
				int a = access(Lines[gr], Lines[si]);
				if(a==0||a==-1) Lines[gr].x[0]=1;
				if(a==0||a== 1) Lines[gr].x[1]=1;
			}
		}
		
		map<P,int>::iterator it;
		
		for(int i=0; i<graph.size(); i++)
		for(int j=0; j<2; j++)
		{
			int gr=graph[i];
			if(Lines[gr].x[j]) continue;
			it=pt.find(Lines[gr][j]);
			node[it->second].to.push_back(i);
		
		}
		bool g=false;
		it=pt.find(P(sx,sy));
		priority_queue<Trl> q;
		q.push(Trl(it->second,sx,sy,-2,-2,0,0));
		
		while(!q.empty())
		{
			Trl t=q.top(); q.pop();
			if(node[t.p].px!=-1) continue;
			node[t.p].px=t.px; node[t.p].py=t.py;
			
			if(t.x==gx&&t.y==gy)
			{
				g=true;
				vector<Pos> v;
				int tp=t.p;
				while(node[tp].px!=-2)
				{
					it=pt.find(P(node[tp].px, node[tp].py));
					v.push_back(Pos(node[tp].px, node[tp].py));
					tp=it->second;
				}
				
				reverse(v.begin(), v.end());
				for(int i=0; i<v.size(); i++)
				{
					printf("%d %d\n", v[i].x, v[i].y);
				}
				printf("%d %d\n", t.x, t.y);
				puts("0");
				
				break;
			}
			
			for(int i=0; i<node[t.p].to.size(); i++)
			{
				int next=node[t.p].to[i];
				next=graph[next];
				P np;
				if(Lines[next][0].real()==t.x&&Lines[next][0].imag()==t.y)
				{
					np=Lines[next][1];
				}
				else
				{
					np=Lines[next][0];
				}
				
				it=pt.find(np);
				if(node[it->second].px!=-1) continue;
				
				q.push(Trl(it->second,np.real(), np.imag(), t.x, t.y, t.c+Lines[next].length,t.r+1));
			}
		}
		
		if(!g) puts("-1");
	}
}

Measured memory_bytes: 896