Go: package main

import (
	"bufio"
	"os"
	"strconv"
	"strings"
	"fmt"
)

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	x := make([]int, 100)
	y := make([]int, 100)
	r := make([]int, 100)
	for scanner.Scan() {
		a, _ := strconv.Atoi(scanner.Text())
		if a == 0 {
			break
		}
		for i := 0; i < a; i++ {
			scanner.Scan()
			input := strings.Split(scanner.Text(), " ")
			tmpx, _ := strconv.Atoi(input[0])
			tmpy, _ := strconv.Atoi(input[1])
			tmpr, _ := strconv.Atoi(input[2])
			x[i], y[i], r[i] = tmpx, tmpy, tmpr
		}
		scanner.Scan()
		b, _ := strconv.Atoi(scanner.Text())
		for i := 0; i < b; i++ {
			scanner.Scan()
			input := strings.Split(scanner.Text(), " ")
			c, _ := strconv.Atoi(input[0])
			d, _ := strconv.Atoi(input[1])
			e, _ := strconv.Atoi(input[2])
			f, _ := strconv.Atoi(input[3])
			ok := false
			for j := 0; j < a; j++ {
				if (c-x[j])*(c-x[j])+(d-y[j])*(d-y[j]) >= r[j]*r[j] || (e-x[j])*(e-x[j])+(f-y[j])*(f-y[j]) >= r[j]*r[j] {
					if (e-c)*(x[j]-c)+(f-d)*(y[j]-d) < 0 {
						if (x[j]-c)*(x[j]-c)+(y[j]-d)*(y[j]-d) <= r[j]*r[j] {
							ok = true
						}
					} else {
						if (e-c)*(x[j]-c)+(f-d)*(y[j]-d)>(e-c)*(e-c)+(f-d)*(f-d) {
							if (x[j]-e)*(x[j]-e)+(y[j]-f)*(y[j]-f)<=r[j]*r[j] {
								ok = true
							}
						} else {
							if (x[j]-c)*(x[j]-c)+(y[j]-d)*(y[j]-d)-((e-c)*(x[j]-c)+(f-d)*(y[j]-d))*((e-c)*(x[j]-c)+(f-d)*(y[j]-d))/((e-c)*(e-c)+(f-d)*(f-d))<=r[j]*r[j] {
								ok = true
							}
						}
					}

				}
			}
			if ok {
				fmt.Println("Safe")
			} else {
				fmt.Println("Danger")
			}
		}
	}
}

C++: #include <complex>
#include <cstdio>
#include <string>
#include <iostream>
#include <vector>
using namespace std;

#define loop(i,a,b) for(int i=(a);i<int(b);i++)
#define rep(i,b) loop(i,0,b)

typedef double R;

const R eps = 1e-8;
const R inf = 1e12;
const R pi = acos(-1);
typedef complex<R> P;
namespace std {
    bool operator < (const P& a, const P& b) {
        return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
    }
}
R cross(const P& a, const P& b) {
    return imag(conj(a)*b);
}
R dot(const P& a, const P& b) {
    return real(conj(a)*b);
}

struct L : public vector<P> {
    // A to B
    L(const P &a = P(), const P &b = P()) {
        push_back(a); push_back(b);
    }
    // ax+by+c=0
    L(R a, R b, R c){
        if(fabs(a) < eps) *this = L(P(0,-c/b),P(1,-c/b));
        else if(fabs(b) < eps) *this = L(P(-c/a,0),P(-c/a,1));
        else *this = L(P(-c/a,0), P(0,-c/b));
    }
};

typedef vector<P> G;

struct C {
    P p; R r;
    C(const P &p = P(), R r = 0) : p(p), r(r) { }
};

// CCW
enum { CCW = +1, CW = -1, CAB = +2, ABC = -2, SAMEPOINT = 0 };
int ccw(P a, P b, P c) {
    b -= a; c -= a;
    if (cross(b, c) > 0)   return CCW; // a->b->c 反時計回り
    if (cross(b, c) < 0)   return  CW; // a->b->c 時計回り
    if (dot(b, c) < 0)     return CAB; // c--a--b 直線上
    if (norm(b) < norm(c)) return ABC; // a--b--c 直線上
    return SAMEPOINT; // 2点以上が重なっている
}

// A->C方向の角ABCの大きさを[0,2*Pi]で求める
R arg(P a, P b, P c) {
    R th = arg((a - b) / (c - b));
    return th > 0 ? th : th+2*pi;
}

// 交差判定
bool colLL(const L &l, const L &m) {
    return
        abs(cross(l[1]-l[0], m[1]-m[0])) > eps || // non-parallel
        abs(cross(l[1]-l[0], m[0]-l[0])) < eps;   // same line
}

bool colLS(const L &l, const L &s) {
    return
        cross(l[1]-l[0], s[0]-l[0])*       // s[0] is left of l
        cross(l[1]-l[0], s[1]-l[0]) < eps; // s[1] is right of l
}

bool colLP(const L &l, const P &p) {
    return abs(cross(l[1]-p, l[0]-p)) < eps;
}

bool colSS(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 colSP(const L &s, const P &p) {
    return abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]) < eps; // triangle inequality
}

bool colCP(const C &c, const P &p) {
    // 境界または内部
    return abs(c.p - p) <= c.r + eps;
}

int colCC(const C& c1, const C& c2){
    double d = abs(c1.p - c2.p), r1 = c1.r, r2 = c2.r;
    if(abs(d - r1 - r2) < eps) return  1; // 接する
    if(d > r1 + r2)       return  0; // 共通部分を持たない
    if(d < r1 - r2)       return +3; // c1 が c2 の中にある
    if(d < r2 - r1)       return -3; // c2 が c1 の中にある
    return 2; // 2つの交点を持つ
}

// 射影
P projLP(const L &l, const P &p) {
    double t = dot(p-l[0], l[0]-l[1]) / norm(l[0]-l[1]);
    return l[0] + t*(l[0]-l[1]);
}
L projLL(const L& l, const L& m) {
    return L(projLP(l,m[0]), projLP(l,m[1]));
}

// 反射
P reflLP(const L &l, const P &p) {
    return p + 2. * (projLP(l, p) - p);
}
L reflLL(const L& l, const L& m) {
    return L(reflLP(l,m[0]), reflLP(l,m[1]));
}

// 距離
R distLP(const L &l, const P &p) {
    return abs(p - projLP(l, p));
}

R distLL(const L &l, const L &m) {
    return colLL(l, m) ? 0 : distLP(l, m[0]);
}

R distLS(const L &l, const L &s) {
    if (colLS(l, s)) return 0;
    return min(distLP(l, s[0]), distLP(l, s[1]));
}

R distSP(const L &s, const P &p) {
    const P r = projLP(s, p);
    if (colSP(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}

R distSS(const L &s, const L &t) {
    if (colSS(s, t)) return 0;
    return min(min(distSP(s, t[0]), distSP(s, t[1])),
               min(distSP(t, s[0]), distSP(t, s[1])));
}

R distCP(const C &c, const P &p) {
    return max(0. , abs(c.p - p));
}

// positive -> outside
// zero     -> on the boundaly
// negative -> inside
R distCL(const C& c, const L& l){
    R d = distLP(l,c.p);
    return d - c.r;
}

// 交点
vector<P> intLL(const L &l, const L &m) {
    R A = cross(l[1] - l[0], m[1] - m[0]);
    R B = cross(l[1] - l[0], l[1] - m[0]);
    if (abs(A) < eps && abs(B) < eps) return {m[0]}; // same line
    if (abs(A) < eps) return {}; // parallel
    return {m[0] + B / A * (m[1] - m[0])};
}

vector<P> intSS(const L& s, const L& t) {
    if(colSS(s,t)) return intLL(s,t);
    else return {};
}

vector<P> intLS(const L& l, const L& s){
    if(colLS(l,s)) return intLL(l,s);
    else return {};
}

// Verify : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1183
//        : http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=2045
vector<P> intCL(const C& c, const L& l){
    R d = distLP(l,c.p); // 中心と直線の距離
    if(fabs(d-c.r) < eps) return { projLP(l, c.p) }; // 触れている
    if(d > c.r) return {}; // 離れている
    P h = projLP(l, c.p);
    P u = sqrt(c.r*c.r - d*d) * (l[0]-l[1]) / abs(l[0]-l[1]);
    return {h+u, h-u};
}

vector<P> intCS(const C& c, const L& s){
    vector<P> cs = intCL(c,s), res;
    for(const P& p : cs) {
        if(colSP(s,p)) res.push_back(p);
    }
    return res;
}

vector<P> intCC(const C& c1, const C& c2){
    int i = colCC(c1,c2);
    // 共通部分なし || 内部
    if(i==0 || abs(i)==3) return {};
    R r1 = c1.r, r2 = c2.r, d = abs(c1.p - c2.p);
    // 接する
    if(i==1) return { c1.p + (c2.p - c1.p) * r1/d };
    // 2つの交点を持つ
    P p = c1.p - c2.p;
    R A = -2. * p.real(), B = 2 * p.imag();
    R C = norm(c1.p) - norm(c2.p) - r1*r1 + r2*r2;
    return intCL(c1, L(A,B,C));
}

int main(){
    int n;
    while(cin>>n && n){
        vector<C> cs(n);
        rep(i,n){
            double x,y,r;
            cin>>x>>y>>r;
            cs[i] = C(P(x,y),r);
        }
        int m;
        cin >> m;
        rep(i,m){
            int x1,y1,x2,y2;
            cin >> x1>>y1>>x2>>y2;
            L l(P(x1,y1),P(x2,y2));
            bool safe = true;
            for(auto& c: cs){
                if(intCS(c,l).size()){
                    safe = false;
                    break;
                }
            }
            puts(!safe ? "Safe" : "Danger");
        }
    }
}