#include <bits/stdc++.h>
#define EPS 1e-10
#define equals(a,b) (fabs((a)-(b))<EPS)
using namespace std;

class Point{
public:
	double x,y;
	Point(){}
	Point(double xx,double yy){
		x=xx;
		y=yy;
	}
	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 (a*x,a*y);
	}
	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;
struct Segment{
	Point p1,p2;
	Segment(){}
	Segment(Point pp1,Point pp2){
		p1=pp1;
		p2=pp2;
	}
};

typedef Segment Line;
class Circle{
public:
	Point c;
	double r;
	Circle(){		
	}
	Circle(Point cc,double rr){
		c=cc;
		r=rr;
	}
};

double norm(Vector v){
	return v.x*v.x+v.y*v.y;
}

double abs(Vector v){
	return sqrt(norm(v));
}

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;
}

static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;

int ccw(Point p0, Point p1, Point p2) {
	Vector a = p1 - p0;
	Vector b = p2 - p0;
	if (cross(a, b) > EPS)return COUNTER_CLOCKWISE;
	if (cross(a, b) < -EPS)return CLOCKWISE;
	if (dot(a, b) < -EPS)return ONLINE_BACK;
	if (a.norm() < b.norm())return ONLINE_FRONT;
	return ON_SEGMENT;
}

bool isParallel(Segment s1,Segment s2){
	return equals(cross(s1.p2-s1.p1,s2.p2-s2.p1),0.0);
}


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

bool intersect(Circle c,Line l){
	return c.r>=(getDistanceLP(l,c.c));
}

double arg(Vector p){
	return atan2(p.y,p.x);
}
Vector polar(double a,double r){
	return Point(cos(r)*a,sin(r)*a);
}

Point project(Segment s,Point p){
	Vector base=s.p2-s.p1;
	double r=dot(p-s.p1,base)/norm(base);
	return s.p1+base*r;
}


pair<Point,Point> getCrossPoints(Circle c,Line l){
	Vector pr=project(l,c.c);
	Vector e=(l.p2-l.p1)/abs(l.p2-l.p1);
	double base=sqrt(c.r*c.r-norm(pr-c.c));
	return make_pair(pr+e*base,pr-e*base);
}

pair<Point,Point> getCrossPoints(Circle c1,Circle c2){
	double d=abs(c1.c-c2.c);
	double a=acos((c1.r*c1.r+d*d-c2.r*c2.r))/(2.0*c1.r*d);
	double t=arg(c2.c-c1.c);
	return make_pair(c1.c+polar(c1.r,t+a),c1.c+polar(c1.r,t-a));
}

vector<Segment> getTangentLine(Circle c1,Circle c2){
	vector<Segment> res;
	if(c1.r<=0.0 || c2.r<=0.0)return res;
	if(c1.r<c2.r)swap(c1,c2);
	Point d=c2.c-c1.c;
	double cr=abs(d);
	if(cr<EPS)return res;
	double d1=c1.r-c2.r-cr;
	if(d1>EPS)return res;
	if(fabs(d1)<EPS){
		pair<Point,Point> tmp=getCrossPoints(c1,c2);
		res.push_back(Segment(tmp.first,tmp.second));
		return res;
	}
	double d3=cr-c1.r-c2.r;
	Segment s1;
	s1.p1.x=c1.r*(c1.r-c2.r)/cr;
	s1.p1.y=sqrt(c1.r*c1.r-s1.p1.x*s1.p1.x);

	s1.p2.x=c2.r*(c1.r-c2.r)/cr;
	s1.p2.y=sqrt(c2.r*c2.r-s1.p2.x*s1.p2.x);
	s1.p2.x+=cr;

	res.push_back(s1);
	s1.p1.y=-s1.p1.y;
	s1.p2.y=-s1.p2.y;
	res.push_back(s1);

	if(d3>EPS){
		Segment s2;
		s2.p1.x=c1.r*(c1.r+c2.r)/cr;
		s2.p1.y=sqrt(c1.r*c1.r-s2.p1.x*s2.p1.x);

		s2.p2.x=-c2.r*(c1.r+c2.r)/cr;
		s2.p2.y=-sqrt(c2.r*c2.r-s2.p2.x*s2.p2.x);
		s2.p2.x+=cr;

		res.push_back(s2);
		s2.p1.y=-s2.p1.y;
		s2.p2.y=-s2.p2.y;
		res.push_back(s2);
	}

	double sn=d.y/cr;
	double cs=d.x/cr;
	for(int i=0;i<res.size();i++){
		Point p;
		p.x=res[i].p1.x*cs-res[i].p1.y*sn+c1.c.x;
		p.y=res[i].p1.x*sn+res[i].p1.y*cs+c1.c.y;
		res[i].p1=p;
		p.x=res[i].p2.x*cs-res[i].p2.y*sn+c1.c.x;
		p.y=res[i].p2.x*sn+res[i].p2.y*cs+c1.c.y;
		res[i].p2=p;
	}
	return res;
}

int n;
Circle jwl[101];
double m[101];

int func(Segment s){
	int cnt=0;
	//printf("%.2f %.2f %.2f %.2f\n",s.p1.x,s.p1.y,s.p2.x,s.p2.y);
	for(int i=0;i<n;i++){
		double d=getDistanceLP(s,jwl[i].c);
		//printf("%.2f ",d);
		if(jwl[i].r-EPS<=d && d<=(jwl[i].r+m[i])+EPS){
			cnt++;
		}
	}
	//printf("\n");
	return cnt;
}


void solve(){
	for(int i=0;i<n;i++){
		scanf("%lf%lf%lf%lf",&jwl[i].c.x,&jwl[i].c.y,&jwl[i].r,&m[i]);
	}
	int res=1;
	for(int i=0;i<n;i++){
		for(int j=i+1;j<n;j++){
			for(int k=0;k<4;k++){
				if(k==1 || k==3){
					jwl[i].r+=m[i];
				}
				if(k==2 || k==3){
					jwl[j].r+=m[j];
				}
				vector<Segment> vi=getTangentLine(jwl[i],jwl[j]);
				if(k==1 || k==3){
					jwl[i].r-=m[i];
				}
				if(k==2 || k==3){
					jwl[j].r-=m[j];
				}
				for(int l=0;l<vi.size();l++){
					res=max(res,func(vi[l]));
				}
			}
		}
	}
	printf("%d\n",res);
	return;
}

int main(void){
	while(1){
		scanf("%d",&n);
		if(n==0)break;
		solve();
	}
}


Measured memory_bytes: 3160