{$undef debug}
{$undef outall}

{$ifdef debug}
{$A+,B-,D+,E+,F-,G+,I+,L+,N+,O-,P-,Q+,R+,S+,T-,V-,X+}
{$M 65520,0,655360}
{$else}
{$A+,B-,D+,E+,F-,G+,I+,L+,N+,O-,P-,Q-,R-,S-,T-,V-,X+}
{$M 16384,0,655360}
{$endif}

type vec = record
      x, y, z: shortint;
     end;

const maxv = 55;
{      truemin = 5; }

var a: array [-1..9, -1..9, -1..9] of integer;
    b: array [0..maxv] of record
         x, y, z, nn: integer;
         xl, xg, yl, yg, zl, zg: integer;
         fig: integer;
       end;
    tmp, rv, v: integer;
    min, nf: integer;
    mf: array [1..maxv] of integer;
    s1, s2, s3: boolean;
    smc, ft, fs: integer;
    f: array [1..4, 1..3] of integer;
    kasall: boolean;
    totkas: integer;
    order: array [1..4] of integer;
    v1, v2, v3, vv: vec;

const ort: array [1..6, 1..3] of integer =
           ((1, 0, 0), (-1, 0, 0),
            (0, 1, 0), (0, -1, 0),
            (0, 0, 1), (0, 0, -1));
      back: array [1..6] of integer = (2, 1, 4, 3, 6, 5);

procedure Nearnum(i: integer);
var x1, y1, z1: integer;
begin
  with b[i] do begin
    nn := 0;
    for x1 := x-1 to x+1 do
      for y1 := y-1 to y+1 do
        for z1 := z-1 to z+1 do
          if (abs(x1-x) + abs(y1-y) + abs(z1-z) = 1) and
             (a[x1,y1,z1] <> 0)
          then inc(nn);
  end;
end;

procedure ReadAll;
var i: integer;
begin
  assign(input, 'block.in'); reset(input);
  assign(output, 'block.out'); Rewrite(output);
  read(v);
  Fillchar(a, sizeof(a), 0);
  Fillchar(b, sizeof(b), 0);
  for i := 1 to v do
    with b[i] do begin
      read(x, y, z);
      a[x, y, z] := i;
      nn := 0;
      fig := 0;
    end;
  for i := 1 to v do NearNum(i);
  for i := 1 to v do
    with b[i] do begin
      xl := a[x-1,y,z];
      xg := a[x+1,y,z];
      yl := a[x,y-1,z];
      yg := a[x,y+1,z];
      zl := a[x,y,z-1];
      zg := a[x,y,z+1];
    end;
  close(input);
end;

procedure WriteOut; forward;

procedure TryThis;
begin
  min := nf;
  for tmp := 1 to v do
    mf[tmp] := b[tmp].fig;
  {$ifdef outall}
  if min = truemin then writeout;
  {$endif}
end;

function use(q: integer): boolean;
begin
  if q = 0 then use := False else
    with b[q] do
    if fig <> 0 then use := False else
    begin
      dec(rv);
      fig := nf;
      use := True;
    end;
end;

procedure deuse(q: integer);
begin
  with b[q] do begin
    fig := 0;
    inc(rv);
  end;
end;

procedure Rec1; forward;

{procedure nlt(x0,y0,z0,i: integer);
var nk, q1, q2, j, k: integer;
begin
  nk := a[x0,y0,z0];
  if use(nk) then begin
    for j := 1 to 6 do
      if j <> i then begin
        q1 := a[x0 + ort[j,1], y0 + ort[j,2], z0 + ort[j,3]];
        if use(q1) then
        begin
          for k := 1 to 6 do
            if (k <> i) and (k <> j) then begin
              q2 := a[x0 + ort[k,1], y0 + ort[k,2], z0 + ort[k,3]];
              if use(q2) then begin
                Rec1;
                deuse(q2);
              end;
            end;
          deuse(q1);
        end;
      end;
    deuse(nk);
  end;
end;}

procedure addnn(q,d: integer);
begin
  with b[q] do begin
    inc(b[xl].nn,d);
    inc(b[yl].nn,d);
    inc(b[zl].nn,d);
    inc(b[xg].nn,d);
    inc(b[yg].nn,d);
    inc(b[zg].nn,d);
  end;
end;

procedure Rec1;
var i, k, cb, cc: integer;
    this: array [1..4] of integer;

{  procedure nonline;
  var i: integer;
  begin
    use(cb);
    with b[cb] do
      for i := 1 to 6 do
        nlt(x + ort[i,1], y + ort[i,2], z + ort[i,3], back[i]);
    deuse(cb);
  end;}

  procedure Rec2(cb: integer);
  var i: integer;
  begin
    if cb = 0 then Exit;
    with b[cb] do begin
      if (fig <> 0) then Exit;
      { init }
      dec(rv);
      fig := nf;
      inc(cc);
      this[cc] := cb;
      addnn(cb, -1);
      { process }
      if cc <= 3 then
        for i := 1 to cc do
          with b[this[i]] do begin
            Rec2(xl); Rec2(xg);
            Rec2(yl); Rec2(yg);
            Rec2(zl); Rec2(zg);
          end;
      Rec1;
      { deinit }
      addnn(cb, 1);
      dec(cc);
      fig := 0;
      inc(rv);
    end;
  end;

begin
  { All is deconstructed }
  if rv = 0 then begin
    TryThis;
    Exit;
  end;

  {$ifdef outall}
  if nf >= min then Exit;
  {$else}
  if nf+1 >= min then Exit;
  {$endif}
  { Try to add figure }

  inc(nf);
  k := 10;
  for i := 1 to v do
    with b[i] do
      if (fig = 0) and (nn < k) then begin
        k := nn;
        cb := i;
      end;
  cc := 0;
{  if rv >= 4 then nonline; }
  Rec2(cb);

  dec(nf);
end;

procedure Solve;
begin
  nf := 0;
  min := 100;
  rv := v;
  Rec1;
end;

function same(axis: integer): boolean;
var i: integer;
begin
  same := false;
  for i := 1 to fs do
    if f[i,axis] <> f[1,axis] then exit;
  same := True;
end;

function samex(axis, ex: integer): byte;
var q, i: integer;
begin
  samex := 0;
  if ex = 1 then q := 2 else q := 1;
  for i := 1 to fs do
    if (i <> ex) and (f[i,axis] <> f[q,axis]) then exit;
  samex := 1;
end;

function smcx(ex: integer): integer;
begin
  smcx := samex(1,ex) + samex(2,ex) + samex(3,ex);
end;

function kas(i, j: integer): boolean;
begin
  kas := (abs(f[i,1]-f[j,1]) + abs(f[i,2]-f[j,2]) + abs(f[i,3]-f[j,3]) = 1);
end;

function tripod: boolean;
var i: integer;
begin
  tripod :=
    (smcx(1) = 2) or (smcx(2) = 2) or
    (smcx(3) = 2) or (smcx(4) = 2);
end;

function Kasfor(i: integer): integer;
var c, j: integer;
begin
  c := 0;
  for j := 1 to fs do
    if (j <> i) and (kas(i,j)) then inc(c);
  Kasfor := c;
end;

procedure GetKas;
var k, i, j: integer;
begin
  kasall := False;
  totkas := 0;
  for i := 1 to fs do begin
    k := 0;
    for j := 1 to fs do
      if kas(i, j) then inc(k);
    if k = fs-1 then kasall := True;
    inc(totkas, k);
  end;
  totkas := totkas div 2;
end;

procedure Detect;
var i, j, k: integer;
begin
  ft := -1;
  if fs <= 2 then begin ft := fs; exit; end;
  s1 := same(1);
  s2 := same(2);
  s3 := same(3);
  smc := byte(s1) + byte(s2) + byte(s3);
  if fs = 3 then begin
    case smc of
      1: ft := 4;
      2: ft := 3;
    end;
    exit;
  end;
  if fs = 4 then begin
    if smc = 2 then begin ft := 5; Exit; end;
    { planar figures }
    if smc = 1 then begin
      GetKas;
      if totkas = 4 then begin ft := 6; Exit; end;
      if totkas = 3 then
      begin
        if kasall then begin ft := 8; Exit; end;
        if tripod then begin ft := 7; exit; end;
        ft := 9; exit;
      end;
    end;
    { remaining three non-planar figures }
    GetKas;
    if kasall then begin ft := 12; Exit; end;
    { 2 figures }
    for i := 1 to 4 do
      if kasfor(i) = 1 then break;
    order[1] := i;
    for i := 4 downto 1 do
      if kasfor(i) = 1 then break;
    order[4] := i;
    for i := 1 to 4 do
      if (i <> order[1]) and (i <> order[4]) then
      begin
        if (kas(i,order[1])) then order[2] := i else order[3] := i;
      end;
    v1.x := f[order[2],1] - f[order[1],1];
    v1.y := f[order[2],2] - f[order[1],2];
    v1.z := f[order[2],3] - f[order[1],3];
    v2.x := f[order[3],1] - f[order[2],1];
    v2.y := f[order[3],2] - f[order[2],2];
    v2.z := f[order[3],3] - f[order[2],3];
    v3.x := f[order[4],1] - f[order[3],1];
    v3.y := f[order[4],2] - f[order[3],2];
    v3.z := f[order[4],3] - f[order[3],3];

    if (v3.x = v1.y*v2.z - v2.y*v1.z) and
       (v3.y = -(v1.x*v2.z - v2.x*v1.z)) and
       (v3.z = v1.x*v2.y - v1.y*v2.x) then ft := 11 else ft := 10;
  end;
end;

procedure Writeout;
var i, j: integer;
begin
  Writeln(min);
  for i := 1 to min do begin
    fillchar(f, sizeof(f), 0);
    fs := 0;
    for j := 1 to v do
      if mf[j] = i then begin
        inc(fs);
        f[fs,1] := b[j].x;
        f[fs,2] := b[j].y;
        f[fs,3] := b[j].z;
      end;
    Detect;
    Write(ft);
    if i < min then Write(' ') else Writeln;
  end;
end;

begin
  Readall;
  Solve;
  Writeout;
end.