#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <vector>
#include <utility>
#define EPS 1e-10
#define maxn 55
using namespace std;
typedef long long ll;
struct Point{
	double x,y;
	Point(double x = 0.0,double y = 0.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 lambda){
		return Point(x * lambda,y * lambda);
	}
	Point operator / (double lambda){
		return Point(x / lambda,y / lambda);
	}
	double norm(){
		return x * x + y * y;
	}
	double abs_(){
		return sqrt(norm());
	}
	bool operator == (const Point &p)const
	{
		return abs(x - p.x) < EPS && abs(y - p.y) < EPS;
	}
	bool operator < (const Point &p)const
	{
		if(abs(x - p.x) < EPS) return y - p.y < -EPS;
		else return x - p.x < EPS;
	}
	double pol(){
		return atan2(y,x);
	}
	Point ccw90(){
		return Point(-y,x);
	}
	
	void print(){
		printf("%.10f %.10f\n",x,y);
	}
};
typedef Point Vector;
struct Segment{
	Point p1,p2;
	Segment(Point p1 = Point(),Point p2 = Point()): p1(p1),p2(p2) {}
	
	void print(){
		printf("%.10f %.10f %.10f %.10f\n",p1.x,p1.y,p2.x,p2.y);
	}
};
typedef Segment Line;
struct Circle{
	Point c;
	double r;
	Circle(Point c = Point(),double r = 0.0): c(c),r(r) {}
	Point arcpoint(double theta){
		return c + Point(cos(theta),sin(theta)) * r;
	}
};
typedef vector<Point> Polygon;
double dot(Vector a,Vector b){
	return a.x * b.x + a.y * b.y;
}
double det(Vector a,Vector b){
	return a.x * b.y - b.x * a.y;
}
int n;
Circle a[maxn],b[maxn];
double m[maxn];
vector <Line> ts;
int cts(Circle o1,Circle o2){
	ts.clear();
	double rdif = o1.r - o2.r,rsum = o1.r + o2.r;
	Vector v = o2.c - o1.c;
	if(abs(rdif) - v.abs_() > EPS) return 0;
	vector <Point> ps;
	ps.clear();
	double alpha;
	if(abs(abs(rdif) - v.abs_()) < EPS){
		if(rdif < 0) alpha = acos(-1);
		else alpha = acos(1);
		ps.push_back(o1.arcpoint(v.pol() + alpha));
	}else{
		alpha = acos(rdif / v.abs_());
		ps.push_back(o1.arcpoint(v.pol() + alpha));
		ps.push_back(o1.arcpoint(v.pol() - alpha));
	}
	if(abs(rsum - v.abs_()) < EPS){
		alpha = acos(1);
		ps.push_back(o1.arcpoint(v.pol() + alpha));
	}else if(rsum - v.abs_() < -EPS){
		alpha = acos(rsum / v.abs_());
		ps.push_back(o1.arcpoint(v.pol() + alpha));
		ps.push_back(o1.arcpoint(v.pol() - alpha));
	}
	int m = ps.size();
	for(int i=0;i<m;i++){
		Line l = Segment(ps[i],ps[i] + (o1.c - ps[i]).ccw90());
		ts.push_back(l);
	}
	return m;
}
double disLP(Line l,Point p){
	return abs(det(l.p2 - l.p1,p - l.p1)) / (l.p2 - l.p1).abs_();
}
int calc(Line l){
	int res = 0;
	for(int i=1;i<=n;i++){
		double d = disLP(l,a[i].c);
		if(d - a[i].r > -EPS && d - (a[i].r + m[i]) < EPS) res++;
	}
	return res;
}
int main(){
	while(~scanf("%d",&n) && n){
		int ans = 1;
		for(int i=1;i<=n;i++){
			scanf("%lf%lf%lf%lf",&a[i].c.x,&a[i].c.y,&a[i].r,&m[i]);
			b[i].c = a[i].c;
			b[i].r = a[i].r + m[i];
		}
		for(int i=1;i<=n;i++){
			for(int j=i+1;j<=n;j++){
				int m = cts(a[i],a[j]);
				for(int k=0;k<m;k++){
					ans = max(ans,calc(ts[k]));
				}
				m = cts(b[i],a[j]);
				for(int k=0;k<m;k++){
					ans = max(ans,calc(ts[k]));
				}
				m = cts(a[i],b[j]);
				for(int k=0;k<m;k++){
					ans = max(ans,calc(ts[k]));
				}
				m = cts(b[i],b[j]);
				for(int k=0;k<m;k++){
					ans = max(ans,calc(ts[k]));
				}
			}
		}
		printf("%d\n",ans);
	}
	return 0;
}



Measured memory_bytes: 3640