#include<bits/stdc++.h>
using namespace std;

const double eps = 1e-8;
const double PI = acos(-1);

double cosine_theorem(double a,double b,double c){
  //a^2 = b^2 + c^2 - (2 * b * c * cosA)
  double cosA=(b*b+c*c-a*a) / (2*b*c);
  return cosA;
}

double Sqrt(double x){
  return (x<0?0:sqrt(x));
}

bool eq(double a, double b){
  return (-eps<a-b&&a-b<eps);
}

struct Point{
  double x,y,z;
  Point (double a=0,double b=0,double c=0): x(a),y(b),z(c) {}
  Point operator + (const Point &p)const{
    return Point(x+p.x,y+p.y,z+p.z);
  }
  Point operator - (const Point &p)const{
    return Point(x-p.x,y-p.y,z-p.z);
  }
  Point operator * (const double &r)const{
    return Point(x*r,y*r,z*r);
  }
  Point operator / (const double &r)const{
    return Point(x/r,y/r,z/r);
  }
};

typedef Point Vector;

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

Point cross(Point a,Point b){
  double nx=a.y*b.z-b.y*a.z;
  double ny=a.z*b.x-b.z*a.x;
  double nz=a.x*b.y-b.x*a.y;
  return Point(nx,ny,nz);
}

double norm(Point a){
  return dot(a,a);
}

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

struct Line{
  Point p;
  Vector v;
  Line(Point a=Point(),Vector b=Vector()):p(a),v(b){}
};

struct Segment{
  Point p0,p1;
  Segment(Point a=Point(),Vector b=Vector()):p0(a),p1(b){}
};

struct Plane{
  Point p;
  Vector v0,v1;
  Plane(Point a=Point(),Vector b=Vector(),Vector c=Vector())
    :p(a),v0(b),v1(c){}
};

Vector normalize(Vector v){
  return v/abs(v);
}

Vector cross(Plane p){
  return cross(p.v0,p.v1);
}

bool isParallel(Vector s,Vector t){
  return eq( 0.0 , norm(cross(s,t)) );
}

bool isParallel(Plane s,Plane t){
  return isParallel( cross(s) , cross(t) );
}

bool isParallel(Plane s,Vector t){
  return eq(0,dot(cross(s.v0,s.v1),t));
}


// *
bool isDependent(Vector a,Vector b,Vector c){
  Vector ab=cross(a,b),ac=cross(a,c);
  return (norm(cross(ab,ac)) < eps);
}

// *
bool isIntersect(Line s,Line t){
  if(isParallel(s.v,t.v))return isParallel(t.p-s.p,s.v);
  Vector a=cross(s.v,t.p-s.p);
  Vector b=cross(s.v,t.p+t.v-s.p);
  return (norm(cross(a,b)) < eps);
}


double getDistance(Line s,Point t){
  return abs(cross(t-s.p,s.v))/abs(s.v);
}

double getDistance(Segment s,Point t){
  if(dot(t-s.p0,s.p1-s.p0)<0)return abs(t-s.p0);
  if(dot(t-s.p1,s.p0-s.p1)<0)return abs(t-s.p1);
  return abs(cross(t-s.p0,s.p1-s.p0))/abs(s.p1-s.p0);
}

double getDistance(Plane s,Point t){
  Vector A=cross(s.v0,s.v1);
  return abs(dot(A,t-s.p))/abs(A);
}

Point getCrossPoint(Plane s,Line t){
  Vector k=cross(s.v0,s.v1);
  double A=dot(k,t.p-s.p);
  double B=dot(k,t.p+t.v-s.p);
  return t.p+t.v*A/(A-B);
}

Line getCrossLine(Plane s,Plane t){
  if(isParallel(s,t.v0))t.v0=t.v0+t.v1;
  Point A=getCrossPoint(s,Line(t.p,t.v0));
  if(isParallel(s,t.v1))t.v1=t.v1+t.v0;
  Point B=getCrossPoint(s,Line(t.p,t.v1));
  return Line(A,B-A);
}

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

vector<Point> getCrossPoint(Ball s,Line t){
  vector<Point> res;
  Vector a=s.p-t.p;
  Vector b=t.v;
  double base=dot(a,b)/abs(b);
  double hh=norm(cross(a,b))/norm(b);
  if(s.r*s.r+eps < hh )return res;
  double w=Sqrt( s.r*s.r - hh );
  res.push_back(t.p+t.v/abs(t.v)*(base-w));
  res.push_back(t.p+t.v/abs(t.v)*(base+w));
  return res;
}

vector<Point> getCrossPoint(Ball s,Segment t){
  vector<Point> res;
  Vector a=s.p-t.p0;
  Vector b=t.p1-t.p0;
  double base=dot(a,b)/abs(b);
  double hh=norm(cross(a,b))/norm(b);
  if(s.r*s.r+eps < hh )return res;
  double w=Sqrt( s.r*s.r - hh );
  
  if(-eps<base-w&&base-w<abs(b)+eps)
    res.push_back(t.p0+b/abs(b)*(base-w));
  
  if(-eps<base+w&&base+w<abs(b)+eps)
      res.push_back(t.p0+b/abs(b)*(base+w));
  
  return res;
}


// *
double getDistance(Line s,Line t){
  if(isParallel(s.v,t.v)){
    return sqrt(norm(cross(s.v,t.p-s.v))/norm(s.v));
  }
  Vector k=cross(s.v,t.v);
  return abs(dot(k,s.p-t.p))/abs(k);
}

// *
double getDistance(Segment s,Segment t){
  Vector sv=s.p1-s.p0;
  Vector tv=t.p1-t.p0;
  Vector sk=cross(cross(sv,tv),sv);
  Vector tk=cross(cross(sv,tv),tv);
  if( dot(sk,t.p0-s.p0)*dot(sk,t.p1-s.p0) < 0 &&
      dot(tk,s.p0-t.p0)*dot(tk,s.p1-t.p0) < 0){
    return getDistance(Line(s.p0,sv),Line(t.p0,tv));
  }
  return min(min(getDistance(s,t.p0),getDistance(s,t.p1)),
             min(getDistance(t,s.p0),getDistance(t,s.p1)));
}


Point reflect(Point sp,Vector sk,Point t){
  return t-sk*dot(sk,t-sp)*2.0/norm(sk);
}
Point reflect(Plane s,Point t){
  Vector k=cross(s.v0,s.v1);
  return t-k*dot(k,t-s.p)*2.0/norm(k);
}

// ***
// res[0]=cos_A 0< A < 2PI
// res[1]=sin_A 0< A < 2PI

// res[2]=sin_B 0< B < PI
// res[3]=cos_B 0< B < PI

vector<double> getArg(Point p){
  vector<double> res(4,0);
  if(abs(p)<eps)return res;
  double len=sqrt(p.x*p.x+p.y*p.y);
  res[0]=p.x/len;
  res[1]=p.y/len;
  res[2]=p.z/abs(p);
  res[3]=Sqrt(1.0-res[2]*res[2]);
  return res;  
}

struct Circle{
  Point p;
  Vector v;
  double r;
  Circle(Point p,Vector v,double r):
    p(p),v(v),r(r) {}
};

bool isCrossBall(Ball a,Ball b){
  double d=abs(a.p-b.p);
  if( d < abs(a.r-b.r)-eps )return false;
  if( d > a.r+b.r+eps )return false;
  return true;
}

Circle getCrossCircle(Ball a,Ball b){
  Vector base=b.p-a.p;
  double cosA=cosine_theorem( b.r , abs(base) , a.r );
  double sinA=Sqrt(1.0-cosA*cosA);

  return Circle( a.p + normalize(base) * ( cosA * a.r ),
                 base,
                 a.r*sinA );
}

double maxz(Circle c){
  double t=getArg(c.v)[3];
  return c.p.z+abs(t*c.r);
}

double minz(Circle c){
  double t=getArg(c.v)[3];
  return c.p.z-abs(t*c.r);
}

int Count;
int parent[1000];
void init(int n){
  Count=n;
  for(int i=0;i<n;i++)parent[i]=i;
}
int find(int x){
  if(parent[x]==x)return x;
  else return parent[x]=find(parent[x]);
}
void unite(int x,int y){
  x=find(x);
  y=find(y);
  if(x==y)return;
  Count--;
  parent[x]=y;
}

int N;
vector< Ball > A;
vector<double> t;

int func(double lz){
  vector<double> rs,xs,ys;
  for(int i=0;i<N;i++){
    Ball b=A[i];
    double dz=abs(lz-b.p.z);
    if(dz>b.r+eps)continue;
    
    double nr=Sqrt(b.r*b.r-dz*dz);
    rs.push_back(nr);
    xs.push_back(b.p.x);
    ys.push_back(b.p.y);
  }
  int n=rs.size();
  init(n);
  for(int i=0;i<n;i++){
    Point pa=Point( xs[i], ys[i], 0 );
    for(int j=0;j<i;j++){
      Point pb=Point( xs[j], ys[j], 0 );
      double dist=abs(pa-pb);
      if( dist < rs[i]+rs[j]+eps ){
        unite(i,j);
      }
    }
  }
  return Count;
}

int main(){
  while(1){
    cin>>N;
    if(N==0)break;
    A.clear();
    t.clear();
    for(int i=0;i<N;i++){
      int x,y,z,r;
      cin>>x>>y>>z>>r;
      A.push_back( Ball(Point(x,y,z),r) );
      t.push_back(z-r);
      t.push_back(z+r);
    }
    for(int i=0;i<N;i++){
      for(int j=0;j<i;j++){
        if( !isCrossBall(A[i],A[j]) )continue;
        Circle c=getCrossCircle(A[i],A[j]);
        t.push_back( maxz(c) );
        t.push_back( minz(c) );
      }
    }
    string ans="";
    sort(t.begin(),t.end());
    vector<double> tmp;

    for(int i=0;i<(int)t.size();i++){
      if(i>0&&eq(t[i],t[i-1]))continue;
      tmp.push_back(t[i]);
    }
    t=tmp;
    sort(t.begin(),t.end());
    
    int size=t.size();

    for(int i=1;i+1<size;i++){
      double a=(t[i-1]+t[i])*0.5;
      double b=(t[i+1]+t[i])*0.5;
      int ca=func(a);
      int cb=func(b);
      if(ca<cb)ans+="1";
      if(ca>cb)ans+="0";
    }
    ans="1"+ans+"0";
    cout<<ans.size()<<endl;
    cout<<ans<<endl;
  }
  return 0;
}

Measured memory_bytes: 3236