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<vector>
#include<algorithm>
#include<string>
#include<complex>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<iomanip>
#include<bitset>
#include<utility>
#include<list>
#include<map>
#include<set>
#include<cstring>
#include<sstream>
#include<cctype>
using namespace std;
const double EPS=1e-10;
const double INF=1e9;
typedef complex<double>P;
namespace std{
    bool operator<(const P& a,const P& b){
        return real(a)!=real(b)?real(a)<real(b):imag(a)<imag(b);
    }
}
#define EQ(a,b) (fabs((a)-(b))<EPS)
#define EQV(a,b) (EQ(real(a),real(b))&&EQ(imag(a),imag(b)))
double cross(const P &a,const P &b){
    return imag(conj(a)*b);
}
double dot(const P &a,const P &b){
    return real(conj(a)*b);
}

struct L:public vector<P>{
    L(const P &a,const P &b){
        push_back(a);push_back(b);
    }
    L(){}
};

typedef vector<P>G;

struct C{
    P p;double r;
    C(const P &p_,double r_):p(p_),r(r_){}
    C(){}
};

int ccw(P a,P b,P c){
    b-=a;c-=a;
    if(cross(b,c)>0)return 1;///counter clockwise
    if(cross(b,c)<0)return -1;///clockwise
    if(dot(b,c)<0)return 2;///c--a--b on line
    if(norm(b)<norm(c))return -2;///a--b--c on line
    return 0;
}
bool orthogonal(P &p,P &q){
    return EQ(dot(p,q),0.0);
}
bool intersectLL(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 intersectLS(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 intersectLP(const L &l,const P &p){
    return abs(cross(l[1]-p,l[0]-p))<EPS;
}
bool intersectSS(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 intersectSP(const L &s,const P &p){
    return abs(abs(s[0]-p)+abs(s[1]-p)-abs(s[1]-s[0]))<EPS;
    ///triangle inequality
}
P projection(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]);
}
P reflection(const L &l,const P &p){
    return p+(projection(l,p)-p)*2.0;
}
double distanceLP(const L &l,const P &p){
    return abs(p-projection(l,p));
}
double distanceLL(const L &l,const L &m){
    return intersectLL(l,m)?0:distanceLP(l,m[1]);
}
double distanceLS(const L &l,const L &s){
    if(intersectLS(l,s))return 0;
    return min(distanceLP(l,s[0]),distanceLP(l,s[1]));
}
double distanceSP(const L &s,const P &p){
    const P r=projection(s,p);
    if(intersectSP(s,r))return abs(r-p);
    return min(abs(s[0]-p),abs(s[1]-p));
}
double distanceSS(const L &s,const L &t){
    if(intersectSS(s,t))return 0;
    return min(min(distanceSP(s,t[0]),distanceSP(s,t[1])),
            min(distanceSP(t,s[0]),distanceSP(t,s[1])));
}
P crossPoint(const L &l,const L &m){
    double A=cross(l[1]-l[0],m[1]-m[0]);
    double 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)assert(false);
    return m[0]+B/A*(m[1]-m[0]);

}

P extreme(const G &g,const L &l){
    int k=0;
    for(int i=1;i<g.size();i++){
        if(dot(g[i],l[1]-l[0])>dot(g[k],l[1]-l[0]))k=i;
    }
    return g[k];
}

G andrewScan(G s){
    G u,l;
    if(s.size()<3)return s;
    sort(s.begin(),s.end());
    u.push_back(s[0]);
    u.push_back(s[1]);

    l.push_back(s[s.size()-1]);
    l.push_back(s[s.size()-2]);

    for(int i=2;i<s.size();i++){
        for(int n=u.size();n>=2&&ccw(u[n-2],u[n-1],s[i])!=-1;n--){
            u.pop_back();
        }
        u.push_back(s[i]);
    }

    for(int i=s.size()-3;i>=0;i--){
        for(int n=l.size();n>=2&&ccw(l[n-2],l[n-1],s[i])!=-1;n--){
            l.pop_back();
        }
        l.push_back(s[i]);
    }
    reverse(l.begin(),l.end());
    for(int i=u.size()-2;i>=1;i--)l.push_back(u[i]);
    return l;
}
/*
IN 2
ON 1
OUT 0
*/
int contains(G g,P p){
    int n=g.size();
    bool x=false;
    for(int i=0;i<n;i++){
        P a=g[i]-p,b=g[(i+1)%n]-p;
        if(abs(cross(a,b))<EPS&&dot(a,b)<EPS)return 1;
        if(imag(a)>imag(b))swap(a,b);
        if(imag(a)<EPS&&EPS<imag(b)&&cross(a,b)>EPS)x=!x;
    }
    return (x?2:0);
}

int main(){
    G g(3);
    C c;
    while(scanf("%lf%lf",&g[0].real(),&g[0].imag()),g[0].real()!=0||g[0].imag()!=0){
        for(int i=1;i<3;i++)scanf("%lf%lf",&g[i].real(),&g[i].imag());
        scanf("%lf%lf%lf",&c.p.real(),&c.p.imag(),&c.r);

        bool flag=true;

        for(int i=0;i<3;i++){
            flag&=(distanceSP(L(g[i],g[(i+1)%3]),c.p)+EPS>c.r);
        }

        if(flag){
            if(contains(g,c.p)==2)puts("a");
            else puts("d");
            continue;
        }
        flag=true;
        for(int i=0;i<3;i++){
            flag&=(c.r+EPS>abs(g[i]-c.p));
        }
        if(flag){
            puts("b");
            continue;
        }
        puts("c");


    }
    return 0;
}