#include<iostream>
#include<cfloat>
#include<cassert>
#include<cmath>
#include<vector>
 
using namespace std;
 
#define EPS (1e-10)
#define equals(a, b) (fabs((a) - (b)) < EPS )
#define dle(a, b) (equals(a, b) || a < b )
static const double PI = acos(-1);
double sc(double a){return sqrt(1.0-a*a);}

class Point{
public:
  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 a ){ return Point(x*a, y*a); }
  Point operator / ( double a ){ return Point(x/a, y/a); }
  double abs() { return sqrt(norm());}
  double norm() { return x*x + y*y; }
  bool operator < ( const Point &p ) const {
    return x != p.x ? x < p.x : y < p.y;
  }
  bool operator == ( const Point &p ) const {
    return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
  }
};

typedef Point Vector;
 
class Segment{
    public:
    Point p1, p2;
    Segment(Point s = Point(), Point t = Point()): p1(s), p2(t){}
};
typedef Segment Line;
 
double norm( Vector a ){ return a.x*a.x + a.y*a.y; }
double abs( Vector a ){ return sqrt(norm(a)); }
double getDistance( Vector a, Vector b ){ return abs(a - b); }
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; }
Point rotate( Point a, double si,double co){
  return Point(a.x*co-a.y*si,a.x*si+a.y*co);
}
Point rotate( Point a, double n){
  return Point( a.x*cos(n)-a.y*sin(n) , a.x*sin(n)+a.y*cos(n) );
}

Point getCrossPointCC(Point p1,double r1,Point p2,double r2){
  double a=r2,b=r1,c=getDistance(p1,p2);
  double cos_A = (b*b+c*c-a*a) / (2.0*b*c);
  double sin_A = sqrt(1.0-cos_A*cos_A);
  Vector v=p2-p1;
  v = v * r1 / c;
  return p1+rotate(v,sin_A,cos_A);
}

Segment getSegmentCC(Point p1,double r1,Point p2,double r2,bool flg=false){
  double b=getDistance(p1,p2),c=r1+r2;
  double a=sqrt(b*b-c*c);
  double cos_A=(b==0?1:c/b),sin_A=(b==0?0:a/b);

  if(flg)sin_A=-sin_A;
  
  Vector v1 = (p2-p1),v2 = (p1-p2);
  v1 = v1 * r1 / b;
  v1 = rotate(v1,sin_A,cos_A);
  v2 = v2 * r2 / b;
  v2 = rotate(v2,sin_A,cos_A);
  return Segment(p1+v1,p2+v2);
}

Segment getSegmentCC2(Point p1,double r1,Point p2,double r2,bool flg=false){
  if(r1>r2){
    swap(p1,p2);
    swap(r1,r2);
  }
  double c=abs(r1-r2),b=getDistance(p1,p2);
  double a=sqrt( b*b - c*c );

  double cos_A=c/b,sin_A=a/b;
  if(flg)sin_A=-sin_A;

  Vector v1 = p1-p2;
  v1 = v1 * r1 / b;
  v1 = rotate( v1, sin_A,cos_A);
  Vector v2 = v1 * r2 / r1;
  return Segment(p1+v1,p2+v2);
}

double getDistanceLP(Line s,Point p){
  return abs(cross(s.p2-s.p1,p-s.p1)/abs(s.p2-s.p1));
}

int N;
Point t[50];
double r[50],m[50];
vector<Segment> segments;
int check(Segment);

int main(){
  while(cin>>N&&N){
    segments.clear();
    for(int i=0;i<N;i++){
      cin>>t[i].x>>t[i].y>>r[i]>>m[i];
      m[i]+=r[i];
      for(int j=0;j<i;j++){

	segments.push_back(getSegmentCC(t[i],m[i],t[j],m[j]));
	segments.push_back(getSegmentCC(t[i],m[i],t[j],m[j],true));
	segments.push_back(getSegmentCC2(t[i],m[i],t[j],m[j]));
	segments.push_back(getSegmentCC2(t[i],m[i],t[j],m[j],true));
	
	segments.push_back(getSegmentCC(t[i],r[i],t[j],r[j]));
	segments.push_back(getSegmentCC(t[i],r[i],t[j],r[j],true));
	segments.push_back(getSegmentCC2(t[i],r[i],t[j],r[j]));
	segments.push_back(getSegmentCC2(t[i],r[i],t[j],r[j],true));
	

      }
    }
    if(N==1){
      cout<<"1"<<endl;
      continue;
    }
    int ans=0;
    for(int i=0;i<(int)segments.size();i++){
      Segment s = segments[i];

      ans=max(ans,check(s));
    }
    cout<<ans<<endl;
  }
  return 0;
}


int check(Segment s){
  int res=0;
  for(int i=0;i<N;i++){
    double d = getDistanceLP(s,t[i]);
    if( r[i]<EPS+d && d< EPS+m[i] )res++;
  }
  return res;
}

Measured memory_bytes: 1704