#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const double EPS = 1e-8;
const double INF = 1e12;
typedef complex<double> P;
namespace std {
	bool operator < (const P& a, const P& b) {
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}
double cross(const P& a, const P& b) {
	return imag(conj(a)*b);
}
double dot(const P& a, const P& b) {
	return real(conj(a)*b);
}

struct L : public vector<P> {
	L(const P &a, const P &b) {
		push_back(a); push_back(b);
	}
};

typedef vector<P> G;

struct C {
	P p; double r;
	C(const P &p, double r) : p(p), r(r) { }
};

int ccw(P a, P b, P c) {
	b -= a; c -= a;
	if(cross(b, c) > 0)   return +1;       // counter clockwise
	if(cross(b, c) < 0)   return -1;       // clockwise
	if(dot(b, c) < 0)     return +2;       // c--a--b on line
	if(norm(b) < norm(c)) return -2;       // a--b--c on line
	return 0;
}

bool intersectLL(const L &l, const L &m) {
	return abs(cross(l[1] - l[0], m[1] - m[0])) > EPS || // non-parallel
		abs(cross(l[1] - l[0], m[0] - l[0])) < EPS;   // same line
}
bool intersectLS(const L &l, const L &s) {
	return cross(l[1] - l[0], s[0] - l[0])*       // s[0] is left of l
		cross(l[1] - l[0], s[1] - l[0]) < EPS; // s[1] is right of l
}
bool intersectLP(const L &l, const P &p) {
	return abs(cross(l[1] - p, l[0] - p)) < EPS;
}
bool intersectSS(const L &s, const L &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;
}
bool intersectSP(const L &s, const P &p) {
	return abs(s[0] - p) + abs(s[1] - p) - abs(s[1] - s[0]) < EPS; // triangle inequality
}

P projection(const L &l, const P &p) {
	double t = dot(p - l[0], l[0] - l[1]) / norm(l[0] - l[1]);
	return l[0] + t*(l[0] - l[1]);
}
P reflection(const L &l, const P &p) {
	return p + 2.0 * (projection(l, p) - p);
}
double distanceLP(const L &l, const P &p) {
	return abs(p - projection(l, p));
}
double distanceLL(const L &l, const L &m) {
	return intersectLL(l, m) ? 0 : distanceLP(l, m[0]);
}
double distanceLS(const L &l, const L &s) {
	if(intersectLS(l, s)) return 0;
	return min(distanceLP(l, s[0]), distanceLP(l, s[1]));
}
double distanceSP(const L &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 L &s, const L &t) {
	if(intersectSS(s, t)) return 0;
	return min(min(distanceSP(s, t[0]), distanceSP(s, t[1])),
			   min(distanceSP(t, s[0]), distanceSP(t, s[1])));
}
P crosspoint(const L &l, const L &m) {
	double A = cross(l[1] - l[0], m[1] - m[0]);
	double B = cross(l[1] - l[0], l[1] - m[0]);
	if(abs(A) < EPS && abs(B) < EPS) return m[0]; // same line
	if(abs(A) < EPS) assert(false); // !!!PRECONDITION NOT SATISFIED!!!
	return m[0] + B / A * (m[1] - m[0]);
}

// 2????????????2??¬?????±?????\???
vector<L> tangentCC(C c1, C c2){
	if(c1.r < c2.r) swap(c1, c2);
	double dist = abs(c1.p - c2.p);
	vector<L> ret;

	if(dist > c1.r + c2.r){
		// ??\????????????
		P cp = c1.p + (c2.p - c1.p) * c1.r / (c1.r + c2.r);
		P v = cp - c1.p;
		double d = abs(v);
		double theta = acos(c1.r / d);
		P p1 = c1.p + v * polar(1.0, theta) / d * c1.r;
		P p2 = c1.p + v * polar(1.0, -theta) / d * c1.r;

		ret.push_back(L(p1, cp));
		ret.push_back(L(p2, cp));
	}

	if(dist + c2.r > c1.r) {
		P v = c2.p - c1.p;
		double d = abs(v);
		double theta = acos((c1.r - c2.r) / d);
		for(int i = -1; i <= 1; i += 2) {
			P x = v * polar(1.0, theta * i) / d;
			P p1 = c1.p + x * c1.r;
			P p2 = c2.p + x * c2.r;
			ret.push_back(L(p1, p2));
		}
	}

	for(int i = 0; i < ret.size(); i++) {
		//cerr << abs(distanceLP(ret[i], c1.p) - c1.r) << endl;
		assert(abs(distanceLP(ret[i], c1.p) - c1.r) < EPS);
		//cerr << abs(distanceLP(ret[i], c2.p) - c2.r) << endl;
		assert(abs(distanceLP(ret[i], c2.p) - c2.r) < EPS);
	}
	return ret;
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);

	int N;
	while(cin >> N, N) {
		vector<C> c;
		vector<double> m(N);
		for(int i = 0; i < N; i++) {
			double x, y, r;
			cin >> x >> y >> r >> m[i];
			c.push_back(C(P(x, y), r));
		}

		if(N == 1) {
			cout << 1 << endl;
			continue;
		}

		int ans = 0;
		for(int i = 0; i < N; i++) {
			for(int j = i + 1; j < N; j++) {
				for(int k = 0; k < 2; k++) {
					for(int l = 0; l < 2; l++) {
						C c1 = c[i], c2 = c[j];
						if(k) c1.r += m[i];
						if(l) c2.r += m[j];
						vector<L> ls = tangentCC(c1, c2);
						for(auto line : ls) {
							int sum = 2;
							for(int x = 0; x < N; x++) {
								if(x == i || x == j) continue;
								double d = distanceLP(line, c[x].p);
								if(c[x].r <= d && d <= c[x].r + m[x]) sum++;
							}
							ans = max(ans, sum);
						}
					}
				}
			}
		}

		cout << ans << endl;
	}
}

Measured memory_bytes: 3504