#include <iostream>
#include <cstdio>
#include <vector>
#include <complex>
#include <cmath>
#include <algorithm>
using namespace std;

const double EPS = 1e-8;
const double PI = acos(-1.0);

bool equal(double a, double b) { return fabs(a - b) < EPS; }

// テァツつケテ」ツつッテ」ツδゥテ」ツつケ
struct P {
	double x, y;
	P(double x_, double y_) { x = x_; y = y_; }
	P(){}
	// テ・ツ環?ァツョツ? テヲツクツ崚ァツョツ? テ」ツつケテ」ツつォテ」ツδゥテ」ツδシテ・ツ??
	P operator+(const P& a) const {
		return P(x + a.x, y + a.y);
	}
	P operator-(const P& a) const {
		return P(x - a.x, y - a.y);
	}
	P operator*(const P& a) const {
		return P(x * a.x - y * a.y, x * a.y + y * a.y);
	}
	P operator*(double c) const {
		return P(x * c, y * c);
	}
	P operator/(const P& a) const {
		double norm = a.x * a.x + a.y * a.y;
		double x_ = (x * a.x + y * a.y) / norm;
		double y_ = (y * a.x - x * a.y) / norm;
		return P(x_, y_);
	}
	P operator/(double c) const {
		return P(x / c, y / c);
	}
	P& operator+=(const P& a) {
		x += a.x; y += a.y;
	}
	P& operator-=(const P& a) {
		x -= a.x; y -= a.y;
	}
	P& operator*=(const P& a) {
		*this = P(x * a.x - y * a.y, x * a.y + y * a.y);
	}
	P& operator*=(double c) {
		*this = P(x * c, y * c);
	}
	P& operator/=(const P& a) {
		double norm = a.x * a.x + a.y * a.y;
		double x_ = (x * a.x + y * a.y) / norm;
		double y_ = (y * a.x - x * a.y) / norm;
		*this = P(x_, y_);
	}
	P& operator/=(double c) {
		*this = P(x / c, y / c);
	}
};
P operator*(double c, P a){
	return P(a.x * c, a.y * c);
}
// テヲツッツ氾ィツシツεヲツシツ氾ァツョツ療・ツュツ?
bool operator==(const P& a, const P& b) {
	return equal(a.x, b.x) && equal(a.y, b.y);
}
bool operator!=(const P& a, const P& b) {
	return !(a == b);
}
bool operator<(const P& a, const P& b) {
	return (a.x != b.x)? a.x < b.x : a.y < b.y;
}

// テ・ツ篠淌ァツつケテ」ツ?凝」ツつ嘉」ツ?ョティツキツ敕ゥツ崢「(テァツオツカテ・ツッツセテ・ツ?、)
double abs(P a) {
	return sqrt(a.x * a.x + a.y * a.y);
}
// 2テァツつケテゥツ鳴禿」ツ?ョティツキツ敕ゥツ崢「
double abs(P a, P b) {
	return abs(a - b);
}
// テ」ツδ偲」ツδォテ」ツδ?
double norm(const P& z){
	return z.x * z.x + z.y * z.y;
}
// テ・ツ?湘ィツァツ?
double arg(const P& z) {
	return atan2(z.y, z.x);
}
// テ」ツδ凖」ツつッテ」ツδ暗」ツδォ a テ」ツ?ョテ・ツ債佚、ツスツ催」ツδ凖」ツつッテ」ツδ暗」ツδォテ」ツつ津ヲツアツづ」ツつ?」ツつ?
P unit(P a) {
	return a / abs(a);
}
// テ」ツδ凖」ツつッテ」ツδ暗」ツδォ a テ」ツ?ョテヲツウツ陛ァツキツ堙」ツδ凖」ツつッテ」ツδ暗」ツδォテ」ツつ津ヲツアツづ」ツつ?」ツつ?
vector<P> normal(P a) {
	vector<P> vp;
	vp.push_back( a * P(0, +1) );
	vp.push_back( a * P(0, -1) );
	return vp;
}
// テ・ツ??ァツゥツ?(dot product) : aテ」ツδサb = |a||b|cosテ篠?
double dot(P a, P b) {
	return a.x * b.x + a.y * b.y;
}
// テ・ツ、ツ姪ァツゥツ?(cross product) : aテδ傭 = |a||b|sinテ篠?
double cross(P a, P b) {
	return a.x * b.y - a.y * b.x;
}

// CCW : テ・ツ渉催ヲツ卍づィツィツ暗・ツ崢榲」ツつ?(Counter Clock Wise)
// CW : テヲツ卍づィツィツ暗・ツ崢榲」ツつ?(Clock Wise)
enum {CCW=1, CW=-1, ON=0};
// * 3テァツつケテ」ツ?古」ツ?ゥテ」ツ?。テ」ツつ嘉・ツ崢榲」ツつ甘」ツ?ァテ」ツ?づ」ツつ凝」ツ?凝ィツソツ氾」ツ?? 3テァツつケテ」ツ??テァツ崢エテァツキツ堙」ツ?ォテ、ツケツ療」ツ?」テ」ツ?ヲテ」ツ??」ツつ凝」ツ?ィテ」ツ?催」ツ?ッ ON テ」ツつ津ィツソツ氾」ツ??
int ccw(const P &a, P b, P c) {
	b -= a, c -= a;
	if( cross(b,c) >  EPS ) return CCW; // CCW : テ・ツ渉催ヲツ卍づィツィツ暗・ツ崢榲」ツつ?
	if( cross(b,c) < -EPS ) return CW;  // CW : テヲツ卍づィツィツ暗・ツ崢榲」ツつ?
	if( dot(b, c)  < -EPS ) return +2;  // c--a--b on line
	if( dot(b, b)  + EPS < dot(c, c) ) return -2; // a--b--c on line 
	return ON;
}

// テ・ツ篠淌ァツつケテ」ツつ津ィツサツクテ」ツ?ォテァツつケ p テ」ツつ津ィツァツ津・ツコツヲ a (テ」ツδゥテ」ツつクテ」ツつ「テ」ツδウ)テ」ツ??」ツ?妥・ツ崢榲ィツサツ「テ」ツ?陛」ツ?崚」ツ?淌ァツつケテ」ツつ津ィツソツ氾」ツ??
P rot(P p, double a){
	return P(p.x * cos(a) - p.y * sin(a), p.x * sin(a) + p.y * cos(a));
}
// テァツつケ a テ」ツつ津ィツサツクテ」ツ?ォテァツつケ b テ」ツつ津ィツァツ津・ツコツヲ angle (テ」ツδゥテ」ツつクテ」ツつ「テ」ツδウ)テ」ツ??」ツ?妥・ツ崢榲ィツサツ「テ」ツ?陛」ツ?崚」ツ?淌ァツつケテ」ツつ津ィツソツ氾」ツ??
P rot(P a, P b, double angle){
	return rot(b - a, angle) + a;
}

// テァツ崢エテァツキツ堙」ツつッテ」ツδゥテ」ツつケ
struct Line : public vector<P> {
	Line(){}
	Line(const P& a, const P& b) {
		push_back(a); push_back(b);
	}
};

// テァツ崢エテァツキツ?a テ」ツ?ィテァツ崢エテァツキツ?b テ」ツ?ョテ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool intersectLL(const Line& a, const Line& b) {
	return abs(cross(a[1] - a[0], b[1] - b[0])) > EPS || abs(cross(a[1] - a[0], b[0] - a[0])) < EPS;
}
// テァツ崢エテァツキツ?l テ」ツ?ィ テァツキツ堙・ツ按?s テ」ツ?ョテ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool intersectLS(const Line& l, const Line& s) {
	return cross(l[1] - l[0], s[0] - l[0]) * cross(l[1] - l[0], s[1] - l[0]) < EPS;
}
// テァツ崢エテァツキツ?l テ、ツクツ甘」ツ?ォテァツつケ p テ」ツ?古」ツ?づ」ツつ凝」ツ?凝」ツ?ゥテ」ツ??」ツ??
bool intersectLP(const Line& l, const P& p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
// テァツキツ堙・ツ按?s テ」ツ?ィ テァツキツ堙・ツ按?t テ」ツ?ョテ、ツコツ、テ・ツキツョテ・ツ按、テ・ツョツ?
bool intersectSS(const Line& s, const Line& t) {
	return ccw(s[0], s[1], t[0]) * ccw(s[0], s[1], t[1]) <= 0 &&
		   ccw(t[0], t[1], s[0]) * ccw(t[0], t[1], s[1]) <= 0;
}
// テァツキツ堙・ツ按?s テ、ツクツ甘」ツ?ォテァツつケ p テ」ツ?古」ツ?づ」ツつ凝」ツ?凝」ツ?ゥテ」ツ??」ツ??
bool intersectSP(const Line& s, const P& p) {
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS;
}

P projection(const Line& l, const P& p) {
	double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + (l[0] - l[1]) * t;
}
P reflection(const Line& l, const P& p) {
	return p + 2 * (projection(l, p) - p);
}
// テァツ崢エテァツキツ堙」ツ?ィテァツつケテ」ツ?ョティツキツ敕ゥツ崢「
double distanceLP(const Line& l, const P& p) {
	return abs(p - projection(l, p));
}
// テァツ崢エテァツキツ堙」ツ?ィテァツ崢エテァツキツ堙」ツ?ョティツキツ敕ゥツ崢「
double distanceLL(const Line& l, const Line& m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
// テァツ崢エテァツキツ堙」ツ?ィテァツキツ堙・ツ按?」ツ?ョティツキツ敕ゥツ崢「
double distanceLS(const Line& l, const Line& s) {
	if (intersectLS(l, s)) return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
// テァツキツ堙・ツ按?」ツ?ィテァツつケテ」ツ?ョティツキツ敕ゥツ崢「
double distanceSP(const Line& s, const P& p) {
	const P r = projection(s, p);
	if (intersectSP(s, r)) return abs(r - p);
	return min(abs(s[0] - p), abs(s[1] - p));
}
// テァツキツ堙・ツ按?」ツ?ィテァツキツ堙・ツ按?」ツ?ョティツキツ敕ゥツ崢「
double distanceSS(const Line& s, const Line& t) {
	if (intersectSS(s, t)) return 0;
	double a = min(distanceSP(s, t[0]), distanceSP(s, t[1]));
	double b = min(distanceSP(t, s[0]), distanceSP(t, s[1]));
	return min(a, b);
}
// テ・ツ??」ツつッテ」ツδゥテ」ツつケ
struct Circle{
	P p;
	double r;
	Circle(P p_, double r_) { p = p_; r = r_; }
};

// 2テ」ツ?、テ」ツ?ョテ・ツ??」ツ?古、ツコツ、テ」ツつ湘」ツつ凝」ツ?凝」ツ?ゥテ」ツ??」ツ??
int is_intersect(const Circle &a, const Circle &b) {
	double x = a.p.x - b.p.x;
	double y = a.p.y - b.p.y;
	double s = a.r + b.r;
	double d = x * x + y * y;
	s *= s;
	if( equal(d, s) ) return 1;
	if( d > s ) return 0;
	double r = abs(a.r - b.r);
	r *= r;
	if( equal(d, r) ) return -1;
	if(d > r) return 2;
	return -2;
}

// 2テ」ツ?、テ」ツ?ョテ・ツ??」ツ?ョテ・ツ?アテゥツ?堙ヲツ篠・テァツキツ堙」ツつ津ヲツアツづ」ツつ?」ツつ?(テァツオツ静ヲツ楪愿」ツ?ッ res テ」ツ?ォティツソツ氾」ツ??
void common_tangent(Circle a, Circle b, vector<Line> &res) {
	if(a.r > b.r) swap(a, b);
	double d = abs(b.p - a.p);
	double th;
	P v, n;
	int t = is_intersect(a, b);
	
	// 2テ」ツ?、テ」ツ?ョテ・ツ??」ツ?古ァツュツ嘉」ツ?療」ツ??」ツ?ィテ」ツ?催」ツ?ィテ・ツ個?・ツ青ォテ」ツ?凖」ツつ凝」ツ?ィテ」ツ?催」ツ?ッテ・ツ?アテゥツ?堙ヲツ篠・テァツキツ堙」ツ?ェテ」ツ??
	if( equal(a.p.x, b.p.x) && equal(a.p.y, b.p.y) && equal(a.r, b.r) ){
		return ;
	}
	if( t == -2 ) return ;
	
	if(t == 0 || t == 1 || t == 2) {
		th = asin( (b.r - a.r) / d );
		v = rot(a.p, b.p, th) - a.p;
		n = P(-v.y, v.x);
		n /= abs(n);
		res.push_back( Line(a.p + n * a.r, b.p + n * b.r) );
		
		v = rot(a.p, b.p, -th) - a.p;
		n = P(v.y, -v.x);
		n /= abs(n);
		res.push_back( Line(a.p + n * a.r, b.p + n * b.r) );
	}
	
	if(t == 0) {
		th = asin( (b.r + a.r) / d );
		v = rot(a.p, b.p, th) - a.p;
		n = P(-v.y, v.x);
		n /= abs(n);
		res.push_back( Line(a.p - n * a.r, b.p + n * b.r) );
		
		v = rot(a.p, b.p, -th) - a.p;
		n = P(v.y, -v.x);
		n /= abs(n);
		res.push_back( Line(a.p - n * a.r, b.p + n * b.r));
	}
	
	if(t == 1) {
		n = b.p - a.p;
		n /= abs(n);
		v = P(-n.y, n.x);
		res.push_back( Line(a.p + n * a.r, a.p + n * a.r + v) );
	}
	
	if(t == -1) {
		n = a.p - b.p;
		n /= abs(n);
		v = P(-n.y, n.x);
		res.push_back( Line(a.p + n * a.r, a.p + n * a.r + v) );
	}
}


int main(){
	int N, x[51], y[51], r[51], m[51];
	while( cin >> N , N ){
		for(int i = 0; i < N; i++) cin >> x[i] >> y[i] >> r[i] >> m[i];
		
		if( N == 1 ){
			cout << 1 << endl;
			continue;
		}
		
		vector<Line> res;
		for(int i = 0 ; i < N; i++){
			for(int j = i + 1; j < N; j++){
				Circle c1(P(x[i], y[i]), r[i]);
				Circle c2(P(x[i], y[i]), r[i] + m[i]);
				Circle c3(P(x[j], y[j]), r[j]);
				Circle c4(P(x[j], y[j]), r[j] + m[j]);
				common_tangent(c1, c3, res);
				if( m[j] != 0 ) common_tangent(c1, c4, res);
				if( m[i] != 0 ) common_tangent(c2, c3, res);
				if( m[i] != 0 && m[j] != 0 ) common_tangent(c2, c4, res);
			}
		}
		int ans = 0;
		for(int i = 0; i < res.size(); i++){
			Line &l = res[i];
			int cnt = 0;
			for(int j = 0; j < N; j++){
				double d = distanceLP(res[i], P(x[j], y[j]));
				if( r[j] <= d + EPS && d - EPS <= r[j] + m[j] ){
					cnt++;
				}
			}
			ans = max(ans, cnt);
		}
		cout << ans << endl;
	}
}

Measured memory_bytes: 3508