#include <algorithm>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

const double EPS = 1e-9;
const double PI = acos(-1);

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

int dcmp(double x, double y) {
    return sign(x - y);
}

struct Vector;
typedef Vector Point;

struct Vector {
    double x;
    double y;

    explicit Vector(double x = 0, double y = 0);

    Vector operator+(const Vector &rhs) const;
    Vector operator-() const;
    Vector operator-(const Vector &rhs) const;
    Vector operator*(double d) const;
    Vector operator/(double d) const;
    double operator*(const Vector &rhs) const;
    double operator^(const Vector &rhs) const;

    bool operator==(const Vector &rhs) const;
    bool operator!=(const Vector &rhs) const;
    bool operator<(const Vector &rhs) const;
    bool operator>(const Vector &rhs) const;
    bool operator<=(const Vector &rhs) const;
    bool operator>=(const Vector &rhs) const;

    friend std::ostream &operator<<(std::ostream &os, const Vector &vector);

    double dot(const Vector &rhs) const;
    double cross(const Vector &rhs) const;
    double length() const;
    double length2() const;
    double angle() const;
    double angle(const Vector &rhs) const;
    Vector rotate(double rad) const;
    Vector rotate90() const;
    Vector normal() const;
    double getDistanceTo(const Point &p) const;

    static bool cmpByAngle(const Vector &a, const Vector &b);
};

struct Line {
    Point a;
    Point b;

    explicit Line(double x1 = 0, double y1 = 0, double x2 = 0, double y2 = 0);
    explicit Line(const Point &a = Point(), const Point &b = Point());

    double getDistanceTo(const Point &p) const;
    Point getIntersection(const Line &rhs) const;
    Point getProjection(const Point &p) const;
    Point getReflection(const Point &p) const;
    bool contains(const Point &p) const;
    bool intersects(const Line &rhs) const;
};

struct Circle {
    Point center;
    double r;

    enum class IntersectsLine {
        NOT_CROSS,
        TANGENT,
        INTERSECT
    };

    enum class IntersectsCircle {
        NOT_CROSS,
        CIRCUMSCRIBED,
        INTERSECT,
        INSCRIBED,
        INCLUDED
    };

    explicit Circle(double x = 0, double y = 0, double r = 0);
    explicit Circle(const Point &c = Point(), double r = 0);
    Circle(const Point &a, const Point &b, const Point &c);

    double area() const;
    double circumstance() const;
    Point point(double a) const;
    bool contains(const Point &p, bool onLine = true) const;
    std::vector<Point> getTangentPoints(const Point &p) const;
    std::vector<Line> getInTangents(const Circle &rhs) const;
    std::vector<Line> getExTangents(const Circle &rhs) const;
    double getDistanceTo(const Circle &rhs) const;
};


Vector::Vector(double x, double y) : x(x), y(y) {}

Vector Vector::operator+(const Vector &rhs) const {
    return Vector(x + rhs.x, y + rhs.y);
}

Vector Vector::operator-() const {
    return Vector(-x, -y);
}

Vector Vector::operator-(const Vector &rhs) const {
    return *this + -rhs;
}

Vector Vector::operator*(double d) const {
    return Vector(x * d, y * d);
}

Vector Vector::operator/(double d) const {
    return *this * (1 / d);
}

double Vector::operator*(const Vector &rhs) const {
    return x * rhs.x + y * rhs.y;
}

double Vector::operator^(const Vector &rhs) const {
    return x * rhs.y - rhs.x * y;
}

bool Vector::operator==(const Vector &rhs) const {
    return dcmp(x, rhs.x) == 0 && dcmp(y, rhs.y) == 0;
}

bool Vector::operator!=(const Vector &rhs) const {
    return !(rhs == *this);
}

bool Vector::operator<(const Vector &rhs) const {
    if (dcmp(x, rhs.x) != 0) {
        return dcmp(x, rhs.x) < 0;
    } else {
        return dcmp(y, rhs.y) < 0;
    }
}

bool Vector::operator>(const Vector &rhs) const {
    return rhs < *this;
}

bool Vector::operator<=(const Vector &rhs) const {
    return !(rhs < *this);
}

bool Vector::operator>=(const Vector &rhs) const {
    return !(*this < rhs);
}

std::ostream &operator<<(std::ostream &os, const Vector &vector) {
    os << "(" << vector.x << ", " << vector.y << ")";
    return os;
}

double Vector::dot(const Vector &rhs) const {
    return *this * rhs;
}

double Vector::cross(const Vector &rhs) const {
    return *this ^ rhs;
}

double Vector::length() const {
    return sqrt(*this * *this);
}

double Vector::length2() const {
    return *this * *this;
}

double Vector::angle() const {
    return atan2(y, x);
}

double Vector::angle(const Vector &rhs) const {
    return acos((*this * rhs) / length() / rhs.length());
}

Vector Vector::rotate(double rad) const {
    return Vector(x * cos(rad) - y * sin(rad), x * sin(rad) + y * cos(rad));
}

Vector Vector::rotate90() const {
    return Vector(-y, x);
}

Vector Vector::normal() const {
    double l = length();
    return Vector(-y / l, x / l);
}

double Vector::getDistanceTo(const Point &p) const {
    return sqrt(pow(x - p.x, 2) + pow(y - p.y, 2));
}

bool Vector::cmpByAngle(const Vector &a, const Vector &b) {
    return dcmp(a.angle(), b.angle()) < 0;
}

Line::Line(double x1, double y1, double x2, double y2) : a(x1, y1), b(x2, y2) {}

Line::Line(const Point &a, const Point &b) : a(a), b(b) {}

double Line::getDistanceTo(const Point &p) const {
    const Vector &v1 = b - a;
    const Vector &v2 = p - a;
    return fabs(v1 ^ v2 / v1.length());
}

Point Line::getIntersection(const Line &rhs) const {
    if (!intersects(rhs)) {
        return Point();
    }
    Vector u = a - rhs.a;
    Vector v = b - a;
    Vector w = rhs.b - rhs.a;
    double t = (w ^ u) / (v ^ w);
    return a + v * t;
}

Point Line::getProjection(const Point &p) const {
    const Vector &v = b - a;
    return a + v * (v * (p - a) / (v * v));
}

Point Line::getReflection(const Point &p) const {
    return getProjection(p) * 2 - p;
}

bool Line::contains(const Point &p) const {
    Point p1 = a;
    Point p2 = b;
    if (p1 == p) {
        p1 = p1 + (p2 - p1) * 2;
    } else if (p2 == p) {
        p2 = p2 + (p1 - p2) * 2;
    }
    return sign((p2 - p) ^ (p1 - p)) == 0;
}

bool Line::intersects(const Line &rhs) const {
    return dcmp((b - a).angle(), (rhs.b - rhs.a).angle()) != 0;
}

Circle::Circle(double x, double y, double r) : center(x, y), r(r) {}

Circle::Circle(const Point &c, double r) : center(c), r(r) {}

Circle::Circle(const Point &a, const Point &b, const Point &c) {
    double a1 = b.x - a.x;
    double b1 = b.y - a.y;
    double c1 = (a1 * a1 + b1 * b1) / 2;
    double a2 = c.x - a.x;
    double b2 = c.y - a.y;
    double c2 = (a2 * a2 + b2 * b2) / 2;
    double d = a1 * b2 - a2 * b1;
    center = Point(a.x + (c1 * b2 - c2 * b1) / d, a.y + (a1 * c2 - a2 * c1) / d);
    r = center.getDistanceTo(a);
}

bool Circle::contains(const Point &p, bool onLine) const {
    double dis = center.getDistanceTo(p);
    if (onLine) {
        return dcmp(dis, r) <= 0;
    } else {
        return dcmp(dis, r) < 0;
    }
}

double Circle::getDistanceTo(const Circle &rhs) const {
    return center.getDistanceTo(rhs.center);
}

Point Circle::point(double a) const {
    return Point(center.x + cos(a) * r, center.y + sin(a) * r);
}

double Circle::area() const {
    return PI * r * r;
}

double Circle::circumstance() const {
    return 2 * PI * r;
}

std::vector<Point> Circle::getTangentPoints(const Point &p) const {
    std::vector<Point> res;
    double d = center.getDistanceTo(p);
    if (contains(p, false)) {
        return res;
    } else if (contains(p, true)) {
        res.push_back(p);
        return res;
    }
    double base = (p - center).angle();
    double angle = acos(r / d);
    res.push_back(point(base + angle));
    res.push_back(point(base - angle));
    return res;
}

std::vector<Line> Circle::getInTangents(const Circle &rhs) const {
    std::vector<Line> res;
    const Point &p = (center * rhs.r + rhs.center * r) / (r + rhs.r);
    const std::vector<Point> &vec1 = getTangentPoints(p);
    const std::vector<Point> &vec2 = rhs.getTangentPoints(p);
    if (!vec1.empty() && !vec2.empty()) {
        res.emplace_back(vec1.front(), vec2.front());
        res.emplace_back(vec1.back(), vec2.back());
    }
    return res;
}

std::vector<Line> Circle::getExTangents(const Circle &rhs) const {
    std::vector<Line> res;
    if (dcmp(r, rhs.r) == 0) {
        Vector dir = rhs.center - center;
        dir = (dir * (r / dir.length())).rotate90();
        res.emplace_back(center + dir, rhs.center + dir);
        res.emplace_back(center - dir, rhs.center - dir);
    } else {
        const Point &p = (center * -rhs.r + rhs.center * r) / (r - rhs.r);
        std::vector<Point> vec1 = getTangentPoints(p);
        std::vector<Point> vec2 = rhs.getTangentPoints(p);
        if (!vec1.empty() && !vec2.empty()) {
            res.emplace_back(vec1.front(), vec2.front());
            res.emplace_back(vec1.back(), vec2.back());
        }
    }
    return res;
}


int main() {
//    freopen("data.in", "r", stdin);

    double x, y, r;
    while (~scanf("%lf%lf%lf", &x, &y, &r)) {
        Circle c1(x, y, r);
        scanf("%lf%lf%lf", &x, &y, &r);
        Circle c2(x, y, r);
        vector<Point> points;
        for (const auto &line : c1.getInTangents(c2)) {
            points.push_back(line.a);
            points.push_back(line.b);
        }
        for (const auto &line : c1.getExTangents(c2)) {
            points.push_back(line.a);
            points.push_back(line.b);
        }
        sort(points.begin(), points.end());
        points.erase(unique(points.begin(), points.end()), points.end());
        for (const auto &point : points) {
            if (c1.contains(point)) {
                printf("%.10f %.10f\n", point.x, point.y);
            }
        }
    }
    return 0;
}



Measured memory_bytes: 3696