#include<bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i=0; i < (n); i++)

static const double pi = 3.141592653589793;
typedef double D;      // 座標値の型。doubleかlong doubleを想定
typedef complex<D> P;  // Point
typedef pair<P, P> L;  // Line
typedef vector<P> VP;
const D EPS = 1e-3;    // 許容誤差。問題によって変える
#define X real()
#define Y imag()
#define LE(n,m) ((n) < (m) + EPS)
#define GE(n,m) ((n) + EPS > (m))
#define EQ(n,m) (abs((n)-(m)) < EPS)
int N;

namespace std {
  bool operator<(const P a, const P b) {
    return a.X != b.X ? a.X < b.X : a.Y < b.Y;
  }
}

D dot(P a, P b) {
  return (conj(a)*b).X;
}

D cross(P a, P b) {
  return (conj(a)*b).Y;
}

P proj(P a1, P a2, P p) {
  return a1 + dot(a2-a1, p-a1)/norm(a2-a1) * (a2-a1);
}

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

bool isecSS(P a1, P a2, P b1, P b2) {
  return ccw(a1, a2, b1)*ccw(a1, a2, b2) <= 0 &&
         ccw(b1, b2, a1)*ccw(b1, b2, a2) <= 0;
}
int points[51][4];

int inCcwConvex(const VP& ps, P p) {
  int n = ps.size();
  P g = (ps[0] + ps[n / 3] + ps[n*2 / 3]) / 3.0;
  if (g == p) return 1;
  P gp = p - g;

  int l = 0, r = n;
  while (l + 1 < r) {
    int mid = (l + r) / 2;
    P gl = ps[l] - g;
    P gm = ps[mid] - g;
    if (cross(gl, gm) > 0) {
      if (cross(gl, gp) >= 0 && cross(gm, gp) <= 0) r = mid;
      else l = mid;
    }
    else {
      if (cross(gl, gp) <= 0 && cross(gm, gp) >= 0) l = mid;
      else r = mid;
    }
  }
  r %= n;
  D cr = cross(ps[l] - p, ps[r] - p);
  return EQ(cr, 0) ? 2 : cr < 0 ? 0 : 1;
}
D distLP(P a1, P a2, P p) {
  return abs(proj(a1, a2, p) - p);
}


int inConvex(P p, const VP& ps) {
  int n = ps.size();
  int dir = ccw(ps[0], ps[1], p);
  rep (i, n) {
    int ccwc = ccw(ps[i], ps[(i + 1) % n], p);
    if (!ccwc) return 2;  // 線分上に存在
    if (ccwc != dir) return 0;
  }
  return 1;
}

tuple<int, double, P, P, P, P> count(P a1,P a2,P b1,P b2) {
	if(isecSS(a1, b1, a2, b2)) swap(b1,b2);
	int cnt = 0;
	vector<P> vp = {a1, a2, b2, b1};
	rep(i, N) {
		P p1 = P(points[i][0], points[i][1]);
		double r1 = points[i][2];
		double r2 = r1 + points[i][3];
		double l1 = min(distLP(a1, b1, p1), distLP(a2, b2, p1));
		double l2 = max(distLP(a1, b1, p1), distLP(a2, b2, p1));
		if(inConvex(p1, vp) > 0) {
			if (l2 + EPS >= r1) {
				cnt += 1;
			}
		} else {
			if (l1 <= r2 + EPS and l2 + EPS >= r1) cnt += 1;
		}
	}
	//cout << a1<< a2<< b1<<b2<< cnt << "d" << -abs(a1 - a2) << "c" << isecSS(a1, b1, a2, b2)<< endl;
	return make_tuple(cnt,-abs(a1 - a2), a1, a2, b2, b1);
}

P rotateP(P a ,D arg) { //点aを点oを中心に反時計周りにまわした複素数を返す。
	//a -= o;
	a *= P(cos(arg), sin(arg));
	//a += o;
	return a;
}
	

int main() {
	
	/*ifstream in("Ain.txt");
	cin.rdbuf(in.rdbuf());
	ofstream ofs("Aout.txt");
	cout.rdbuf(ofs.rdbuf());
	*/
	while (cin >> N, N) {
		rep(i, N) {
			rep(j, 4) {
				cin >> points[i][j];
			}
		}
		priority_queue<tuple<int, double, P, P, P, P>, vector<tuple<int, double, P, P, P, P>>> pq;
		double ar1 = pi / 10;
		P pa = P(-3000, 0);
		P pa1 = rotateP(pa, -ar1 / 2);
		P pa2 = rotateP(pa, ar1 / 2);
		rep(a , 20) {
			P pb1 = rotateP(pa1, 2 * ar1);
			P pb2 = rotateP(pa2, 2 * ar1);
			rep(b, 17) {
				pq.push(make_tuple(N, 10, pa1, pa2, pb1, pb2));
				pb1 = rotateP(pb1, ar1);
				pb2 = rotateP(pb2, ar1);
				//cout << pa1 << pa2 << pb1 << pb2 << endl;
			}
			pa1 = rotateP(pa1, ar1);
			pa2 = rotateP(pa2, ar1);
		}
				
	int ans = 0;
	while(true) {
		auto p = pq.top();
		if (abs(get<1>(p)) < EPS) {
			ans = get<0>(p);
			break;
		}
		pq.pop();
		double d = -get<1>(p) / 2;
		P ma = (get<2>(p) + get<3>(p)) / P(2, 0);
		P mb = (get<4>(p) + get<5>(p)) / P(2, 0);
		pq.push(count(get<2>(p), ma, get<4>(p), mb));
		pq.push(count(ma, get<3>(p), get<4>(p), mb));
		pq.push(count(get<2>(p), ma, mb, get<5>(p)));
		pq.push(count(ma, get<3>(p), mb, get<5>(p)));
	}
	cout << ans << endl;
	}
}




Measured memory_bytes: 12156