#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;
#define MAX_MIRRORS 7
#define MAX_REFLECT 7
struct Point {
double x,y;
Point() : x(0.0), y(0.0) {}; Point(double x, double y) : x(x), y(y) {};
};
struct Segment {
Point end[2];
Segment() {};
Segment(double x1, double y1, double x2, double y2) {
end[0] = Point(x1,y1);
end[1] = Point(x2,y2);
}
Point perpendicular() const {
return Point(end[1].y - end[0].y, end[0].x - end[1].x); }
Point snapTo(const Point& p) const {
Point v = perpendicular();
double t = (end[0].x * v.x + end[0].y * v.y - v.x*p.x - v.y*p.y) / (v.x*v.x + v.y*v.y);
return Point(p.x + t*v.x, p.y + t*v.y);
}
};
ifstream fin("laser.in");
int n;
Segment mirror[MAX_MIRRORS];
int reflections[MAX_REFLECT]; vector<double> solutions;
double signedArea(Point a, Point b, Point c) {
return ( (b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y) ) / 2.0;
}
bool lineIntersectsSegment(const Point& a, const Point& b, const Point& c, const Point& d) {
return ( (signedArea(a,b,c) > 0) != (signedArea(a,b,d) > 0) );
}
bool segmentIntersectsSegment(const Point& a, const Point& b, const Point& c, const Point& d) {
return lineIntersectsSegment(a,b,c,d) && lineIntersectsSegment(c,d,a,b);
}
Point computeIntersection(const Point& a, const Point& b, const Point& c, const Point& d) {
Segment temp(a.x, a.y, b.x, b.y);
Point perp = temp.perpendicular();
double constant = perp.x * a.x + perp.y * a.y;
double t = (constant - perp.x*c.x - perp.y*c.y) / (perp.x*(d.x-c.x) + perp.y*(d.y-c.y));
return Point(c.x + t*(d.x-c.x), c.y + t*(d.y-c.y));
}
Point reflect(const Point& p, const Segment& m) {
Point intersect = m.snapTo(p);
Point delta(intersect.x-p.x, intersect.y-p.y);
return Point(p.x + 2*delta.x, p.y + 2*delta.y);
}
double computeIdealAngle(int numReflect) {
Point target(0,0);
for (int k=numReflect-1; k >= 0; k--) {
target = reflect(target, mirror[reflections[k]]);
}
double radians = atan2(target.y, target.x); double degrees = radians * 180.0 / M_PI;
if (degrees < -0.5) degrees += 360.0; return degrees;
}
bool verify(double theta, int numReflect) {
Point p(0,0);
double radian = theta * M_PI / 180;
Point dir(cos(radian), sin(radian));
vector<Point> hops;
hops.push_back(p);
for (int k=0; k < numReflect; k++) {
Segment& m(mirror[reflections[k]]); Point forward(p.x+dir.x, p.y+dir.y);
if (!lineIntersectsSegment(p, forward, m.end[0], m.end[1]))
return false;
Point pRefl = reflect(p,m); Point oldP = p;
p = computeIntersection(p, forward, m.end[0], m.end[1]);
if (dir.x*oldP.x + dir.y*oldP.y > dir.x*p.x + dir.y*p.y)
return false; hops.push_back(p);
dir = Point(p.x - pRefl.x, p.y - pRefl.y); }
if (dir.x*p.x + dir.y*p.y > 0)
return false; hops.push_back(Point(0,0));
for (int k=0; k < numReflect + 1; k++)
for (int j=0; j < n; j++)
if (j != reflections[k] && (k == 0 || j != reflections[k-1]))
if (segmentIntersectsSegment(hops[k], hops[k+1], mirror[j].end[0], mirror[j].end[1]))
return false;
return true; }
void fillAndSolve(int numReflect=0) {
if (numReflect < MAX_REFLECT) {
for (int m=0; m < n; m++) { if (numReflect == 0 || m != reflections[numReflect-1]) { reflections[numReflect] = m;
double theta = computeIdealAngle(numReflect + 1);
if (verify(theta, numReflect + 1))
solutions.push_back(theta);
fillAndSolve(numReflect+1);
}
}
}
}
int main() {
while (true) {
fin >> n;
if (n == 0) break;
for (int k=0; k<n; k++) {
fin >> mirror[k].end[0].x >> mirror[k].end[0].y;
fin >> mirror[k].end[1].x >> mirror[k].end[1].y;
}
solutions.clear();
fillAndSolve();
if (solutions.size() == 0)
cout << "no danger" << endl;
else {
vector<int> clean;
for (int k=0; k < solutions.size(); k++)
clean.push_back((int) (solutions[k] + 0.5));
sort(clean.begin(), clean.end());
vector<int> uniq(clean.begin(), unique(clean.begin(), clean.end()));
cout << uniq[0];
for (int k=1; k < uniq.size(); k++)
cout << " " << uniq[k];
cout << endl;
}
}
}