Go: package main

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

var scanner = bufio.NewScanner(os.Stdin)

func main() {
	for scanner.Scan() {
		buf0 := strings.Split(scanner.Text(), " ")
		input0 := make([]int, 2)
		for i := range input0 {
			input0[i], _ = strconv.Atoi(buf0[i])
		}
		if input0[0] == 0 && input0[1] == 0 {
			break
		}
		a, b := input0[0], input0[1]
		scanner.Scan()
		buf1 := strings.Split(scanner.Text(), " ")
		input1 := make([]int, 2)
		for i := range input1 {
			input1[i], _ = strconv.Atoi(buf1[i])
		}
		c, d := input1[0], input1[1]
		scanner.Scan()
		buf2 := strings.Split(scanner.Text(), " ")
		input2 := make([]int, 2)
		for i := range input2 {
			input2[i], _ = strconv.Atoi(buf2[i])
		}
		e, f := input2[0], input2[1]
		scanner.Scan()
		buf3 := strings.Split(scanner.Text(), " ")
		input3 := make([]int, 2)
		for i := range input3 {
			input3[i], _ = strconv.Atoi(buf3[i])
		}
		g, h := input3[0], input3[1]
		scanner.Scan()
		r, _ := strconv.Atoi(scanner.Text())
		if (a-g)*(a-g)+(b-h)*(b-h) <= r*r && (c-g)*(c-g)+(d-h)*(d-h) <= r*r && (e-g)*(e-g)+(f-h)*(f-h) <= r*r {
			fmt.Println("b")
		} else if dist(a, b, c, d, g, h) > float64(r)-0.000001 && dist(a, b, e, f, g, h) > float64(r)-0.000001 && dist(e, f, c, d, g, h) > float64(r)-0.000001 && inclusive(a, b, c, d, e, f, g, h) {
			fmt.Println("a")
		} else if CL_intersect(a, b, c, d, g, h, r) || CL_intersect(a, b, e, f, g, h, r) || CL_intersect(e, f, c, d, g, h, r) {
			fmt.Println("c")
		} else {
			fmt.Println("d")
		}
	}
}

func CL_intersect(ax, ay, bx, by, cx, cy, r int) bool {
	acx := cx - ax
	acy := cy - ay
	bcx := cx - bx
	bcy := cy - by
	abx := bx - ax
	aby := by - ay
	if acx*acx+acy*acy >= r*r || bcx*bcx+bcy*bcy >= r*r {
		if abx*acx+aby*acy < 0 {
			if acx*acx+acy*acy <= r*r {
				return true
			}
		} else {
			if abx*acx+aby*acy > abx*abx+aby*aby {
				if bcx*bcx+bcy*bcy <= r*r {
					return true
				}
			} else if acx*acx+acy*acy-(abx*acx+aby*acy)*(abx*acx+aby*acy)/(abx*abx+aby*aby) <= r*r {
				return true
			}
		}
	}
	return false
}

func inclusive(ax, ay, bx, by, cx, cy, px, py int) bool {
	ok1 := true
	ok2 := true
	if (bx-ax)*(py-ay)-(px-ax)*(by-ay) < 0 {
		ok1 = false
	}
	if (bx-ax)*(py-ay)-(px-ax)*(by-ay) > 0 {
		ok2 = false
	}
	if (cx-bx)*(py-by)-(px-bx)*(cy-by) < 0 {
		ok1 = false
	}
	if (cx-bx)*(py-by)-(px-bx)*(cy-by) > 0 {
		ok2 = false
	}
	if (ax-cx)*(py-cy)-(px-cx)*(ay-cy) < 0 {
		ok1 = false
	}
	if (ax-cx)*(py-cy)-(px-cx)*(ay-cy) > 0 {
		ok2 = false
	}
	return ok1 || ok2
}

func dist(ax, ay, bx, by, px, py int) float64 {
	dx := float64(bx - ax)
	dy := float64(by - ay)
	A := float64(dx*dx + dy*dy)
	B := dx*float64(ax-px) + dy*float64(ay-py)
	t := -B / A
	if t < 0 {
		t = 0
	}
	if t > 1 {
		t = 1
	}
	tx := float64(ax) + dx*t
	ty := float64(ay) + dy*t
	return math.Sqrt((float64(px)-tx)*(float64(px)-tx) + (float64(py)-ty)*(float64(py)-ty))
}

C++: #include <iostream>
#include <algorithm>
#include <cmath>
#include <cassert>
#include <vector>

using namespace std;

//-------------------------------------------------------------------------
// 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) {}
    };
 
	struct triangle {
		point p[3];
	};
 
    enum rotate_dir {
        rotate_None = 0,
        rotate_CW = 1,
        rotate_CCW = -1
    };
 
    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 cross_product(const point& p1, const point& p2)
    {
        return p1.x * p2.y - p2.x * p1.y;
    }
 
    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;
    }
 
    ///! p1-p2-p3が左右どちらの方向に折れているかを判定
    rotate_dir direction(const point& p1, const point& p2, const point& p3)
    {
        point p1_p3 = p1 - p3;
        point p2_p3 = p2 - p3;
        double cross = cross_product(p1_p3, p2_p3);
 
        if (std::abs(cross) < EPS) {
            return rotate_None;
        }
        else if (cross > 0) {
            return rotate_CW;
        }
        else {
            return rotate_CCW;
        }
    }

	bool is_inside_circle(const point& p, const circle& c)
	{
		return get_distance(p, c.center) <= c.radius + EPS;
	}

	bool is_inside_circle(const triangle& t, const circle& c)
	{
		for (int i = 0; i < 3; i++) {
			if (!is_inside_circle(t.p[i], c)) {
				return false;
			}
		}
		return true;
	}
 
    // (p1s, p1e)と(p2s, p2e)の線分交差判定.EPS以下で接している場合はtrue、重なっている場合はfalse
    bool intersect(const point& p1s, const point& p1e, const point& p2s, const point& p2e)
    {
        assert(p1s != p1e && p2s != p2e);
        return
            (direction(p1s, p1e, p2s) != direction(p1s, p1e, p2e)) &&
            (direction(p2s, p2e, p1s) != direction(p2s, p2e, p1e));
    }

	// 円と三角形が交差するかどうか
	bool intersect(const circle& c, const triangle& t)
	{
		for (int i = 0; i < 3; i++) {
			point ps = t.p[i], pe = t.p [(i + 1) % 3];

			if (is_inside_circle(ps, c) != is_inside_circle(pe, c)) {
				return true;
			}
			if (is_inside_circle(ps, c) && is_inside_circle(pe, c)) {
				continue; // この辺は交差しない
			}
			point m = get_project(ps, pe, c.center);

			if (get_distance(m, c.center) <= c.radius + EPS && is_inter_point(ps, pe, m)) {
				return true;
			}
		}
		return false;
	} 

    // targetが三角形p1,p2,p3の内部にあるかどうか
    bool is_inside_triangle(const point& target, const point& p1, const point& p2, const point& p3)
    {
        point center_of_gravity = (p1 + p2 + p3) / 3; // 重心
 
        if (center_of_gravity == target) return true;
 
        // 重心とtargetを結んだ線分が三角形の辺と交叉するなら、点は三角形の外部にある
        bool intersect_any =
            intersect(p1, p2, center_of_gravity, target) ||
            intersect(p2, p3, center_of_gravity, target) ||
            intersect(p3, p1, center_of_gravity, target);
 
        return !intersect_any;
    }

	bool is_inside_triangle(const point& target, const triangle& t)
	{
		return is_inside_triangle(target, t.p[0], t.p[1], t.p[2]);
	}
 
	bool is_inside_triangle(const circle& c, const triangle& t)
	{
		if (is_inside_triangle(c.center, t) && !intersect(c, t)) {
			return true;
		} else {
			return false;
		}
	}
 
} // namespace geometry


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

using namespace geometry;

int main(void) {
	triangle triangle;
	circle circle;

	while (cin >> triangle.p[0]) {
		if (triangle.p[0].x == 0 && triangle.p[0].y == 0) {
			break;
		}
		cin >> triangle.p[1] >> triangle.p [2] >> circle;

		if (is_inside_triangle(circle, triangle)) {
			cout << "a" << endl;
		} else if (is_inside_circle(triangle, circle)) {
			cout << "b" << endl;
		} else if (intersect(circle, triangle)) {
			cout << "c" << endl;
		} else {
			cout << "d" << endl;
		}
	}
}