#include <bits/stdc++.h>

#define PB          push_back
#define PF          push_front
#define MP          make_pair
#define FI          first
#define SE          second
#define SIZE( A )   int( ( A ).size( ) )
#define ALL( A )    ( A ).begin( ), ( A ).end( )
#define ALLR( A )   ( A ).rbegin( ), ( A ).rend( )

using namespace std;

typedef long long           ll;
typedef unsigned long long  ull;
typedef double              lf;
typedef pair< int, int >    pii;
typedef pair< ll, ll >      pll;
typedef vector< bool >      vb;
typedef vector< lf >        vd;
typedef vector< ll >        vll;
typedef vector< int >       vi;
typedef vector< pii >       vpii;

const int MAXN = int( 1e5 )+10;
const int MOD  = int( 360 );
const int oo   = INT_MAX;
const lf EPS = 1e-9;
const lf PI = acos(-1.0);

struct pt {
  lf x, y;
  pt( ) { }
  pt( lf x, lf y ) : x( x ), y ( y ) { }
};

inline lf x( pt P ) { return P.x; }
inline lf y( pt P ) { return P.y; }

istream& operator >> ( istream& in, pt& p ) {
  lf x,y; in >> x >> y;
  p = pt(x,y); return in;
}

ostream& operator << ( ostream& out, const pt& p ) {
  out << double(p.x) << " " << double(p.y);
  return out;
}

pt operator + ( const pt& A, const pt& B ) {
  return pt( x(A)+x(B), y(A)+y(B) );
}

pt operator - ( const pt& A, const pt& B ) {
  return pt( x(A)-x(B), y(A)-y(B) );
}

pt operator * ( const lf& B, const pt& A ) {
  return pt( x(A)*B, y(A)*B );
}

pt operator * ( const pt& A, const lf& B ) {
  return pt( x(A)*B, y(A)*B  );
}

pt operator * ( const pt& A, const pt& B ) {
  return pt( x(A)*x(B)-y(A)*y(B), x(A)*y(B)+y(A)*x(B) );
}

pt operator / ( const pt& A, const lf& B ) {
  return pt( x(A)/B, y(A)/B );
}

inline lf dot( pt A, pt B ) {
  return x(A)*x(B) + y(A)*y(B);
}

inline lf cross( pt A, pt B ) {
  return x(A)*y(B) - y(A)*x(B);
}

inline lf norm( pt A ) {
  return x(A)*x(A) + y(A)*y(A);
}

inline lf abs( pt A ) {
  return sqrt( norm(A) );
}

inline lf arg( pt A ) {
  return atan2( y(A), x(A) );
}

inline pt exp( pt A ) {
  return pt( exp( x(A) )*cos( y(A) ), exp( x(A) )*sin( y(A) ) ) ;
}

inline bool same ( lf a, lf b ) {
  return a+EPS > b && b+EPS > a;
}

inline bool samePt ( pt A, pt B ) {
  return same ( x(A), x(B) ) && same ( y(A), y(B) );
}

inline pt rot ( pt p, lf ang ) { return p * exp ( pt(0,1) * ang ); }

inline lf dist ( pt A, pt B ) { return abs( B - A ); }

lf distToLine (pt p, pt A, pt B, pt &c) {
  lf u = dot( p-A , B-A ) / norm( B-A );
  c = A + u*( B-A );
  return dist( p , c );
}

pt refPoint(pt X, pt A, pt B) {
  pt aux; distToLine(X, A, B, aux);
  return X + lf(2.0)*(aux-X);
}

int intersectionCircles( pt c1, lf r1, pt c2, lf r2, pt &p1, pt &p2 ) {
  if( samePt( c1, c2 ) && same(r1,r2) ) return -1;
  lf sr = (r1 + r2) * (r1 + r2);
  lf dr = (r1 - r2) * (r1 - r2);
  lf d = norm( c2-c1 );
  if( d+EPS < dr || d > sr+EPS ) return 0;
  if ( same(d,sr) || same(d,dr) ) {
    p1 = p2 = c1 + (c2-c1)/sqrt(d) * r1;
    return 1;
  }
  pt tmp;
  tmp.x = (r1*r1 - r2*r2 + d ) / (2.0*sqrt(d)) ;
  tmp.y = sqrt( r1*r1 - tmp.x*tmp.x ) ;
  lf ang = arg( c2 - c1 );
  p1 = rot( tmp, ang ) + c1;
  p2 = refPoint( p1, c1, c2 );
  return 2;
}

pt c1,c2, p1,p2;
lf r1,r2;

int main( ) {

  #ifdef LOCAL
    freopen( "input", "r", stdin );
    //freopen( "output", "w", stdout );
  #else
    //freopen( "input", "r", stdin );
    //freopen( "output", "w", stdout );
    ios_base::sync_with_stdio( 0 );
    cin.tie( 0 );
  #endif
  while( cin >> c1 >> r1 >> c2 >> r2 ) {
    if( norm( c2-c1 ) > (r1+r2)*(r1+r2) ) {
      cout << "4\n";
      continue;
    }
    if( norm( c2-c1 ) == (r1+r2)*(r1+r2) ) {
      cout << "3\n";
      continue;
    }
    int r = intersectionCircles( c1, r1, c2, r2, p1, p2 );
    if( r == 2 ) {
      cout << "2\n";
      continue;
    }
    if( r == 1 ) {
      cout << "1\n";
      continue;
    }
    cout << "0\n";
  }
  return 0;
}

Measured memory_bytes: 3620