#include <bits/stdc++.h>
using namespace std;
struct Point{
int x,y,n;
}pts[100005];
Point p0;
stack<Point> s;
vector<int> v(100005);
void swap_pts(Point &u,Point &v){
Point temp = u;
u = v;
v = temp;
}
int orientation(Point p,Point q,Point r)
{
int ans = (q.y-p.y)*(r.x-q.x) - (r.y - q.y)*(q.x-p.x);
if( ans == 0) // colinear
return 0;
return ans < 0 ? 2 : 1; // anticlock / clockwise
}
int distSq(Point a,Point b){
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y);
}
int compare(const void *a,const void *b){
Point *u = (Point*) a;
Point *v = (Point*) b;
int val = orientation(p0,*u,*v);
int dv = distSq(p0,*v);
int du = distSq(p0,*u);
if(val == 2)
return -1;
else if(val == 0 && dv > du)
return -1;
else if(val == 0 && dv == du && (*v).n < (*u).n)
return -1;
else
return 1;
}
void printStack(){
p0 = s.top();s.pop();
Point p2 = p0,p1;
double p = 0.0;
int j=0;
v[j++] = p0.n;
while(!s.empty()){
p1 = s.top();s.pop();
p += (double) sqrt(distSq(p2,p1));
p2 = p1;
v[j++] = p1.n;
}
p += (double) sqrt(distSq(p2,p0));
printf("%.2f\n",p);
for(int i = j - 1; i >=0; i--)
printf("%d ",v[i]);
printf("\n\n");
}
Point nextToTop(){
Point temp = s.top();
s.pop();
Point res = s.top();
s.push(temp);
return res;
}
bool checkConditions(int n){
if(n==1){
printf("0.00\n1\n\n");
return false;
}else if(n==2){
double p = (double) (2*sqrt(distSq(pts[0],pts[1])));
if(pts[1].y < pts[0].y || (pts[1].y==pts[0].y && pts[1].x < pts[0].x))
printf("%.2f\n%d %d\n\n",p,pts[1].n,pts[0].n);
else
printf("%.2f\n%d %d\n\n",p,pts[0].n,pts[1].n);
return false;
}else
return true;
}
void convexHull(int n){
int minval = 0;
for(int i = 1; i < n; i++)
if((pts[i].y < pts[minval].y) || (pts[i].y == pts[minval].y && pts[i].x < pts[minval].x))
minval = i;
swap_pts(pts[0],pts[minval]);
p0 = pts[minval];
qsort(&pts[1], n-1, sizeof(Point), compare);
int m = 1;
for(int i = 1; i < n; i++){
while(i < n-1 && (orientation(p0,pts[i],pts[i+1])==0))
i++;
pts[m] = pts[i];
m++;
}
if(!checkConditions(m))
return;
s.push(pts[0]);
s.push(pts[1]);
s.push(pts[2]);
for(int i = 3; i < m; i++){
while(orientation(nextToTop(),s.top(),pts[i])!=2)
s.pop();
s.push(pts[i]);
}
printStack();
}
int main(){
int tc;
scanf("%d",&tc);
while(tc--){
int n;
scanf("%d",&n);
for(int i = 0; i < n; i++){
scanf("%d%d",&pts[i].x,&pts[i].y);
pts[i].n = i+1;
}
if(checkConditions(n))
convexHull(n);
}
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+Cgp1c2luZyBuYW1lc3BhY2Ugc3RkOwoKc3RydWN0IFBvaW50ewogICAgaW50IHgseSxuOwp9cHRzWzEwMDAwNV07CgpQb2ludCBwMDsKc3RhY2s8UG9pbnQ+IHM7CnZlY3RvcjxpbnQ+IHYoMTAwMDA1KTsKCnZvaWQgc3dhcF9wdHMoUG9pbnQgJnUsUG9pbnQgJnYpewogICAgUG9pbnQgdGVtcCA9IHU7CiAgICB1ID0gdjsKICAgIHYgPSB0ZW1wOwp9CgppbnQgb3JpZW50YXRpb24oUG9pbnQgcCxQb2ludCBxLFBvaW50IHIpCnsKCWludCBhbnMgPSAocS55LXAueSkqKHIueC1xLngpIC0gKHIueSAtIHEueSkqKHEueC1wLngpOwoJaWYoIGFucyA9PSAwKSAvLyBjb2xpbmVhcgoJCXJldHVybiAwOwoJcmV0dXJuIGFucyA8IDAgPyAyIDogMTsgLy8gYW50aWNsb2NrIC8gY2xvY2t3aXNlCn0KCmludCBkaXN0U3EoUG9pbnQgYSxQb2ludCBiKXsKICAgIHJldHVybiAoYS54LWIueCkqKGEueC1iLngpICsgKGEueS1iLnkpKihhLnktYi55KTsKfQoKaW50IGNvbXBhcmUoY29uc3Qgdm9pZCAqYSxjb25zdCB2b2lkICAqYil7CiAgICBQb2ludCAqdSA9IChQb2ludCopIGE7CiAgICBQb2ludCAqdiA9IChQb2ludCopIGI7CiAgICBpbnQgdmFsID0gb3JpZW50YXRpb24ocDAsKnUsKnYpOwoKICAgIGludCBkdiA9IGRpc3RTcShwMCwqdik7CiAgICBpbnQgZHUgPSBkaXN0U3EocDAsKnUpOwoKICAgIGlmKHZhbCA9PSAyKQogICAgICAgIHJldHVybiAtMTsKICAgIGVsc2UgaWYodmFsID09IDAgJiYgZHYgPiBkdSkKICAgICAgICByZXR1cm4gLTE7CiAgICBlbHNlIGlmKHZhbCA9PSAwICYmIGR2ID09IGR1ICYmICgqdikubiA8ICgqdSkubikKICAgICAgICByZXR1cm4gLTE7CiAgICBlbHNlCiAgICAgICAgcmV0dXJuIDE7Cgp9Cgp2b2lkIHByaW50U3RhY2soKXsKICAgIHAwID0gcy50b3AoKTtzLnBvcCgpOwogICAgUG9pbnQgcDIgPSBwMCxwMTsKICAgIGRvdWJsZSBwID0gMC4wOwogICAgaW50IGo9MDsKICAgIHZbaisrXSA9IHAwLm47CiAgICAKICAgIHdoaWxlKCFzLmVtcHR5KCkpewogICAgICAgIHAxID0gcy50b3AoKTtzLnBvcCgpOwogICAgICAgIHAgKz0gKGRvdWJsZSkgc3FydChkaXN0U3EocDIscDEpKTsKICAgICAgICBwMiA9IHAxOwogICAgICAgIHZbaisrXSA9IHAxLm47CiAgICB9CiAgICBwICs9IChkb3VibGUpIHNxcnQoZGlzdFNxKHAyLHAwKSk7CiAgICBwcmludGYoIiUuMmZcbiIscCk7CgogICAgZm9yKGludCBpID0gaiAtIDE7IGkgPj0wOyBpLS0pCiAgICAgICAgcHJpbnRmKCIlZCAiLHZbaV0pOwogICAgcHJpbnRmKCJcblxuIik7Cn0KClBvaW50IG5leHRUb1RvcCgpewogICAgUG9pbnQgdGVtcCA9IHMudG9wKCk7CiAgICBzLnBvcCgpOwogICAgUG9pbnQgcmVzID0gcy50b3AoKTsKICAgIHMucHVzaCh0ZW1wKTsKICAgIHJldHVybiByZXM7Cn0KCmJvb2wgY2hlY2tDb25kaXRpb25zKGludCBuKXsKICAgIGlmKG49PTEpewogICAgICAgIHByaW50ZigiMC4wMFxuMVxuXG4iKTsKICAgICAgICByZXR1cm4gZmFsc2U7CiAgICB9ZWxzZSBpZihuPT0yKXsKICAgICAgICBkb3VibGUgcCAgPSAoZG91YmxlKSAoMipzcXJ0KGRpc3RTcShwdHNbMF0scHRzWzFdKSkpOwogICAgICAgIGlmKHB0c1sxXS55IDwgcHRzWzBdLnkgfHwgKHB0c1sxXS55PT1wdHNbMF0ueSAmJiBwdHNbMV0ueCA8IHB0c1swXS54KSkKICAgICAgICAgICAgcHJpbnRmKCIlLjJmXG4lZCAlZFxuXG4iLHAscHRzWzFdLm4scHRzWzBdLm4pOwogICAgICAgIGVsc2UKICAgICAgICAgICAgcHJpbnRmKCIlLjJmXG4lZCAlZFxuXG4iLHAscHRzWzBdLm4scHRzWzFdLm4pOwogICAgICAgIHJldHVybiBmYWxzZTsKICAgIH1lbHNlCiAgICAgICAgcmV0dXJuIHRydWU7Cn0KCnZvaWQgY29udmV4SHVsbChpbnQgbil7CiAgICBpbnQgbWludmFsID0gMDsKICAgIGZvcihpbnQgaSA9IDE7IGkgPCBuOyBpKyspCiAgICAgICAgaWYoKHB0c1tpXS55IDwgcHRzW21pbnZhbF0ueSkgfHwgKHB0c1tpXS55ID09IHB0c1ttaW52YWxdLnkgJiYgcHRzW2ldLnggPCBwdHNbbWludmFsXS54KSkKICAgICAgICAgICAgbWludmFsID0gaTsKCiAgICBzd2FwX3B0cyhwdHNbMF0scHRzW21pbnZhbF0pOwogICAgcDAgPSBwdHNbbWludmFsXTsKCiAgICBxc29ydCgmcHRzWzFdLCBuLTEsIHNpemVvZihQb2ludCksIGNvbXBhcmUpOwoKICAgIGludCBtID0gMTsKICAgIGZvcihpbnQgaSA9IDE7IGkgPCBuOyBpKyspewogICAgICAgIHdoaWxlKGkgPCBuLTEgJiYgKG9yaWVudGF0aW9uKHAwLHB0c1tpXSxwdHNbaSsxXSk9PTApKQogICAgICAgICAgICBpKys7CiAgICAgICAgcHRzW21dID0gcHRzW2ldOwogICAgICAgIG0rKzsKICAgIH0KCiAgICBpZighY2hlY2tDb25kaXRpb25zKG0pKQogICAgICAgIHJldHVybjsKCiAgICBzLnB1c2gocHRzWzBdKTsKICAgIHMucHVzaChwdHNbMV0pOwogICAgcy5wdXNoKHB0c1syXSk7CgogICAgZm9yKGludCBpID0gMzsgaSA8IG07IGkrKyl7CiAgICAgICAgd2hpbGUob3JpZW50YXRpb24obmV4dFRvVG9wKCkscy50b3AoKSxwdHNbaV0pIT0yKQogICAgICAgICAgICBzLnBvcCgpOwogICAgICAgIHMucHVzaChwdHNbaV0pOwogICAgfQogICAgCiAgICBwcmludFN0YWNrKCk7Cn0KCmludCBtYWluKCl7CiAgICBpbnQgdGM7CiAgICBzY2FuZigiJWQiLCZ0Yyk7CiAgICB3aGlsZSh0Yy0tKXsKICAgICAgICBpbnQgbjsKICAgICAgICBzY2FuZigiJWQiLCZuKTsKICAgICAgICBmb3IoaW50IGkgPSAwOyBpIDwgbjsgaSsrKXsKICAgICAgICAgICAgc2NhbmYoIiVkJWQiLCZwdHNbaV0ueCwmcHRzW2ldLnkpOwogICAgICAgICAgICBwdHNbaV0ubiA9IGkrMTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgaWYoY2hlY2tDb25kaXRpb25zKG4pKQogICAgICAgICAgICBjb252ZXhIdWxsKG4pOwoKICAgIH0KICAgIHJldHVybiAwOwp9