#include <bits/stdc++.h>
//#include "GC_template.h"
using namespace std;

namespace CG{
    const double eps = 1e-8;
    int sgn(double x) {
        if (x < -eps) return -1;
        if (x > eps) return 1;
        return 0;
    }

    struct point {
        double x, y;
        point() = default;
        point(double x, double y) : x(x), y(y) {}
        point(const point &) = default;
    };

    typedef point vector;

    point operator + (const point &A, const vector &B) {return point(A.x+B.x,A.y+B.y);}
    vector operator - (const point &A, const point &B) {return vector(A.x-B.x,A.y-B.y);}
    double operator * (const vector &A, const vector &B) {return A.x*B.x+A.y*B.y;}
    vector operator * (const vector &A, double r) {return vector(A.x*r,A.y*r);}
    vector operator * (double r, const vector &A) {return vector(A.x*r,A.y*r);}
    vector operator / (const vector &A, double r) {return vector(A.x/r,A.y/r);}
    double cross (const vector &A, const vector &B) {return A.x*B.y-A.y*B.x;}

    double sqr(double x) {return x*x;}
    double sqr_length(const vector &A) {return sqr(A.x)+sqr(A.y);}
    double length(const vector &A) {return sqrt(sqr_length(A));}
    double sqr_dist(const point &A,const point &B) {return sqr(A.x-B.x)+sqr(A.y-B.y);}
    double dist(const point &A,const point &B) {return sqrt(sqr_dist(A,B));}
    vector rot(const vector &A,double theta) {return vector(A.x*cos(theta)-A.y*sin(theta),A.x*sin(theta)+A.y*cos(theta));}
    vector lerp(const vector &A, const vector &B, double t) {return A*(1-t)+B*t;}
    bool quadartic(double A, double B, double C,std::vector<double> &vec) {
        double det = sqr(B) - 4*A*C;
        if(det < 0) return 0;
        if(sgn(det) == 0) vec.push_back(-B/(2*A));
        else {
            vec.push_back((-B-sqrt(det))/(2*A));
            vec.push_back((-B+sqrt(det))/(2*A));
            if(A<0) std::swap(vec[0],vec[1]);
        }
        return 1;
    }

    struct segment {
        point a, b;
        vector v;
        segment() = default;
        segment(const point &a, const point &b) : a(a), b(b), v(b - a) {};
        segment(const segment &) = default;
    };

    typedef segment line;

    bool point_in_segment(const point &p, const segment &s) {
        return sgn(cross(s.b-s.a,p-s.a)) == 0 && sgn((p-s.a)*(p-s.b)) <= 0;
    }

    struct circle {
        point O;
        double r;
        circle() = default;
        circle(const point &O, double r) : O(O), r(r) {};
        circle(const circle &) = default;
    };
    const double pi = acos(-1);

    int get_tangents(const point &p, const circle &cir, std::vector<line> &vec) {
        vector u = p-cir.O;
        double l = dist(p,cir.O);
        if(sgn(l-cir.r) < 0) return 0;
        if(sgn(l-cir.r) == 0) {
            vec.emplace_back(p,p+rot(u,pi/2));
            return 1;
        }
        double theta = asin(cir.r/l);
        vec.emplace_back(p,p+rot(u,theta));
        vec.emplace_back(p,p+rot(u,-theta));
        return 2;
    }

    int get_tangents(circle A, circle B, std::vector<line> &vec) {
        if (A.r < B.r) std::swap(A, B);
        double l = dist(A.O, B.O);
        if (sgn(l) == 0 && sgn(A.r - B.r) == 0) return -1;
        if (sgn(A.r - B.r - l) > 0) return 0;
        if (sgn(A.r - B.r - l) == 0) {
            vec.emplace_back(lerp(A.O, B.O, A.r / l), rot(B.O - A.O, pi / 2));
            return 1;
        }

        {
            double theta = acos((A.r - B.r) / l);
            vector unit = (A.O - B.O) / l;
            vec.emplace_back(A.O + (A.r * rot(unit, theta)), B.O + (B.r * rot(unit, theta)));
            vec.emplace_back(A.O + (A.r * rot(unit, -theta)), B.O + (B.r * rot(unit, -theta)));
        }

        {
            if (sgn(A.r + B.r - l) > 0) return 2;
            if (sgn(A.r + B.r - l) == 0) {
                vec.emplace_back(lerp(A.O, B.O, A.r / l), rot(A.O - B.O, pi / 2));
                return 3;
            }
            double theta = acos((A.r + B.r) / l);
            vector unit = (A.O - B.O) / l;
            vec.emplace_back(A.O + (A.r * rot(unit, theta)), B.O + (B.r * rot(unit, theta)));
            vec.emplace_back(A.O + (A.r * rot(unit, -theta)), B.O + (B.r * rot(unit, -theta)));
            return 4;
        }
    }

    int circle_line_intersection(const circle &c, const line &l,std::vector<point> &vec) {
        vector d = l.v;
        double A = d * d, B = d * (l.a - c.O) * 2, C = sqr_dist(l.a, c.O) - sqr(c.r);
        std::vector<double> vect;
        int t = quadartic(A, B, C, vect);
        if (t == 0) return 0;
        for (auto v : vect)
            vec.emplace_back(lerp(l.a, l.b, v));
        return t;
    }

    int circle_circle_intersection(circle A, circle B,std::vector<point> &vec) {
        if (A.r < B.r) std::swap(A, B);
        double l = dist(A.O, B.O);
        if (sgn(l) == 0) {
            if (sgn(A.r - B.r) == 0) return -1;
            else return 0;
        }
        if (sgn(A.r + B.r - l) < 0 || sgn(A.r - B.r - l) > 0) return 0;
        double theta = acos((sqr(A.r) + sqr(l) - sqr(B.r)) / (2 * A.r * l));
        if (sgn(A.r + B.r - l) == 0) {
            vec.emplace_back(lerp(A.O, B.O, A.r / l));
            return 1;
        }
        vector unit = (A.O - B.O) / l;
        vec.emplace_back(A.r * rot(unit, theta));
        vec.emplace_back(A.r * rot(unit, -theta));
    }
}


int main() {
    CG::circle A,B;
    double a,b,c;
    cin >> a >> b >> c;
    A.O = CG::point(a,b);A.r = c;
    cin >> a >> b >> c;
    B.O = CG::point(a,b);B.r = c;
    vector<CG::line> vec;
    cout << CG::get_tangents(A,B,vec) << endl;
    return 0;
}


Measured memory_bytes: 3688