#include <bits/stdc++.h>
using namespace std;
#define FOR(i,k,n) for(int i = (k); i < (n); i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(a) a.begin(), a.end()
#define MS(m,v) memset(m,v,sizeof(m))
#define D10 fixed<<setprecision(10)
typedef vector<int> vi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
const int INF = 114514810;
const int MOD = 1000000007;
const double EPS = 1e-10;
typedef double weight;
struct edge
{
	int to; weight cost;
	bool operator < (const edge& e) const { return cost < e.cost; }
	bool operator >(const edge& e) const { return cost > e.cost; }
};

typedef vector<edge> Edges;
typedef vector<Edges> Graph;
//int dx[] = { -1, 0, 0, 1 }; int dy[] = { 0, -1, 1, 0 };
template<class T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template<class T> T &chmax(T &a, const T &b) { return a = max(a, b); }
bool valid(int x, int y, int h, int w) { return (x >= 0 && y >= 0 && x < h&&y < w); }
int place(int x, int y, int w) { return w*x + y; }
///*************************************************************************************///
///*************************************************************************************///
///*************************************************************************************///

typedef long double ld;
const double PI = acos(-1.0);
bool eq(double a, double b) { return fabs(a - b) < EPS; }
typedef complex<double> Point;
typedef vector<Point> Polygon;

namespace std
{
	bool operator < (const Point& a, const Point& b)
	{
		return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
	}
}

struct Line
{
	Point a, b;
	Line(Point p, Point q) :a(p), b(q) {};
	Line(double x1, double y1, double x2, double y2) :a(Point(x1, y1)), b(Point(x2, y2)) {};
};

struct Circle
{
	Point p; double r;
	Circle(Point a, double b) :p(a), r(b) {};
};

double dot(Point a, Point b)
{
	return real(conj(a)*b);
}

double cross(Point a, Point b)
{
	return imag(conj(a)*b);
}

int ccw(Point a, Point b, Point c)
{
	b -= a; c -= a;
	if (cross(b, c) > EPS) return 1;    //counter cloclwise
	if (cross(b, c) < -EPS) return -1;  //cloclwise
	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;                           //a--c--b on line
}

bool isis_ll(Line l, Line m)
{
	return abs(cross(l.b - l.a, m.b - m.a)) > EPS;
}

bool isis_ls(Line l, Line s)
{
	return cross(l.b - l.a, s.a - l.a)*cross(l.b - l.a, s.b - l.a) < EPS;
}

bool isis_ss(Line s, Line t)
{
	return (ccw(s.a, s.b, t.a)*ccw(s.a, s.b, t.b) <= 0 &&
		ccw(t.a, t.b, s.a)*ccw(t.a, t.b, s.b) <= 0);
}

bool isis_lp(Line l, Point p)
{
	return (abs(cross(l.b - p, l.a - p)) < EPS);
}

bool isis_sp(Line s, Point p)
{
	return (abs(s.a - p) + abs(s.b - p) - abs(s.b - s.a)) < EPS;
}

Point projection(Line l, Point p)
{
	Point base = l.b - l.a;
	double r = dot(p - l.a, base) / norm(base);
	return l.a + base*r;
}

Point mirror(Line l, Point p)
{
	return 2.0*projection(l, p) - p;
}

double dist_lp(Line l, Point p)
{
	return abs(p - projection(l, p));
}

double dist_ll(Line l, Line m)
{
	return isis_ll(l, m) ? 0 : dist_lp(l, m.a);
}

double dist_ls(Line l, Line s)
{
	if (isis_ls(l, s)) return 0;
	return min(dist_lp(l, s.a), dist_lp(l, s.b));
}

double dist_sp(Line s, Point p)
{
	Point r = projection(s, p);
	if (isis_sp(s, r)) return abs(r - p);
	return min(abs(s.a - p), abs(s.b - p));
}

double dist_ss(Line s, Line t)
{
	if (isis_ss(s, t)) return 0;
	return min(min(dist_sp(s, t.a), dist_sp(s, t.b)), min(dist_sp(t, s.a), dist_sp(t, s.b)));
}

Point is_ll(Line s, Line t)
{
	double a = cross(s.b - s.a, t.b - t.a);
	double b = cross(s.b - s.a, s.b - t.a);
	return t.a + b / a*(t.b - t.a);
}

vector<Point> is_cc(Circle c1, Circle c2)
{
	vector<Point> res;
	double d = abs(c1.p - c2.p);
	double rc = (d*d + pow(c1.r, 2) - pow(c2.r, 2)) / (2 * d);
	double dfr = pow(c1.r, 2) - rc*rc;
	if (abs(dfr) < EPS) dfr = 0;
	if (dfr < 0.0) return res;
	double rs = sqrt(dfr);
	Point diff = (c2.p - c1.p) / d;
	res.push_back(c1.p + diff*Point(rc, rs));
	if (dfr != 0.0) res.push_back(c1.p + diff*Point(rc, -rs));
	return res;
}

int isis_cc(Circle c1, Circle c2)
{
	double d = abs(c1.p - c2.p);
	if (d - c1.r - c2.r < -EPS) return -2; //separate
	if (abs(d - c1.r - c2.r) < EPS) return -1; //circumscribe
	if (c1.r < c2.r) swap(c1, c2);
	if (abs(d - c1.r + c2.r) < EPS) return 1;//inscribe
	if (c1.r - d - c2.r>EPS) return 2;//involve
	else return 0;//intersect
}

vector<Line> tangent_cp(Circle c, Point p)
{
	vector<Line> res;
	Point v = c.p - p;
	double d = abs(v);
	double l = sqrt(norm(v) - c.r * c.r);
	if (l<EPS) { return res; }
	Point v1 = v * Point(l / d, c.r / d);
	Point v2 = v * Point(l / d, -c.r / d);
	res.push_back(Line(p, p + v1));
	if (l < EPS) return res;
	res.push_back(Line(p, p + v2));
	return res;
}

vector<Line> tangent_cc(Circle c1, Circle c2)
{
	vector<Line> res;
	if (abs(c1.p - c2.p) - (c1.r + c2.r) > -EPS)
	{
		Point center = (c1.p * c2.r + c2.p * c1.r) / (c1.r + c2.r);
		res = tangent_cp(c1, center);
	}
	if (abs(c1.r - c2.r) > EPS)
	{
		Point out = (-c1.p * c2.r + c2.p * c1.r) / (c1.r - c2.r);
		vector<Line> nres = tangent_cp(c1, out);
		res.insert(res.end(), nres.begin(), nres.end());
	}
	else
	{
		Point v = c2.p - c1.p; v /= abs(v);
		Point q1 = c1.p + v * Point(0, 1) * c1.r;
		Point q2 = c1.p + v * Point(0, -1) * c1.r;
		res.push_back(Line(q1, q1 + v));
		res.push_back(Line(q2, q2 + v));
	}
	return res;
}

int main()
{
	int n;
	while (cin >> n, n)
	{
		vector<Circle> cs;
		REP(i, n)
		{
			double x, y, r, m;
			cin >> x >> y >> r >> m;
			Point p(x, y);
			cs.push_back(Circle{ p, r });
			cs.push_back(Circle{ p, r + m });
		}
		int ans = 1;
		REP(i, cs.size())REP(j, i)
		{
			vector<Line> ls = tangent_cc(cs[i], cs[j]);
			REP(k, ls.size())
			{
				int cnt = 0;
				REP(l, cs.size())
				{
					if (l % 2)
					{
						if (dist_lp(ls[k], cs[l].p) - cs[l].r < EPS) cnt++;
					}
					else
					{
						if (dist_lp(ls[k], cs[l].p) - cs[l].r < -EPS) cnt--;
					}
				}
				chmax(ans, cnt);
			}
		}
		cout << ans << endl;
	}
	return 0;
}

Measured memory_bytes: 1272