// WA!
/* Header {{{ */
#include <bits/stdc++.h>
using namespace std;

typedef long long readtype;
typedef long long var;
typedef long double let;

readtype read() {
  readtype a = 0, c = getchar(), s = 0;
  while (!isdigit(c)) s |= c == '-', c = getchar();
  while (isdigit(c)) a = a * 10 + c - 48, c = getchar();
  return s ? -a : a;
}

#ifdef LOCAL_LOGGER
#define logger(...) fprintf(stderr, __VA_ARGS__)
#define abortif(v, ...) if (v) {logger("Error in Line %d, Function '%s()'.\nInfo: ", __LINE__, __FUNCTION__); logger(__VA_ARGS__); exit(0);}
#else
#define logger(...);
#define abortif(v, ...);
#endif
/* }}} */

const let eps = 1e-8;

int sign(let x) { return (x < -eps) ? -1 : (x > eps ? 1 : 0); }

struct Point {
  let x, y;
  friend bool operator < (Point a, Point b) {
    if (sign(a.x - b.x) == 0) return sign(a.y - b.y) < 0;
    return sign(a.x - b.x) < 0;
  }
  friend Point operator + (Point a, Point b) {
    return (Point) {a.x + b.x, a.y + b.y};
  }
  friend Point operator - (Point a, Point b) {
    return (Point) {a.x - b.x, a.y - b.y};
  }
  Point operator ~ () {
    return (Point) {x, -y};
  }

  friend let Dist(Point a, Point b) { return (b - a).dist(); }

  let dist() {
    return sqrt(x * x + y * y);
  }

  Point Rotate(let sink, let cosk) {
    return (Point) {
      x * cosk - y * sink, x * sink + y * cosk
    };
  }
  
  Point Rotate(Point v) {
    let z = v.dist();
    if (!z) return *this;
    return Rotate(v.y / z, v.x / z);
  }

  void EchoWith(char c) {
    printf("%.8Lf %.8Lf", x, y);
    putchar(c);
  }
};

typedef Point Vec;

struct Segment {
  Point s, e;
  Vec v;
  Segment() {}
  Segment(Point a, Point b) { 
    s = a, e = b, v = b - a;
  }
  Segment(Point a, Point b, Vec c) { 
    s = a, e = b, v = c;
  }

  Segment Rotate(let sink, let cosk) {
    return (Segment) {
      s.Rotate(sink, cosk), e.Rotate(sink, cosk), v.Rotate(sink, cosk)
    };
  }

  Segment Rotate(Vec v) {
    let z = v.dist();
    return Rotate(v.y / z, v.x / z);
  }

  Segment operator + (Vec k) {
    return (Segment) {
      s + k, e + k, v
    };
  }
  Segment operator - (Vec k) {
    return (Segment) {
      s - k, e - k, v
    };
  }
};

struct Circle {
  Point o;
  let r;
};

Vec SideDelta(let y, let d) {
  return (Vec) {sqrt(d * d - y * y), y};
}

Segment MoveCutX(Point a, Point b, Point an, Point bn) {
  Vec ov = b - a, tv = bn - an, dx = a - an;

  Segment s = (Segment) {
    (Point) {an.x, 0}, (Point) {bn.x, 0}
  };

  // printf("S: "), s.v.EchoWith('\n');
  // s.s.EchoWith('|'), s.e.EchoWith('\n');

  s = s - an;

  // printf("S: "), s.v.EchoWith('\n');
  // s.s.EchoWith('|'), s.e.EchoWith('\n');
  // printf("Tv: "), tv.EchoWith('\n');
  
  s = s.Rotate(~tv);

  // printf("S: "), s.v.EchoWith('\n');
  // s.s.EchoWith('|'), s.e.EchoWith('\n');
  // printf("Ov: "), ov.EchoWith('\n');
  
  s = s.Rotate(ov);

  // printf("S: "), s.v.EchoWith('\n');
  // s.s.EchoWith('|'), s.e.EchoWith('\n');
  // printf("Dx: "), dx.EchoWith('\n');

  s = s + dx + an;

  // printf("S: "), s.v.EchoWith('\n');
  // s.s.EchoWith('|'), s.e.EchoWith('\n');
  // puts("");
  return s;
}

vector<Point> CommonTangent(Circle c1, Circle c2) {
  vector<Point> res;
  Vec v = c2.o - c1.o;
  Point p = (c2.o - c1.o).Rotate(~v);
  let r1 = c1.r, r2 = c2.r;
  if (sign(p.x + r2 - r1) < 0 && (p.x - r2 + r1) > 0) {
    // 内含
    return res;
  }
  if (sign(p.x + r2 - r1) > 0 && (p.x - r2 + r1) < 0) {
    // 内含
    return res;
  }
  if (sign(p.x + r2 - r1) == 0) {
    // 右内切
    Point rp = ((Point) {r1, 0}).Rotate(v) + c1.o;
    res.push_back(rp);
    return res;
  }
  if (sign(p.x - r2 + r1) == 0) {
    // 左内切
    Point rp = ((Point) {-r1, 0}).Rotate(v) + c1.o;
    res.push_back(rp);
    return res;
  }

  // 上下公切线
  let d = Dist(c1.o, c2.o);
  Point un = (Point) {0, r1} + SideDelta(r2 - r1, d),
        dn = (Point) {0, -r1} + SideDelta(-r2 - (-r1), d);

  Point up = MoveCutX(c1.o, c2.o, (Point) {0, r1}, un).s,
        dp = MoveCutX(c1.o, c2.o, (Point) {0, -r1}, dn).s;
  res.push_back(up);
  res.push_back(dp);

  if (sign(p.x - r2 - r1) == 0) {
    // 右外切
    Point rp = ((Point) {r1, 0}).Rotate(v) + c1.o;
    res.push_back(rp);
    return res;
  }
  if (sign(p.x + r2 + r1) == 0) {
    // 左外切
    Point rp = ((Point) {-r1, 0}).Rotate(v) + c1.o;
    res.push_back(rp);
    return res;
  }

  if (sign(p.x - r2 - r1) > 0 || sign(p.x + r2 + r1) < 0) {
    // 相离
    Point udn = (Point) {0, r1} + SideDelta(-r2 - r1, d),
          dun = (Point) {0, -r1} + SideDelta(r2 - (-r1), d);
    Point udp = MoveCutX(c1.o, c2.o, (Point) {0, r1}, udn).s,
          dup = MoveCutX(c1.o, c2.o, (Point) {0, -r1}, dun).s;
    res.push_back(udp);
    res.push_back(dup);
    return res;
  }

  // 相交
  return res;
}

Point ReadPoint() {
  Point p;
  scanf("%Lf%Lf", &p.x, &p.y);
  return p;
}

Circle ReadCircle() {
  Point p = ReadPoint();
  let c;
  scanf("%Lf", &c);
  return (Circle) {p, c};
}

int main() {
// #ifndef ONLINE_JUDGE
//   freopen("CGL_7_G.in", "r", stdin);
//   freopen("CGL_7_G.out", "w", stdout);
// #endif
// #ifdef LOCAL_LOGGER
//   freopen("CGL_7_G.log", "w", stderr);
// #endif
  Circle c1 = ReadCircle(), c2 = ReadCircle();
  vector<Point> res = CommonTangent(c1, c2);
  sort(res.begin(), res.end());
  for (size_t i = 0; i < res.size(); ++i)
    res[i].EchoWith('\n');
  return 0;
}

/* ==== Makefile ==== {{{
CompileAndRun:
	make Compile
	make Run

Compile:
	g++ -o CGL_7_G CGL_7_G.cpp -g -Wall -DLOCAL_LOGGER

CompileUF:
	g++ -o CGL_7_G CGL_7_G.cpp -g -Wall -DLOCAL_LOGGER -fsanitize=undefined

Run:
	./CGL_7_G < CGL_7_G.in > CGL_7_G.out
==================
}}} */



Measured memory_bytes: 3296