const md=1 shl 22-1; type tt=record x,y:int64; end; type ttt=record x,y,id1,id2:longint; end; Var ot:array[0..1500,1..3]of longint; p,list:array[0..1533]of tt; id1,id2,i,j,n,num,u,k,l,r:longint; ok:boolean; x,y:int64; last:array[0..md+1]of longint; next:array[0..1500*1503]of longint; a:array[0..1500*1503]of ttt; used:array[0..1533]of boolean; number:array[0..1533]of longint; procedure add(x,y,num1,num2:longint); var h:int64; begin h:=(int64(x)*int64(y))and md; inc(k); next[k]:=last[h]; last[h]:=k; a[k].x:=x; a[k].y:=y; a[k].id1:=num1; a[k].id2:=num2; end; procedure get(x,y:longint;var id1,id2:longint); var h:int64; j:longint; begin id1:=-1; h:=(int64(x)*int64(y))and md; j:=last[h]; while j>0 do begin if (a[j].x=x)and(a[j].y=y) then begin id1:=a[j].id1; id2:=a[j].id2; exit; end; j:=next[j]; end; end; function gcd(x,y:int64):int64; begin while (x>0)and(y>0) do if x>y then x:=x mod y else y:=y mod x; gcd:=x+y; end; procedure getmid(x1,y1,x2,y2:int64;var x,y:int64); var d:int64; begin // Writeln(x1,' ',y1,' ',x2,' ',y2); d:=(y1*y2) div gcd(y1,y2); x1:=x1*(d div y1); x2:=x2*(d div y2); x:=x1+x2; y:=d+d; d:=gcd(x,y); x:=x div d; y:=y div d; end; begin assign(input,'points.in'); reset(input); assign(output,'points.out'); rewrite(output); read(n); for i:=1 to n do begin read(p[i].x,p[i].y); if p[i].x=0 then l:=i; if (p[i].x=1)and(p[i].y=1) then r:=i; end; add(1,2,l,r); fillchar(used,sizeof(used),false); used[l]:=true; used[r]:=true; list[1]:=p[l]; list[2]:=p[r]; number[1]:=l; number[2]:=r; for i:=1 to n-2 do begin ok:=false; for j:=1 to n do if not used[j] then begin num:=j; get(p[j].x,p[j].y,id1,id2); if id1=-1 then continue; ok:=true; ot[i,1]:=j; ot[i,2]:=id1; ot[i,3]:=id2; list[i+2]:=p[j]; number[i+2]:=j; used[j]:=true; for u:=1 to i+1 do begin getmid(list[u].x,list[u].y,p[j].x,p[j].y,x,y); if y>1000000000 then continue; add(x,y,number[u],j); end; break; end; if not ok then begin Writeln('NO');Writeln(num);halt(0);end; end; Writeln('YES'); for i:=1 to n-2 do Writeln(ot[i,1],' ',ot[i,2],' ',ot[i,3]); end.