#include <vector>
#include <list>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <deque>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
#include <cassert>
using namespace std;
inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
const double EPS = 1e-10;
const double PI  = acos(-1.0);

#include <complex>
typedef complex<double> P;
// 外積 (cross product) : a×b = |a||b|sinΘ
double cross(P a, P b) {
  return (a.real() * b.imag() - a.imag() * b.real());
}// 点a,bを通る直線と点cとの距離
double distance_l_p(P a, P b, P c) {
  return abs(cross(b-a, c-a)) / abs(b-a);
}//直線abと円及び球 |x-c|=rの交差判定
bool interpoint_lc(P a, P b, P c, double r,int sign){
    if(distance_l_p(a , b,c) > r + sign*EPS) return false;
    return true;
}

//円(x0,y0,r0)と円(x1,y1,r1)の共通接線の接点
void tangency(P pos0,double r0, P pos1, double r1, pair<P, P> out[4])
{
	double x0=pos0.real(),y0=pos0.imag();
	double x1=pos1.real(),y1=pos1.imag();
	const P v(x1 - x0, y1 - y0);
	const double a0 = arg(v);
	const double a1 = acos((r0 - r1) / abs(v));
	out[0] = make_pair(P(x0 + r0 * cos(a0 + a1), y0 + r0 * sin(a0 + a1)), P(x1 + r1 * cos(a0 + a1), y1 + r1 * sin(a0 + a1)));
	out[1] = make_pair(P(x0 + r0 * cos(a0 - a1), y0 + r0 * sin(a0 - a1)), P(x1 + r1 * cos(a0 - a1), y1 + r1 * sin(a0 - a1)));
	const double a2 = acos((r0 + r1) / abs(v));
	out[2] = make_pair(P(x0 + r0 * cos(a0 + a2), y0 + r0 * sin(a0 + a2)), P(x1 + r1 * cos(a0 + a2 + PI), y1 + r1 * sin(a0 + a2 + PI)));
	out[3] = make_pair(P(x0 + r0 * cos(a0 - a2), y0 + r0 * sin(a0 - a2)), P(x1 + r1 * cos(a0 - a2 + PI), y1 + r1 * sin(a0 - a2 + PI)));
}
struct gem{
	int r,m;
	P pos;
};
int go(vector<gem> &gems,P from,P to){
	int ans=0;
	REP(i,gems.size()){
		if(!interpoint_lc(from,to,gems[i].pos,gems[i].r,-1)){
			if(interpoint_lc(from,to,gems[i].pos,gems[i].r+gems[i].m,1)){
				ans++;
			}
		}
	}
	return ans;
}
int main(){
	int n;
	while(cin>>n,n){
		vector<gem> gems(n);
		REP(i,n){
			int x,y;
			cin>>x>>y>>gems[i].r>>gems[i].m;
			gems[i].pos=P(x,y);
		}
		if(n==1){
			cout<<1<<endl;
			continue;
		}

		vector<pair<P,P> > points;
		REP(i,n){
			FOR(j,i+1,n){
				pair<P,P> ps[4];
				tangency(gems[i].pos,gems[i].r,gems[j].pos,gems[j].r,ps);
				REP(k,4){
					points.push_back(ps[k]);
				}
				tangency(gems[i].pos,gems[i].r+gems[i].m,gems[j].pos,gems[j].r+gems[j].m,ps);
				REP(k,4){
					points.push_back(ps[k]);
				}
				tangency(gems[i].pos,gems[i].r,gems[j].pos,gems[j].r+gems[j].m,ps);
				REP(k,4){
					points.push_back(ps[k]);
				}
				tangency(gems[i].pos,gems[i].r+gems[i].m,gems[j].pos,gems[j].r,ps);
				REP(k,4){
					points.push_back(ps[k]);
				}
			}
		}
		int ans=0;
		REP(i,points.size()){
			int a=go(gems,points[i].first,points[i].second);
			ans=max(ans,a);
		}
		cout<<ans<<endl;
	}
}

Measured memory_bytes: 2776