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 <iostream>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <vector>

//-------------------------------------------------------------------------
// geometric library
 
namespace geometry {
 
#define EPS 1E-10 ///< 0とみなすサイズ。適当
 
    struct point {
        double x;
        double y;
 
		point() {}
		point(double x, double y) : x(x), y(y) {}
        point& operator += (const point& rhs) { x += rhs.x; y += rhs.y; return *this; }
        point& operator -= (const point& rhs) { x -= rhs.x; y -= rhs.y; return *this; }
        point& operator /= (double factor) { x /= factor; y /= factor; return *this; }
        point& operator *= (double factor) { x *= factor; y *= factor; return *this; }
        bool operator == (const point& rhs) const { return (std::abs(x - rhs.x) < EPS) && (std::abs(y - rhs.y) < EPS); }
        bool operator != (const point& rhs) const { return !(*this == rhs); }
        bool operator <= (const point& rhs) const { return x < rhs.x || (x == rhs.x && y <= rhs.y); }
        bool operator >= (const point& rhs) const { return x > rhs.x || (x == rhs.x && y >= rhs.y); }
        bool operator < (const point& rhs) const { return !(*this >= rhs); }
        bool operator > (const point& rhs) const { return !(*this <= rhs); }
		double arg() const { return atan2(y, x); }
        double norm() const { return sqrt(x * x + y * y); }
		point get_normal() const { return point(-y, x); }
    };

	typedef point vec2d;
 
    struct circle {
        point center;
        double radius;
		circle() {}
		circle(double x, double y, double r) : center(x, y), radius(r) {}
    };
 
    point operator + (const point& p1, const point& p2)
    {
        point p(p1);
        p += p2;
        return p;
    }
 
    point operator / (const point& p1, double factor)
    {
        point p(p1);
        p /= factor;
        return p;
    }
  
    point operator * (const point& p1, double factor)
    {
        point p(p1);
        p *= factor;
        return p;
    }
 
    point operator * (double factor, const point& p1)
    {
        point p(p1);
        p *= factor;
        return p;
    }
 
    point operator - (const point& p1, const point& p2)
    {
        point p(p1);
        p -= p2;
        return p;
    }
 
    std::istream& operator >> (std::istream& is, point& p)
    {
        is >> p.x >> p.y;
        return is;
    }

    std::istream& operator >> (std::istream& is, circle& c)
    {
        is >> c.center >> c.radius;
        return is;
    }

    ///! 2点の距離
    double get_distance(const point& p1, const point& p2)
    {
        return sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2));
    }

    double inner_product(const point& p1, const point& p2)
    {
        return p1.x * p2.x + p1.y * p2.y;
    }

	///! 直線s-eにpを投影した点を求める
	point get_project(const point& s, const point& e, const point& p)
	{
		double scale = inner_product(p - s, e - s) / (e - s).norm();
		return s + scale * (e - s) / (e - s).norm();
	}
	
	///! pがs-e間(s,e上含む)にあればtrue
	bool is_inter_point(const point& s, const point& e, const point& p) {
		double d = get_distance(s, p) + get_distance(p, e) - get_distance(s, e);
		return abs(d) < EPS;
	}

} // namespace geometry


using namespace geometry;
using namespace std;

//-----------------------------------------------
//

typedef circle wall;
class field;

class player {
public:
	explicit player(const field& field);
	bool can_see(const player& target) const;
	bool is_inside(const wall& wall) const;
	void move(const point& new_location);
	const point& get_location() const;
private:
	const field& m_field;
	point m_loc;
};

class field {
public:
	void place(const wall& w);
	bool has_any_wall_between(const player& p1, const player& p2) const;
private:
	bool has_wall_between(const player& p1, const player& p2, const wall& wall) const;
	vector<wall> m_walls;
};

//-----------------------------------------------
//

player::player(const field& field) : m_field(field) {}

bool player::can_see(const player& target) const {
	return m_field.has_any_wall_between(*this, target) ? false : true;
}

bool player::is_inside(const wall& wall) const {
	return get_distance(m_loc, wall.center) < wall.radius;
}

void player::move(const point& new_location) {
	m_loc = new_location;
}

const point& player::get_location() const {
	return m_loc;
}

//-----------------------------------------------
//

void field::place(const wall& w) {
	m_walls.push_back(w);
}

bool field::has_wall_between(const player& p1, const player& p2, const wall& wall) const {
	if (p1.is_inside(wall) != p2.is_inside(wall)) {
		return true; // 片方だけ壁の中。
	}
	if (p1.is_inside(wall) && p2.is_inside(wall)) {
		return false; // 両方とも壁の中。
	}

	point m = get_project(p1.get_location(), p2.get_location(), wall.center);

	if (get_distance(m, wall.center) <= wall.radius + EPS && is_inter_point(p1.get_location(), p2.get_location(), m)) {
		return true;
	} else {
		return false;
	}
}

bool field::has_any_wall_between(const player& p1, const player& p2) const {
	if (p1.get_location() == p2.get_location()) {
		return false; // p1 & p2 are at a same point
	}

	for (vector<wall>::const_iterator it = m_walls.begin(); it != m_walls.end(); ++it) {
		if (has_wall_between(p1, p2, *it)) {
			return true;
		}
	}

	return false;
}

//-----------------------------------------------
//

int main(void) {
	int n, m;

	while (cin >> n) {
		if (n == 0) {
			break;
		}

		field f;
		player taro(f);
		player oni(f);

		for (int i = 0; i < n; i++) {
			wall w;
			cin >> w;
			f.place(w);
		}

		cin >> m;

		for (int i = 0; i < m; i++) {
			point t, s;
			cin >> t >> s;
			taro.move(t);
			oni.move(s);

			cout << (oni.can_see(taro) ? "Danger" : "Safe") << endl;
		}
	}
}