#include <algorithm>
#include <iostream>
#include <complex>
#include <utility>
#include <vector>
#define EPS (1e-10)
#define X real()
#define Y imag()
using namespace std;
typedef complex<double> P;
typedef pair<P, P> L;
typedef pair<P, double> C;

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

double dot(P a, P b){
  return a.X*b.X + a.Y*b.Y;
}

double cross(P a, P b){
  return a.X*b.Y - a.Y*b.X;
}

P n_vector(P a){
  double l = abs(a);
  return P(-a.Y,a.X)/l;
}

vector<P> cpcc(C a, C b){
  double d = abs(a.first-b.first), ra = a.second, rb = b.second;
  double t = (ra*ra-rb*rb+d*d)/2/d, h = sqrt(ra*ra-t*t);
  P m = t/abs(b.first-a.first)*(b.first-a.first)+a.first;
  vector<P> cp(2,m);
  P n = n_vector(a.first-b.first);
  cp[0] -= h*n;
  cp[1] += h*n;
  return cp;
}

vector<P> tangent_to_C(P p, C c){
  C c2 = C((p+c.first)/2.0,abs(p-c.first)/2.0);
  return cpcc(c,c2);
}

vector<P> points_of_contact(C a, C b){
  //???a, b?????±?????\?????????a?????\???????±???????
  vector<P> ret, cp;
  if(a.second == b.second){
    P n = n_vector(b.first-a.first);
    ret.push_back(P(a.first+a.second*n));
    ret.push_back(P(a.first-a.second*n));
  }
  P i = (a.first*b.second+b.first*a.second)/(a.second+b.second);
  if(abs(a.first-b.first) > a.second+b.second){//4??¬
    cp = tangent_to_C(i,a);
    for(int i = 0; i < 2; ++i) ret.push_back(cp[i]);
    if(a.second != b.second){
      P e = (a.first*b.second-b.first*a.second)/(b.second-a.second);
      cp = tangent_to_C(e,a);
      for(int i = 0; i < 2; ++i) ret.push_back(cp[i]);
    }
  }else if(abs(a.first-b.first) == a.second+b.second){//3??¬
    cp = tangent_to_C(i,a);
    ret.push_back(cp[0]);
    if(a.second != b.second){
      P e = (a.first*b.second-b.first*a.second)/(b.second-a.second);
      cp = tangent_to_C(e,a);
      for(int i = 0; i < 2; ++i) ret.push_back(cp[i]);
    }
  }else if(abs(a.first-b.first) > abs(a.second-b.second)){//2??¬
    if(a.second != b.second){
      P e = (a.first*b.second-b.first*a.second)/(b.second-a.second);
      cp = tangent_to_C(e,a);
      for(int i = 0; i < 2; ++i) ret.push_back(cp[i]);
    }
  }else if(abs(a.first-b.first) == abs(a.second-b.second)){//1??¬
    P e = (a.first*b.second-b.first*a.second)/(b.second-a.second);
    cp = tangent_to_C(e,a);
    ret.push_back(cp[0]);
  }
  sort(ret.begin(), ret.end());
  return ret;
}

vector<L> common_tangent(C a, C b){
  vector<P> p = points_of_contact(a, b);
  vector<L> ret;
  int n = p.size();
  for(int i = 0; i < n; ++i){
    ret.push_back(L(p[i], p[i]+n_vector(p[i]-a.first)));
  }
  return ret;
}

double p_to_l_dist(P a, L s){
  return abs(cross(s.first-s.second,a-s.second))/abs(s.first-s.second);
}

int count(vector<C>& c, vector<double>& m, int s, int t){
  C a = c[s], b = c[t];
  vector<L> tangents = common_tangent(a, b);
  int n = tangents.size(), ret = 0;

  for(int i = 0; i < n; ++i){
    int cnt = 0;
    for(int j = 0; j < c.size(); ++j){
      double d = p_to_l_dist(c[j].first, tangents[i]), r = c[j].second;
      if(d - r > -EPS && r + m[j] - d > -EPS) ++cnt;
    }
    ret = max(ret, cnt);
  }

  a.second += m[s];
  b.second += m[t];
  vector<L> tangents2 = common_tangent(a, b);
  n = tangents2.size();
  for(int i = 0; i < n; ++i){
    int cnt = 0;
    for(int j = 0; j < c.size(); ++j){
      double d = p_to_l_dist(c[j].first, tangents2[i]), r = c[j].second;
      if(d - r > -EPS && r + m[j] - d > -EPS) ++cnt;
    }
    ret = max(ret, cnt);
  }

  return ret;
}

int main(){
  int N;
  while(cin >> N, N){
    vector<C> c;
    vector<double> m(N);
    double x, y, r;
    for(int i = 0; i < N; ++i){
      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){
	ans = max(ans, count(c, m, i, j));
      }
    }
    cout << ans << endl;
  }
  return 0;
}

Measured memory_bytes: 3176