#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <math.h>
#include <assert.h>
#include <vector>
#include <complex>
#include <map>
#include <queue>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
static const double EPS = 1e-9;
static const double PI = acos(-1.0);

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, s, n) for (int i = (s); i < (int)(n); i++)
#define FOREQ(i, s, n) for (int i = (s); i <= (int)(n); i++)
#define FORIT(it, c) for (__typeof((c).begin())it = (c).begin(); it != (c).end(); it++)
#define MEMSET(v, h) memset((v), h, sizeof(v))

typedef complex<double> Point;

namespace std {
  bool operator<(const Point &lhs, const Point &rhs) {
    if (fabs(lhs.real() - rhs.real()) > EPS) { return lhs.real() < rhs.real(); }
    if (fabs(lhs.imag() - rhs.imag()) > EPS) { return lhs.imag() < rhs.imag(); }
    return false;
  }
};

struct Line : public vector<Point> {
  bool sign;
  Line() {;}
  Line(Point a, Point b) : sign(false) { push_back(a); push_back(b); }
};

double cross(const Point &a, const Point &b) {
  return imag(conj(a) * b);
}
double dot(const Point &a, const Point &b) {
  return real(conj(a) * b);
}
int ccw(Point a, Point b, Point c) {
  b -= a; c -= a;
  if (cross(b, c) > 0) { return 1; }
  if (cross(b, c) < 0) { return -1; }
  if (dot(b, c) < 0) { return 2; }
  if (norm(b) < norm(c)) { return -2; }
  return 0;
}

bool intersectSS(const Line &s, const Line &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 Line &s, const Point &p) {
  return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

Point crosspointSS(const Line &l, const Line &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) {
    if (intersectSP(l, m[0])) { return m[0]; }
    if (intersectSP(l, m[1])) { return m[1]; }
    if (intersectSP(m, l[0])) { return l[0]; }
    if (intersectSP(m, l[1])) { return l[1]; }
    assert(false);
  }
  if (abs(A) < EPS) { assert(false); }
  return m[0] + B / A * (m[1] - m[0]);
}

struct Edge {
  int to;
  double cost;
  Edge() {;}
  Edge(int to, double cost) : to(to), cost(cost) {;}
  bool operator<(const Edge &rhs) const {
    return cost > rhs.cost;
  }
};

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;

int m;
Line lines[1100];
map<Point, int> vertex;
Point revVertex[1100];
set<int> adj[1100];

bool intersection[1100];

int parent[1100];
bool visit[1100];
double dist[1100];
char str[1000];

bool movable(const Point &a, const Point &b, const Line &l) {
  if (!l.sign) { return true; }
  Point c;
  if (l[0] == b) { c = l[1]; }
  if (l[1] == b) { c = l[0]; }
  Point vect1 = a - b;
  Point vect2 = c - b;
  if (dot(vect1, vect2) > EPS) { return true; }
  return false;
}

int main() {
  int n;
  while (scanf("%d", &n), n) {
    MEMSET(intersection, false);
    REP(i, 1100) { adj[i].clear(); dist[i] = 1e+10; }
    vertex.clear();
    m = 0;
    Point start, end;
    int sx, sy, gx, gy;
    scanf("%d %d %d %d", &sx, &sy, &gx, &gy);
    start = Point(sx, sy);
    end = Point(gx, gy);
    revVertex[0] = start;
    revVertex[1] = end;
    vertex[start] = m++;
    vertex[end] = m++;
    REP(i, n) {
      scanf("%d %d %d %d", &sx, &sy, &gx, &gy);
      lines[i] = Line(Point(sx, sy), Point(gx, gy));
    }
    REP(i, n) {
      bool exist[2] = { false, false };
      REP(j, n) {
        if (i == j) { continue; }
        REP(k, 2) {
          if (!intersectSP(lines[j], lines[i][k])) { continue; }
          exist[k] = true;
          if (!vertex.count(lines[i][k])) { 
            revVertex[m] = lines[i][k];
            vertex[lines[i][k]] = m++;
          }
          int index = vertex[lines[i][k]];
          adj[index].insert(i);
          adj[index].insert(j);
        }
      }
      if (!(exist[0] && exist[1])) { lines[i].sign = true; }
      if (intersectSP(lines[i], start)) { adj[0].insert(i); }
      if (intersectSP(lines[i], end)) { adj[1].insert(i); }
    }
    Graph g(m);
    REP(i, n) {
      if (lines[i].sign) { continue; }
      Point prevP = Point(-1, -1);
      int prev = -1;
      FORIT(it, vertex) {
        if (!intersectSP(lines[i], it->first)) { continue; }
        if (prev == -1) { prev = it->second; prevP = it->first; continue; }
        Point nextP = it->first;
        int next = it->second;
        double dist = abs(prevP - nextP);
        bool can = true;
        FORIT(it2, adj[next]) {
          if (!movable(prevP, nextP, lines[*it2])) { can = false; break; }
        }
        if (can) { g[prev].push_back(Edge(next, dist)); }
        can = true;
        FORIT(it2, adj[prev]) {
          if (!movable(nextP, prevP, lines[*it2])) { can = false; break; }
        }
        if (can) { g[next].push_back(Edge(prev, dist)); }
        prev = next;
        prevP = nextP;
      }
    }
    REP(i, n) {
      int cnt = 0;
      FORIT(it, adj[i]) {
        if (!lines[*it].sign) { cnt++; }
      }
      if (cnt > 1) { intersection[i] = true; }
    }
    priority_queue<Edge> que;
    MEMSET(parent, -1);
    MEMSET(visit, false);
    que.push(Edge(0, 0));
    vector<string> ans;
    ans.push_back("-1");
    while (!que.empty()) {
      int from = que.top().to;
      double cost = que.top().cost;
      que.pop();
      if (visit[from]) { continue; }
      visit[from] = true;
      if (from == 1) {
        ans[0] = "0";
        while (from != -1) {
          if (intersection[from]) {
            sprintf(str, "%.0f %.0f", revVertex[from].real(), revVertex[from].imag());
            ans.push_back(str);
          }
          from = parent[from];
        }
        break;
      }
      assert(from < (int)g.size());
      assert(from != -1);
      FORIT(it, g[from]) {
        int to = it->to;
        double ncost = cost + it->cost;
        if (visit[to] || ncost >= dist[to]) { continue; }
        parent[to] = from;
        dist[to] = ncost;
        que.push(Edge(to, ncost));
      }
    }
    reverse(ans.begin(), ans.end());
    FORIT(it, ans) {
      cout << *it << endl;
    }
  }
}

Measured memory_bytes: 0