/**** Geometrical Library (complex class version) ****/

#include<cmath>
#include<vector>
#include<complex>
#include<algorithm>

#define	pb			push_back
#define	rep(i,n)	for(int i=0;i<n;i++)

using namespace std;

typedef	complex<double>	Point;

const double EPS=1e-9;

class Line:public vector<Point>{
public:
	Line(){}
	Line(const Point &a,const Point &b){
		pb(a),pb(b);
	}
};

class Circle{
public:
	Point c;
	double r;
	Circle(){}
	Circle(const Point &C,double R):c(C),r(R){}
};

namespace std{
	bool operator <(const Point &a,const Point &b){
		return (real(a)==real(b))?(imag(a)<imag(b)):(real(a)<real(b));
	}
	bool operator >(const Point &a,const Point &b){
		return b<a;
	}
}

double dot(const Point &a,const Point &b){
	return real(a)*real(b)+imag(a)*imag(b);
}

double cross(const Point &a,const Point &b){
	return real(a)*imag(b)-imag(a)*real(b);
}

inline void calc_abc(const Line &l,double &a,double &b,double &c){	// l : ax+by+c=0
	a=imag(l[0])-imag(l[1]);
	b=real(l[1])-real(l[0]);
	c=cross(l[0],l[1]);
}

Point perp_foot(const Point &p,const Line &l){
	double a,b,c;
	calc_abc(l,a,b,c);
	Point v(a,b);
	return p-(dot(p,v)+c)*v/norm(v);
}

int intersect(const Circle &c,const Line &l,Point *p=NULL,Point *q=NULL){
	Point m=perp_foot(c.c,l);
	double d2=norm(c.c-m);
	if(c.r*c.r+EPS<d2)	return 0;
	else if(abs(c.r*c.r-d2)<EPS){
		if(p&&q)	*p=*q=m;
		return 1;
	}
	else{
		if(p&&q){
			Point v;
			double n0=norm(l[0]-m),n1=norm(l[1]-m);
			if(n0<n1)	v=l[1]-m,n0=n1;
			else		v=l[0]-m;
			v*=sqrt((c.r*c.r-d2)/n0);
			*p=m+v,*q=m-v;
		}
		return 2;
	}
}

/**************** Library END ****************/

#include<cstdio>

void addCommonTangent(vector<Line> &lns,const Circle &c1,const Circle &c2){
	double d2=norm(c1.c-c2.c);
	double rsum2=(c1.r+c2.r)*(c1.r+c2.r);
	double rdif2=(c1.r-c2.r)*(c1.r-c2.r);
	Point u=(c2.c-c1.c)/abs(c2.c-c1.c);

	Point v;
	double theta;
	if(d2>rsum2+EPS){
		theta=asin(sqrt(1-rdif2/d2));
		v=u*exp(Point(0,theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));
		v=u*exp(Point(0,-theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));

		theta=acos(sqrt(rsum2/d2));
		v=u*exp(Point(0,theta));	lns.pb(Line(c1.c+c1.r*v,c2.c-c2.r*v));
		v=u*exp(Point(0,-theta));	lns.pb(Line(c1.c+c1.r*v,c2.c-c2.r*v));
	}
	else if(d2>rsum2-EPS){
		theta=asin(sqrt(1-rdif2/d2));
		v=u*exp(Point(0,theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));
		v=u*exp(Point(0,-theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));

		v=u*Point(0,1);	lns.pb(Line(c1.r*u,c1.r*u+v));
	}
	else if(d2>rdif2+EPS){
		theta=asin(sqrt(1-rdif2/d2));
		v=u*exp(Point(0,theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));
		v=u*exp(Point(0,-theta));	lns.pb(Line(c1.c+c1.r*v,c2.c+c2.r*v));
	}
	else if(d2>rdif2-EPS){
		v=u*Point(0,1);	lns.pb(Line(c1.r*u,c1.r*u+v));
	}
}

int main(){
	for(int n;scanf("%d",&n),n;){
		Circle jwl[50],mag[50];
		rep(i,n){
			int x,y,m;	scanf("%d%d%lf%d",&x,&y,&jwl[i].r,&m);
			jwl[i].c=mag[i].c=Point(x,y);
			mag[i].r=jwl[i].r+m;
		}

		vector<Line> lns;
		rep(i,n)for(int j=i+1;j<n;j++){
			addCommonTangent(lns,jwl[i],jwl[j]);
			addCommonTangent(lns,jwl[i],mag[j]);
			addCommonTangent(lns,mag[i],jwl[j]);
			addCommonTangent(lns,mag[i],mag[j]);
		}

		int cmax=1;
		rep(i,lns.size()){
			int cnt=0;
			rep(j,n){
				if(intersect(jwl[j],lns[i])<=1 && intersect(mag[j],lns[i])>=1)	cnt++;
			}
			cmax=max(cmax,cnt);
		}
		printf("%d\n",cmax);
	}

	return 0;
}

Measured memory_bytes: 2584