#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct pnode
{
int x,y,len;
};
pnode point[600];
//找出凸包第一点 依题目 y值最小,y值相等的情况下x值小
bool cmpid(pnode a,pnode b)
{
return a.y==b.y?a.x<b.x:a.y<b.y;
}
//计算两点的距离(平方
int dis(pnode a,pnode b)
{
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
//叉积
int crossproduct(pnode a,pnode b,pnode c)
{
return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
}
//级角排序
bool cmpoint(pnode a,pnode b)
{
int cp = crossproduct(point[0],a,b);
if( cp==0 )
return a.len < b.len;//两点共线 则按距离小-》大排
else
return cp>0;
}
void output( int n )
{
if(n<=2)
puts("0");
else
{
printf("%d\n",n);
for( int i = 0;i<n;++i)
printf("%d %d\n",point[i].x,point[i].y );
}
}
void graham( int n)
{
sort(point ,point+n,cmpid);
int i;
for( i = 1; i<n;++i)
point[i].len = dis(point[0],point[i]);
sort(point+1,point+n,cmpoint);
//计算凸包
int top = 1;
for( i = 2;i<n;++i)
{
while( top>0 &&crossproduct(point[top-1],point[top],point[i])<=0 )
--top;
point[++top] = point[i];
}
point[++top] = point[0];
//删除不是拐点的点
int now = 1;
for( i = 2; i<=top;++i)
{
if( crossproduct(point[now-1],point[now],point[i]) )
point[++now] = point[i];
else
point[now] = point[i];
}
output(now+1);
}
int main()
{
// freopen("in.txt","r",stdin);
int cas;
cin>>cas;
printf("%d\n",cas);
while(cas--)
{
int n;
cin>>n;
for( int i = 0;i <n;++i)
{
scanf("%d %d",&point[i].x,&point[i].y );
}
graham(n);
int t;
if( cas )
{
cin>>t;
puts("-1");
}
}
return 0;
}