#include<bits/stdc++.h>

using namespace std;

#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b))<EPS)
#define PI M_PI

const double inf=1e20;

inline int sign(const double &x){
    if(x>EPS) return 1;
    else if(x<-EPS) return -1;
    return 0;
}

/*   点  */
struct Point{
    double x,y;

    Point(double x=0,double y=0):x(x),y(y){}

    Point operator + (Point p) { return Point(x+p.x,y+p.y); }
    Point operator - (Point p) { return Point(x-p.x,y-p.y); }
    Point operator * (double k) { return Point(k*x,k*y); }
    Point operator / (double k) { return Point(x/k,y/k); }

    //向量的大小
    inline double abs(){ return sqrt(norm()); }
    inline double norm() { return x*x+y*y; }

    bool operator < (const Point & p) const{
        return sign(x-p.x)!=0?sign(x-p.x)<0:sign(y-p.y)<0;
    }

    bool operator == (const Point & p) const {
        return fabs(x-p.x)<EPS&&fabs(y-p.y)<EPS;
    }
};
typedef Point Vector;

double dot(Vector a,Vector b){
    return a.x*b.x+a.y*b.y;
}
double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}
struct Circle{
    Point c;
    double r;
    Circle(Point c = Point() ,double r = 0.0 ):c(c),r(r){}
    //求与当前点所成的极角为a的点坐标
    Point point(double a){
        return Point(c.x+r*cos(a),c.y+r*sin(a));
    }
};
Point rotate(Point base,Point a,double r){      //a-base 向量旋转r度。
  Point b=a-base;
  a.x=b.x*cos(r)-b.y*sin(r);                // + - 注意方向
  a.y=b.x*sin(r)+b.y*cos(r);
  a=a+base;
  return a;
}

pair<Point,Point> getTangent(Circle c,Point p){
  Vector v=p-c.c;
  double r=acos(c.r/v.abs());
  v=v*c.r/v.abs();
  Point p1=rotate(c.c,c.c+v,r);
  Point p2=rotate(c.c,c.c+v,2*PI-r);
  return make_pair(p1,p2);
}

int getTangents(Circle A, Circle B, Point *a, Point *b){
    int cnt = 0;        //存切点用
    if(sign(A.r - B.r) < 0){
        swap(A, B);
        swap(a, b);
    }
    double d = sqrt((A.c.x - B.c.x) * (A.c.x - B.c.x) + (A.c.y - B.c.y) * (A.c.y - B.c.y));     //圆心距
    double rdiff = A.r - B.r;      //两圆半径差
    double rsum = A.r + B.r;       //两圆半径和
    if(sign(d - rdiff) < 0) return 0;        //1.内含
    double base = atan2(B.c.y - A.c.y, B.c.x - A.c.x);      //向量AB的极角
    if(sign(d) == 0) return -1;        //2.重合
    if(sign(d - rdiff) == 0){       //3.内切
        a[cnt] = b[cnt] = A.point(base);
        cnt++;
        return 1;
    }
    double ang = acos((A.r - B.r) / d);
    a[cnt] = A.point(base + ang); b[cnt] = B.point(base + ang); cnt++;      //4.相交（外切、外离的外公切线也在此求出）
    a[cnt] = A.point(base - ang); b[cnt] = B.point(base - ang); cnt++;      //两条外公切线的切点
    if(sign(d - rsum) == 0){        //5.外切
        a[cnt] = b[cnt] = A.point(base);
        cnt++;
    }
    else if(sign(d - rsum) > 0){      //6.外离
        double ang = acos((A.r + B.r) / d);
        a[cnt] = A.point(base + ang); b[cnt] = B.point(PI + base + ang); cnt++;
        a[cnt] = A.point(base - ang); b[cnt] = B.point(PI + base - ang); cnt++;
    }
    return cnt;

}


int main(){
    Circle A,B;
    Point a[5],b[5];
    while(scanf("%lf%lf%lf%lf%lf%lf",&A.c.x,&A.c.y,&A.r,&B.c.x,&B.c.y,&B.r)!=EOF){
        bool flag=0;
        if(sign(A.r - B.r) < 0) flag=1;
        int cnt=getTangents(A,B,a,b);
//        printf("%d\n",cnt);
        if(cnt==-1||cnt==0) continue;
        vector<Point> v;
        for(int i=0;i<cnt;i++){
            v.push_back(a[i]);
        }
        sort(v.begin(),v.end());
        for(int i=0;i<cnt;i++){
            printf("%.10f %.10f\n",v[i].x,v[i].y);
        }
    }
    return 0;
}



Measured memory_bytes: 3608