#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)
#define self (*this)
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> {
    L(const P &a = P(), const P &b = P()) {
        push_back(a); push_back(b);
    }
    L(R a, R b, R c){ // ax+by+c=0
        if(fabs(a) < eps) self = L(P(0,-c/b),P(1,-c/b));
        else if(fabs(b) < eps) self = L(P(-c/a,0),P(-c/a,1));
        else self = L(P(-c/a,0), P(0,-c/b));
    }
    P vec() const { return self[1] - self[0]; }
};

struct S : public vector<P> {
    // A to B
    S(const P &a = P(), const P &b = P()) { push_back(a); push_back(b); }
    L toL() const { return L(self[0], self[1]); }
    P vec() const { return toL().vec(); }
    R len() const { return abs(vec()); }
};

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 col(const L &l, const L &m) {
    return abs(cross(l.vec(), m.vec())) > eps || abs(cross(l.vec(), m[0]-l[0])) < eps;
}

bool col(const L &l, const S &s) {
    return cross(l.vec(), s[0]-l[0])*cross(l.vec(), s[1]-l[0]) < eps;
}

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

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

int col(const C& c1, const C& c2){
    double d = abs(c1.p - c2.p), r1 = c1.r, r2 = c2.r;
    if(r1 + r2 < d) return 0; // 離れている
    if(abs(r1 + r2 - d) < eps) return 1; // 外接
    if(abs(d - abs(r1 - r2)) < eps) return -1; // 内接
    if(d < r1 - r2)            return +3; // c1 が c2 の中にある
    if(d < r2 - r1)            return -3; // c2 が c1 の中にある
    return 2; // 2つの交点を持つ
}

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

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

// 距離
R dist(const P &p, const P &q){
    return abs(p - q);
}

R dist(const L &l, const P &p) {
    return abs(p - proj(l, p));
}

R dist(const L &l, const L &m) {
    return col(l, m) ? 0 : dist(l, m[0]);
}

R dist(const L &l, const S &s) {
    if (col(l, s)) return 0;
    return min(dist(l, s[0]), dist(l, s[1]));
}

R dist(const S &s, const P &p) {
    const P r = proj(s.toL(), p);
    if (col(s, r)) return abs(r - p);
    return min(abs(s[0] - p), abs(s[1] - p));
}

R dist(const S &s, const S &t) {
    if (col(s, t)) return 0;
    return min(min(dist(s, t[0]), dist(s, t[1])),
               min(dist(t, s[0]), dist(t, s[1])));
}

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

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

// 交点
vector<P> hit(const L &l, const L &m) {
    R A = cross(l.vec(), m.vec());
    R B = cross(l.vec(), 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.vec())};
}

vector<P> hit(const S& s, const S& t) {
    if(col(s,t)) return hit(s,t);
    else return {};
}

vector<P> hit(const L& l, const S& s){
    if(col(l,s)) return hit(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> hit(const C& c, const L& l){
    R d = dist(l,c.p); // 中心と直線の距離
    if(fabs(d-c.r) < eps) return { proj(l, c.p) }; // 触れている
    if(d > c.r) return {}; // 離れている
    P h = proj(l, c.p);
    P u = sqrt(c.r*c.r - d*d) * (l.vec()) / abs(l.vec());
    return {h+u, h-u};
}

vector<P> hit(const C& c, const S& s){
    vector<P> cs = hit(c,s.toL()), res;
    for(const P& p : cs) {
        if(col(s,p)) res.push_back(p);
    }
    return res;
}

vector<P> hit(const C& c1, const C& c2){
    if(abs(c1.p - c2.p) < 0) return {}; // 中心が同じ
    int i = col(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 }; // 接する
    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 hit(c1, L(A,B,C)); // 2つの交点を持つ
}

vector<P> hit(const C& c, const G& g){
    vector<P> res;
    int n = g.size();
    rep(i,n){
        vector<P> ps = hit(c, S(g[i],g[(i+1)%n]));
        rep(j,ps.size()) res.push_back(ps[j]);
    }
    return res;
}

bool inside(C c, G t){
    int ccw1 = ccw(t[0], t[1], c.p);
    int ccw2 = ccw(t[1], t[2], c.p);
    int ccw3 = ccw(t[2], t[0], c.p);
    if ( !(ccw1 == ccw2 && ccw2 == ccw3 ) ) return false;
    rep(i,t.size()){
        L l(t[i], t[(i+1)%3]);
        if(c.r > dist(l, c.p)) return false;
    }
    return true;
}

bool inside(G t, C c){
    rep(i,t.size()){
        if(c.r < dist(t[i],c.p)) return false;
    }
    return true;
}

bool isIntersect(C c, G t){
    rep(i,3){
        S s(t[i], t[(i+1)%3]);
        auto ps = hit(c,s);
        if(ps.size()) return true;
    }
    return false;
}

char solve(C c, G t){
    if(inside(c,t)) return 'a';
    if(inside(t,c)) return 'b';
    if(isIntersect(c,t)) return 'c';
    return 'd';
}

int main(){
    int a,b;
    while(cin>>a>>b && a){
        G t(3);
        t[0] = P(a,b);
        rep(i,2){
            int a,b;
            cin>>a>>b;
            t[i+1] = P(a,b);
        }
        int a,b,r;
        cin>>a>>b>>r;
        C c(P(a,b),r);
        cout << solve(c,t) << endl;
    }
}

Measured memory_bytes: 1216