#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<iomanip>
#include<cassert>
#include<sstream>
#include<complex>
#include<cstdio>
#include<climits>
#include<cstdlib>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<ctime>
#include<cctype>
#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)
#define inf (1<<28)
#define EPS (1e-10)
#define COUNTER_CLOCKWISE 1
#define CLOCKWISE -1 
#define ONLINE_BACK 2
#define ONLINE_FRONT -2
#define ON_SEGMENT 0
#define equals(a,b) (fabs((a)-(b)) < EPS)
#define MAX 51
using namespace std;

class Point
{
  public:
  double x,y;

  Point(double x = -inf,double y = -inf): 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 a){return Point(a*x,a*y);}
  Point operator / (double a){return Point(x/a,y/a);}
  bool operator < (const Point& p) const{ return !equals(x,p.x)?x<p.x:y<p.y; }

};

struct Segment
{
  Point p1,p2;
  Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
};
typedef Point Vector;
typedef Segment Line;
typedef vector<Point> Polygon;

double dot(Point a,Point b){ return a.x*b.x + a.y*b.y; }

double cross(Point a,Point b){ return a.x*b.y - a.y*b.x; }

double norm(Point a){ return a.x*a.x+a.y*a.y; }

double abs(Point a){return sqrt(norm(a));}

bool pequals(Point a,Point b){ return equals(a.x,b.x) && equals(a.y,b.y); }

Point rotate(Point a,double rad){ return Point(cos(rad)*a.x - sin(rad)*a.y,sin(rad)*a.x + cos(rad)*a.y); }

double toRad(double agl) { return agl*M_PI/180.0; }

struct Circle
{
  Point p;
  double r;
  Circle(Point p=Point(),double r=0):p(p),r(r){}
};

pair<Line,Line> innerTangent(Circle A,Circle B){
  complex<double> a(A.p.x,A.p.y);
  complex<double> b(B.p.x,B.p.y);

  double d=abs(b-a);
  double t=M_PI/2-atan2(A.r+B.r,sqrt(d*d-(A.r+B.r)*(A.r+B.r)));
  complex<double> l1 = a+(b-a)*polar(A.r/d,-t);
  complex<double> l2 = b+(a-b)*polar(B.r/d,-t);
  complex<double> l3 = a+(b-a)*polar(A.r/d, t);
  complex<double> l4 = b+(a-b)*polar(B.r/d, t);

  return make_pair(Line(Point(l1.real(),l1.imag()),Point(l2.real(),l2.imag())),
		   Line(Point(l3.real(),l3.imag()),Point(l4.real(),l4.imag())));
}

pair<Line,Line> outerTangent(Circle A,Circle B){
  complex<double> a(A.p.x,A.p.y);
  complex<double> b(B.p.x,B.p.y);

  double d=abs(b-a);
  double ta=acos((A.r-B.r)/d);
  double tb=M_PI-ta;
  complex<double> l1 = (b-a)*polar(A.r/d, ta)+a;
  complex<double> l2 = (b-a)*polar(-B.r/d,-tb)+b;
  complex<double> l3 = (b-a)*polar(A.r/d,-ta)+a;
  complex<double> l4 = (b-a)*polar(-B.r/d, tb)+b;

  return make_pair(Line(Point(l1.real(),l1.imag()),Point(l2.real(),l2.imag())),
		   Line(Point(l3.real(),l3.imag()),Point(l4.real(),l4.imag())));
}

Point projection(Line l,Point p) {
  double t = dot(p-l.p1, l.p1-l.p2) / norm(l.p1-l.p2);
  return l.p1 + (l.p1-l.p2)*t;
}
Point reflection(Line l,Point p) {
  return p + (projection(l, p) - p) * 2;
}
double distanceLP(Line l, Point p) {
  return abs(p - projection(l, p));
}


int N;
Circle cs[4*MAX];
Circle jewels[MAX];
double m[MAX];



bool check(Line l,int index)
{
  double dist = distanceLP(l,jewels[index].p);
  if(!equals(dist,jewels[index].r) && dist < jewels[index].r)
    return false;
  return equals(dist,jewels[index].r) || equals(dist,jewels[index].r+m[index]) || (jewels[index].r < dist && dist < jewels[index].r+m[index]);
}

int compute(int a,int b)
{
  int ret,cnt;
  ret = cnt = 0;
  pair<Line,Line> ll = innerTangent(cs[a],cs[b]);
  Line line = ll.first;

  rep(i,N)cnt += check(line,i);      
  ret = max(ret,cnt);
  cnt = 0;
  line = ll.second;

  rep(i,N)cnt += check(line,i);      
  ret = max(ret,cnt);
  cnt = 0;
  ll = outerTangent(cs[a],cs[b]);
  line = ll.first;
  rep(i,N)cnt += check(line,i); 
  ret = max(ret,cnt);
  cnt = 0;

  line = ll.second;
  rep(i,N)cnt += check(line,i); 
  ret = max(ret,cnt);


  return ret;
}

int main()
{
  while(cin >> N,N)
    {
      int index = 0;
      for(int i=0;i<N;i++)
	{
	  cin >> jewels[i].p.x >> jewels[i].p.y >> jewels[i].r >> m[i];
	  cs[index++] = Circle(jewels[i].p,jewels[i].r);
	  cs[index++] = Circle(jewels[i].p,jewels[i].r+m[i]);
	}

      int ans = 1;
      for(int i=0;i<2*N;i++)
	{
	  for(int j=(i%2?i+1:i+2);j<2*N;j++)
	    {
	      ans = max(ans,compute(i,j));
	    }
	}

      cout << ans << endl;
    }
  return 0;
}

Measured memory_bytes: 1384