#include <iostream>
#include <vector>
#include <complex>
#include <cmath>
using namespace std;

#define P complex<T> 
#define EPS (1e-9)

/*****
 * ¼üÍ¼üãÌÙÈé2_(p1, p2)Å\·
 * ~ÍScÆ¼arÉæè(c, r)Æ\·
 *****/

//XJ[lÌðÔ·B+:1, -:-1, 0:0B
template<typename T>
int sig(T a){
    return a==0?0:a>0?1:-1;
}

//xNgp1, p2ÌàÏðÔ·
template<typename T>
T iprod(P p1, P p2){
    return (p1.real()*p2.real()) + (p1.imag()*p2.imag());
}

//xNgp1, p2ÌOÏ(XJ[l,zÀW)ðÔ·
template<typename T>
T oprod(P p1, P p2){
    return (p1.real()*p2.imag()) - (p1.imag()*p2.real());
}


//üª(p1, p2)Æ_qÌ£ðÔ·
template<typename T>
T disSP(P p1, P p2, P q){
    if(iprod( (p2-p1), (q-p1) ) < EPS) return abs(q-p1);
    if(iprod( (p1-p2), (q-p2) ) < EPS) return abs(q-p2);
    return disLP(p1, p2, q);
}

//¼ü(p1, p2)Æ_qÌ£ðÔ·
template<typename T>
T disLP(P p1, P p2, P q){
    return abs( oprod( (p2-p1), (q-p1) ) ) / abs(p2-p1);
}

//üª(p1, p2)Æüª(q1, q2)Ìð_ª¶Ý·éÆ«ÉtrueðÔ·
template<typename T>
bool crsSS(P p1, P p2, P q1, P q2){
    if(max(p1.real(), p2.real()) + EPS < min(q1.real(), q2.real())) return false;
    if(max(q1.real(), q2.real()) + EPS < min(p1.real(), p2.real())) return false;
    if(max(p1.imag(), p2.imag()) + EPS < min(q1.imag(), q2.imag())) return false;
    if(max(q1.imag(), q2.imag()) + EPS < min(p1.imag(), p2.imag())) return false;
   return sig(oprod(p2-p1, q1-p1)) * sig(oprod(p2-p1, q2-p1)) < EPS
        && sig(oprod(q2-q1, p1-q1)) * sig(oprod(q2-q1, p2-q1)) < EPS;
}

//~(c1, r)Æ~(c2, r2)Ìð_ª¶Ý·éÆ«ÉtrueðÔ·B
//Ú_ÌÆ«à½ªtrueðÔ·
template<typename T>
bool crsCC(P c1, T r1, P c2, T r2){
    T dis = abs(c1-c2);
    return dis < r1 + r2 + EPS && abs(r1-r2) < dis + EPS;
}

//Op`(p1, p2, p3)ÌOSðÔ·
/*********¢À*********/
template<typename T>
P ccenter(P p1, P p2, P p3){
    return p1;
}
//4_p1, p2, p3, p4ª¯ê¼üãÉ éÆ«trueðÔ·B
//4_ª¯ê¼üãÉ éÆ«àtrueðÔ·çµ¢
template<typename T>
bool onCir(P p1, P p2, P p3, P p4){
    if(abs(oprod(p2-p1, p3-p1)) < EPS) return true;
    P c = ccenter(p1, p2, p3);
    return abs(norm(c-p1) - norm(c-p4)) < EPS;
}

//_q©ç¼ü(p1, p2)Éºëµ½üÌ«ðÔ·
template<typename T>
P proj(P p1, P p2, P q){
    return p1 + (iprod( p2-p1, q-p1 )/(norm(p2-p1))*(p2-p1));
}

//¼ü(p1,p2)Æ¼ü(q1, q2)Ìð_ðÔ·
template<typename T>
P isLL(P p1, P p2, P q1, P q2){
    T d = oprod( q2-q1, p2-p1 );
    if ( abs(d) < EPS ) return NULL;
    return p1 + (oprod(q2-q1, q1-p1)/d*(p2-p1));
}

//¼ü(p1,p2)Æ~(c,r)Ìð_ÌvectorðÔ·(p1Éß¢)
template<typename T>
vector<P> isCL(P c, T r, P p1, P p2){
    vector<P> ans;
    T x = iprod(p1-c, p2-p1);
    T y = norm(p2-p1);
    T d  = x*x - y*(norm(p1-c) - r*r);
    if(d < -EPS) return ans;
    if(d < 0) d = 0;
    P q1 = p1 - (x/y)*(p2-p1);
    P q2 = sqrt(d)/y*(p2-p1);
    ans.push_back(q1-q2);
    ans.push_back(q1+q2);
    return ans;
}

//~(c1, r1), ~(c2, r2)Ìð_ÌvectorðÔ·
template<typename T>
vector<P> isCC(P c1, T r1, P c2, T r2){
    vector<P> ans;
    T x = norm(c1-c2);
    T y = ((r1*r1 - r2*r2)/x + 1)/2;
    T d = r1*r1/x - y*y;
    if(d < -EPS) return ans;
    if(d < 0) d=0;
    P q1 = c1 + y*(c2-c1);
    P q2 = (c2 - c1)*(polar(sqrt(d), (T)M_PI/2));
    ans.push_back(q1-q2);
    ans.push_back(q1+q2);
    return ans;
}

//_p©çø¢½~(c, r)ðÊéÚüÌÚ_ÌvectorðÔ·
template<typename T>
vector<P> tanCP(P c, T r, P p){
    vector<P> ans;
    T x = norm(p-c);
    T d = x - r*r;
    if(d < -EPS) return ans;
    if(d < 0) d = 0;
    P q1 = (r*r/x)*(p-c);
    P q2 = (p-c)*(polar(-r*sqrt(d)/x, (T)M_PI/2));
    ans.push_back(c+q1-q2);
    ans.push_back(c+q1+q2);
    return ans;
}

//~(c1, r1), ~(c2, r2)Ì¤ÊÚüÌvectorðÔ·
/******2~ªÚ·éÆ«ÌªvC³*********/
template<typename T>
vector< vector<P> > tanCC(P c1, T r1, P c2, T r2){
    vector< vector<P> > ans;
    vector<P> line;
    if(abs(r1-r2) < EPS){
        P dir = c2-c1;
        dir = dir * polar(r1/abs(dir), (T)M_PI/2);
        
        line.clear(); line.push_back(c1+dir); line.push_back(c2+dir);
        ans.push_back(line);
        line.clear(); line.push_back(c1-dir); line.push_back(c2-dir);
        ans.push_back(line);
        
    }else{
        P p = (-r2*c1 + r1*c2)/(r1-r2);
        vector<P> ps, qs;
        ps = tanCP(c1, r1, p);
        qs = tanCP(c2, r2, p);
        for(int i=0; i<(int)ps.size() && i<(int)qs.size(); i++){
            line.clear(); line.push_back(ps[i]);line.push_back(qs[i]);
            ans.push_back(line);
        }
    }
    P p = (r2*c1 + r1*c2)/(r1+r2);
    vector<P> ps, qs;
    ps = tanCP(c1, r1, p);
    qs = tanCP(c2, r2, p);
    /*** ps[i] == qs[i] ÌÛÉÚüðÁèÅ«éæ¤Éµ½¢ ***/
    for(int i=0; i<(int)ps.size() && i<(int)qs.size(); i++){
        /*** ÈºÍèÉÇÁ ***/
        if(abs(ps[i]-qs[i]) < EPS){
            P dir = (c2 - c1)*polar((T)1/(abs(c2-c1)), (T)M_PI/2);
            ps[i] += dir;
            qs[i] -= dir;
        }
        /*** ±±ÜÅ ***/
        line.clear(); line.push_back(ps[i]);line.push_back(qs[i]);
        ans.push_back(line);
    }
    return ans;
}

//~(c1, r1), ~(c2, r2)Ì¤ÊªÊÏ
template<typename T>
T areaCC(P c1, T r1, P c2, T r2){
    T d = abs(c1-c2);
    if(r1+r2 < d+EPS) return 0;
    if(d < abs(r1-r2) + EPS){
        T r = min(r1, r2);
        return r*r*M_PI;
    }
    T x = (d*d+r1*r1-r2*r2)/(2*d);
    T t1 = acos(x/r1);
    T t2 = cos((d-x)/r2);
    return r1*r1*t1 + r2*r2*t2 - d*r1*sin(t1);
}

//Oð´_Æ·éB~(O,r1)ÆOp`(O,p1,p2)Ì¤ÊªÊÏ
template<typename T>
T areaCT(T r, P p1, P p2){
    T o(0, 0);
    vector<P> qs = isCL(o, r, p1, p2);
    if(qs.empty()) return r*r*arg(p1-p2)/2;
    bool b1 = abs(p1) > r + EPS, b2 = abs(p2) > r + EPS;
    if(b1 && b2){
        if(iprod(p1-qs[0], p2-qs[0]) < EPS &&
                iprod(p1-qs[1], p2-qs[1]) < EPS){
            return (r*r*(arg(p1-p2)-arg(qs[0]-qs[1])) + oprod(qs[0], qs[1]))/2;
        }else{
            return r*r*arg(p1-p2)/2;
        }
    }else if(b1){
        return (r*r*arg(p1-qs[0]) + oprod(qs[0], p2))/2;
    }else if(b2){
        return (r*r*arg(qs[1]-p2) + oprod(p1, qs[1]))/2;
    }else{
        return oprod(p1, p2) / 2;
    }
}


typedef long double ld;
#define Point complex<ld>
#define fs first
#define sc second

int main(){
    int n;
    vector<Point> ss;
    while(cin>>n){
        if(n==0) break;
        ld x, y, r, m;
        vector< pair< Point,ld > > cs;
        for(int i=0; i<n; i++){
            cin >> x >> y >> r >> m;
            Point p(x,y);
            cs.push_back(make_pair(p,r));
            cs.push_back(make_pair(p,r+m));
        }
        if(n<=2){cout<<n<<endl; continue;}
        int best=-1;
        for(int i=0; i<n*2; i++){
            for(int j=i+1; j<n*2; j++){
                vector< vector< Point > > lines=tanCC(cs[i].fs, cs[i].sc, cs[j].fs, cs[j].sc);
                for(int ii=0; ii<(int)lines.size(); ii++){
                    int tmp = 0;
                    for(int jj=0; jj<n; jj++){
                        ld d = disLP(lines[ii][0],lines[ii][1],cs[2*jj].fs);
                        if(d > cs[2*jj].sc - EPS && d < cs[2*jj+1].sc + EPS)
                            tmp++;
                    }
                    if(tmp > best) best=tmp;
                }
            }
        }
        cout << best << endl;
    }
    return 0;
}

Measured memory_bytes: 1004