#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


//#define EPS 0.0001

enum Type{
	Small,
	Large,
};

struct Point{
    Point(double arg_x,double arg_y){
        x = arg_x;
        y = arg_y;
    }

    Point(){
        x = y = 0.0;
    }

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

    double x,y;
};

typedef Point Vector;

struct Sphere{
    Point center;
    double r,power;
};

typedef Sphere Circle;

struct Line{
public:
    Point p[2];
    Line(Point p1,Point p2){
        p[0] = p1;
        p[1] = p2;
    }
    Line(){

    }
};

int N;
double NUM = 10000;
Circle circle[55][2];

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

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

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

Point project(Line l,Point p){

    Vector base = l.p[1]-l.p[0];
    double r = dot(p-l.p[0],base)/norm(base);
    return l.p[0]+base*r;
}

//円と直線の交点を求める関数
vector<Point> getCrossPoints(Circle c,Line l){

    vector<Point> ret;

    Vector pr = project(l,c.center);
    Vector e = (l.p[1]-l.p[0])/abs(l.p[1]-l.p[0]);

    double base;

    if(fabs(c.r*c.r-norm(pr-c.center)) < EPS){

        base = 0;
    }else{
        base = sqrt(c.r*c.r-norm(pr-c.center));
    }

    ret.push_back(Point(pr+e*base));
    ret.push_back(Point(pr-e*base));

    return ret;
}

vector<Point> getContact(Circle circle,Point point){

    double k = circle.center.x - point.x;
    double X = point.y - circle.center.y;

    double A = k*k - circle.r*circle.r;

    if(fabs(A) < EPS){

        double slope = (circle.r*circle.r-X*X)/(2*k*X);

        if(fabs(slope) < EPS){

            vector<Point> ret;

            ret.push_back(Point(point.x,sqrt(circle.r*circle.r-(point.x-circle.center.x)*(point.x-circle.center.x))+circle.center.y));
            ret.push_back(Point(sqrt(circle.r*circle.r-(point.y-circle.center.y)*(point.y-circle.center.y))+circle.center.x,point.y));

            return ret;
        }

        Line line;

        line.p[0] = point;
        line.p[1] = Point(point.x+NUM,point.y+NUM*slope);

        return getCrossPoints(circle,line);
    }

    double B = 2*k*X;
    double C = X*X - circle.r*circle.r;

    double slope_1 = (-B+sqrt(B*B-4*A*C))/(2*A);
    double slope_2 = (-B-sqrt(B*B-4*A*C))/(2*A);

    Line line_1,line_2;

    line_1.p[0] = point;
    line_1.p[1] = Point(point.x+NUM,point.y+NUM*slope_1);
    vector<Point> ret_1 = getCrossPoints(circle,line_1);

    line_2.p[0] = point;
    line_2.p[1] = Point(point.x+NUM,point.y+NUM*slope_2);

    vector<Point> ret_2 = getCrossPoints(circle,line_2);

    vector<Point> ret;

    ret.push_back(ret_1[0]);
    ret.push_back(ret_2[0]);

    return ret;
}


vector<Line> getCommonTangent(Circle C1,Circle C2){

	vector<Point> POINT;
	vector<Line> ret;


	double p = C2.center.x-C1.center.x;
	double q = C2.center.y-C1.center.y;

	double A = p*p+q*q;

	double n_1 = (q*C1.r*(C1.r+C2.r)-p*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.y;
	double n_2 = (q*C1.r*(C1.r+C2.r)+p*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.y;

	double m_1 = (p*C1.r*(C1.r+C2.r)+q*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.x;
	double m_2 = (p*C1.r*(C1.r+C2.r)-q*C1.r*sqrt(A-(C1.r+C2.r)*(C1.r+C2.r)))/(A)+C1.center.x;

	if(A-(C1.r+C2.r)*(C1.r+C2.r) >= 0){
		POINT.push_back(Point(m_1,n_1));
		POINT.push_back(Point(m_2,n_2));

		for(int i = 0; i < 2; i++){

			Point another = getContact(C2,POINT[i])[0];
			ret.push_back(Line(POINT[i],another));

			another = getContact(C2,POINT[i])[1];
			ret.push_back(Line(POINT[i],another));
		}

		POINT.clear();
	}

	double n_3 = (q*C1.r*(C1.r-C2.r)-p*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.y;
	double n_4 = (q*C1.r*(C1.r-C2.r)+p*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.y;

	double m_3 = (p*C1.r*(C1.r-C2.r)+q*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.x;
	double m_4 = (p*C1.r*(C1.r-C2.r)-q*C1.r*sqrt(A-(C1.r-C2.r)*(C1.r-C2.r)))/(A)+C1.center.x;

	if(A-(C1.r-C2.r)*(C1.r-C2.r) >= 0){
		POINT.push_back(Point(m_3,n_3));
		POINT.push_back(Point(m_4,n_4));

		for(int i = 0; i < 2; i++){

			Point another = getContact(C2,POINT[i])[0];
			ret.push_back(Line(POINT[i],another));

			another = getContact(C2,POINT[i])[1];
			ret.push_back(Line(POINT[i],another));
		}

		POINT.clear();
	}
	return ret;
}



void func(){

	for(int i = 0; i < N; i++){

		scanf("%lf %lf %lf %lf",&circle[i][Small].center.x,&circle[i][Small].center.y,&circle[i][Small].r,&circle[i][Small].power);

		circle[i][Large].center = circle[i][Small].center;
		circle[i][Large].r = circle[i][Small].r+circle[i][Small].power; //磁力の大きさを加えた場合
	}

	if(N == 1){
		printf("1\n");
		return;
	}

	vector<Line> LINE;
	vector<Line> tmp_line;

	Type type[2] = {Small,Large};

	for(int i = 0; i < N; i++){
		for(int k = 0; k < N; k++){
			if(k == i)continue;

			for(int a = 0; a < 2; a++){
				for(int b = 0; b < 2; b++){

					tmp_line = getCommonTangent(circle[i][type[a]],circle[k][type[b]]);

					if(tmp_line.size() == 0)continue;

					for(int c = 0; c < tmp_line.size(); c++){
						LINE.push_back(tmp_line[c]);
					}
					tmp_line.clear();
				}
			}
		}
	}

	int ans = 0;

	for(int i = 0; i < LINE.size(); i++){
		int count = 0;

		for(int a = 0; a < N; a++){

			double tmp_dist = getDistanceLP(LINE[i],circle[a][Small].center)-circle[a][Small].r;

			if(EPS+tmp_dist >= 0 && tmp_dist <= circle[a][Small].power+EPS){

				count++;
			}

		}
		ans = max(ans,count);
	}

	printf("%d\n",ans);
}

int main(){

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}

    return 0;
}



Measured memory_bytes: 9524