#include<bits/stdc++.h>
#define int long long
#define ld long double
#define pdd pair<ld,ld>
#define pii pair<int,int>
#define fi first
#define se second
#define pb emplace_back
using namespace std;
namespace IO{
const int maxn=(1<<20);char *p1,*p2,buf[maxn];
#define gc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,maxn,stdin),p1==p2)?EOF:*p1++)
int read(){
int f=1,k=0;char c;
while(!isdigit(c=gc()))if(c=='-')f=-1;
while(isdigit(c))k=k*10+c-48,c=gc();
return f*k;
}
void write(int k,char c){
if(k<0){putchar('-');k=-k;}
char st[21];int top=0;
do{st[++top]=(k%10)|48,k/=10;}while(k);
while(top)putchar(st[top--]);
putchar(c);
}
}using namespace IO;
const int N=1e4+10;
auto *it=new unsigned;
mt19937 rnd(time(0)^(*it));
const ld pi2=acos(-1)*2,M=1;
pdd P[N];int K,n,x,y,top;bool flag[N];
void add(ld x,ld y){P[++top]={x,y};}
int rd(){return (rnd()%4?1:-1)*(rnd()%K+1);}
namespace Andrew{
#define x fi
#define y se
int st[N],top;
ld Cross(pdd a,pdd b,pdd c){
return (b.x-a.x)*(c.y-a.y)-(b.y-a.y)*(c.x-a.x);
}
void solve(int n){
sort(P+1,P+1+n);int ans=0;
for(int i=1;i<=n;++i){
while(top>1&&Cross(P[st[top-1]],P[st[top]],P[i])<=0)--top;
st[++top]=i;
}
int t=top;
for(int i=n;i>=1;--i){
while(top>t&&Cross(P[st[top-1]],P[st[top]],P[i])<=0)--top;
st[++top]=i;
}
for(int i=top;i>=1;--i)ans+=!flag[st[i]],flag[st[i]]=1;
write(ans,'\n');memset(flag,0,sizeof flag);
for(int i=top;i>=1;--i){
if(flag[st[i]])continue;
write(P[st[i]].x,' ');write(P[st[i]].y,'\n');
flag[st[i]]=1;
}
write(n-ans,'\n');
for(int i=1;i<=n;++i)
if(!flag[i])write(P[i].x,' '),write(P[i].y,' '),write(rd(),'\n');
}
#undef x
#undef y
}
signed main(){
n=10000;K=1000;
for(int i=1;i<=n;++i){
x=rd(),y=rd();
add(x,y);
}
Andrew::solve(n);
return 0;
}