#include <bits/stdc++.h>

using namespace std;

#define whole(xs) (xs).begin(),(xs).end()
#define uniq(xs) ((xs).erase(unique((xs).begin(), (xs).end()), (xs).end()))

namespace {

    template<class T> ostream& operator<<(ostream& os, const vector<T>& vs) {
        if (vs.empty()) return os << "[]";
        os << "[" << vs[0];
        for (int i = 1; i < vs.size(); i++) os << " " << vs[i];
        return os << "]";
    }

    const double EPS = 1e-8;

    bool EQ(double a, double b) { return abs(a - b) < EPS; }

    struct Point {
        double x, y;
        Point() {}
        Point(double x, double y) : x(x), y(y) {}
        Point operator+(const Point& p) const { return Point(x + p.x, y + p.y); }
        Point operator-(const Point& p) const { return Point(x - p.x, y - p.y); }
        Point operator*(double k) const { return Point(k * x, k * y); }
        Point operator/(double k) const { return Point(x / k, y / k); }
        Point operator-() const { return Point(-x, -y); }
    };
    double dot(const Point& a, const Point& b) { return a.x * b.x + a.y * b.y; }
    double cross(const Point& a, const Point& b) { return a.x * b.y - a.y * b.x; }
    double norm(const Point& a) { return sqrt(dot(a, a)); }
    Point rot90(const Point& p) { return Point(-p.y, p.x); } // 反時計回りに90度回転 
    double angle(const Point& a) { return atan2(a.y, a.x); } // x軸を反時計回りに何ラジアン回転させれば点aに乗るか
    ostream& operator<<(ostream& os, const Point& p) { return os << "(" << p.x << "," << p.y << ")"; }
    istream& operator>>(istream& is, Point& p) { return is >> p.x >> p.y; }
    bool operator==(const Point& a, const Point& b) { return EQ(a.x, b.x) && EQ(a.y, b.y); }
    bool operator!=(const Point& a, const Point& b) { return not(EQ(a.x, b.x) && EQ(a.y, b.y)); }
    bool operator<(const Point& a, const Point& b) { return EQ(a.x, b.x) ? a.y < b.y : a.x < b.x; }
    double distance(const Point& a, const Point& b) {
        double dx = a.x - b.x, dy = a.y - b.y;
        return sqrt(dx * dx + dy * dy);
    }

    int ccw(Point a, Point b, Point c){
        b = b - a; c = c - a;
        if (cross(b, c) > EPS) return +1;      // a,b,cの順に反時計周り
        if (cross(b, c) < -EPS) return -1;     // a,b,cの順に時計周り
        if (dot(b, c) < 0) return +2;          // c--a--b 直線
        if (norm(b) < norm(c)) return -2;      // a--b--c 直線
        return 0;                              // a--c--b 直線
    }

    struct Line {
        Point a, b;
        Line() {}
        Line(const Point& a, const Point& b) : a(a), b(b) {}
    };
    bool contains(const Line& l, const Point& p) { return ccw(l.a, l.b, p) % 2 == 0; }
    bool parallel(const Line& s, const Line& t) { return abs(cross(s.b - s.a, t.b - t.a)) < EPS; }
    bool orthogonal(const Line& s, const Line& t) { return abs(dot(s.b - s.a, t.b - t.a)) < EPS; }
    bool equals(const Line& s, const Line& t) { return parallel(s, t) && contains(s, t.a); }
    istream& operator>>(istream& is, Line& l) { return is >> l.a >> l.b; }
    ostream& operator<<(ostream& os, const Line& l) { return os << "Line(" << l.a << "," << l.b << ")"; }

    Point crosspoint(const Line& s, const Line& t) {
        double d = cross(t.b - t.a, s.b - s.a);
        assert(abs(d) >= EPS);
        return s.a + (s.b - s.a) * cross(t.b - t.a, t.b - s.a) / d;
    }

    struct Segment : Line {
        Segment() {}
        Segment(const Point& a, const Point& b) : Line(a, b) {}
    };
    bool intersects(const Segment& s, const Segment& t) {
        return ccw(s.a, s.b, t.a) * ccw(s.a, s.b, t.b) <= 0 && ccw(t.a, t.b, s.a) * ccw(t.a, t.b, s.b) <= 0;
    }
    Point crosspoint(const Segment& s, const Segment& t) {
        assert(intersects(s, t));
        if (equals(s, t)) {
            if (s.a == t.a) return s.a;
            if (s.b == t.a) return s.b;
            if (s.a == t.b) return s.a;
            if (s.b == t.b) return t.b;
            assert(false);
        } else {
            return crosspoint((Line)s, (Line)t);
        }
    }

    int N;
    Point start, goal;
    vector<Segment> ss;
    bool input() {
        cin >> N;
        if (N == 0) return false;
        cin >> start >> goal;
        ss.clear(); ss.resize(N);
        for (int i = 0; i < N; i++) {
            cin >> ss[i];
        }
        return true;
    }

    struct Edge {
        Point from, to;
        double w;
        Edge() {}
        Edge(Point from, Point to, double w) : from(from), to(to), w(w) {}
    };
    map< Point, vector<Edge> > G;

    void addEdge(const Point& a, const Point& b) {
        //cout << a << " -> " << b << endl;
        G[a].push_back(Edge(a, b, distance(a, b)));
    }

    struct State {
        Point v;
        double w;
        State(Point v, double w) : v(v), w(w) {}
    };
    bool operator<(const State& a, const State& b) { return a.w > b.w; }

    void dijkstra() {
        map< Point, double > D;
        map< Point, Point > P;
        priority_queue<State> PQ;
        PQ.push(State(start, 0));
        D[start] = 0;
        while (!PQ.empty()) {
            State c = PQ.top(); PQ.pop();
            for (auto it = G[c.v].begin(); it != G[c.v].end(); it++) {
                Edge& e = *it;
                if (D.count(e.to) == 0 || D[e.to] > c.w + e.w) {
                    D[e.to] = c.w + e.w;
                    P[e.to] = e.from;
                    PQ.push(State(e.to, c.w + e.w));
                }
            }
        }

        if (D.count(goal) == 0) {
            cout << -1 << endl;
            return;
        }

        vector<Point> path;
        Point p = goal;
        while (p != start) {
            path.push_back(p);
            p = P[p];
        }
        path.push_back(start);
        reverse(whole(path));
        for (int i = 0; i < path.size(); i++) {
            cout << path[i].x << " " << path[i].y << endl;
        }
        cout << 0 << endl;
    }

    void solve() {
        G.clear();
        vector<Segment> rs; // 道
        vector<Segment> ps; // 標識
        for (int i = 0; i < N; i++) {
            bool a = false, b = false;
            for (int j = 0; j < N; j++) {
                if (i == j) continue;
                if (intersects(ss[i], ss[j])) {
                    Point p = crosspoint(ss[i], ss[j]);
                    if (ss[i].a == p) a = true;
                    if (ss[i].b == p) b = true;
                }
            }
            (a && b ? rs : ps).push_back(ss[i]);
        }

        vector<Segment> rs1; // 道を分割したの
        for (int i = 0; i < rs.size(); i++) {
            vector<Point> cs;
            cs.push_back(rs[i].a);
            cs.push_back(rs[i].b);
            for (int j = 0; j < rs.size(); j++) {
                if (i == j) continue;
                if (not intersects(rs[i], rs[j])) continue;
                cs.push_back(crosspoint(rs[i], rs[j]));
            }
            sort(whole(cs));
            uniq(cs);
            for (int j = 0; j < cs.size() - 1; j++) {
                rs1.push_back(Segment(cs[j], cs[j + 1]));
            }
        }

        swap(rs, rs1);

        for (int i = 0; i < rs.size(); i++) {
            bool ab = true;
            bool ba = true;
            Point v = rs[i].b - rs[i].a;
            for (int j = 0; j < ps.size(); j++) {
                if (intersects(rs[i], ps[j])) {
                    Point p = (contains(rs[i], ps[j].a) ? ps[j].a : ps[j].b);
                    Point q = (contains(rs[i], ps[j].a) ? ps[j].b : ps[j].a);
                    if (dot(v, q - p) >= 0) {
                        ab = false;
                    }
                    if (dot(-v, q - p) >= 0) {
                        ba = false;
                    }
                }
            }
            if (ab) addEdge(rs[i].a, rs[i].b);
            if (ba) addEdge(rs[i].b, rs[i].a);
        }
        dijkstra();
    }
}

int main() {
    while (input()) solve();
    return 0;
}

Measured memory_bytes: 3240