#include<bits/stdc++.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define HUGE_NUM 99999999999999999
#define MOD 1000000007
//#define EPS 0.000000001
using namespace std;


#define EPS 0.00000001

#define SIZE 15

struct Point{
	Point(double arg_x,double arg_y){
		x = arg_x;
		y = arg_y;
	}

	Point(){
		x = y = 0.0;
	}

	Point operator + (Point p){ return Point(x+p.x,y+p.y); }
	Point operator - (Point p){ return Point(x-p.x,y-p.y);}
	Point operator * (double a){ return Point(a*x,a*y); }
	Point operator / (double a){ return Point(x/a,y/a); }

	double abs(){ return sqrt(norm()); }
	double norm(){ return x*x + y*y; }

	bool operator<(const Point &p) const{
		return x != p.x? x < p.x: y < p.y;
	}

	bool operator == (const Point &p) const{
		return fabs(x-p.x) < EPS && fabs(y-p.y) < EPS;
	}

	double x,y;
};

typedef Point Vector;

struct Line{
	Line(){

	}
	Line(Point a,Point b){
		p[0] = a;
		p[1] = b;
	}
	Point p[2];
};

int N;
int POW[SIZE];
bool FLG;
double NUM = 100;
double dp[5][1 << 10][10][10],ans;
Point point[SIZE];


double calc_dist(Point A,Point B){

	return sqrt((A.x-B.x)*(A.x-B.x)+(A.y-B.y)*(A.y-B.y));
}


Point calc_minus(Point a,Point b){
    Point ret;

    ret.x = a.x-b.x;
    ret.y = a.y-b.y;

    return ret;
}

double calc_len(Vector a){
    return sqrt(a.x*a.x+a.y*a.y);
}

double calc_slope(Line A){

	if(fabs(A.p[0].x-A.p[1].x) < EPS){

		return DBL_MAX;

	}else if(fabs(A.p[0].y-A.p[1].y) < EPS){

		return 0;

	}else{

		return (A.p[1].y-A.p[0].y)/(A.p[1].x-A.p[0].x);
	}
}

double norm(Vector a){
	return a.x*a.x+a.y*a.y;
}

double abs(Vector a){
	return sqrt(norm(a));
}

double cross(Vector a,Vector b){
    return a.x*b.y-a.y*b.x;
}

double dot(Vector a,Vector b){
    return a.x*b.x + a.y*b.y;
}

int func(double x1,double y1,double x2, double y2, double xp, double yp){
	double naiseki,norm1,norm2,gaiseki;
	norm1 = sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
	norm2 = sqrt((xp-x1)*(xp-x1)+(yp-y1)*(yp-y1));
	naiseki = (xp-x1)*(x2-x1)+(yp-y1)*(y2-y1);
	gaiseki = (x2-x1)*(yp-y1)-(xp-x1)*(y2-y1);
	if(gaiseki > EPS){
		return 1;
	}else if(gaiseki < -EPS){
		return -1;
	}
	if(naiseki < -EPS){
		return 2;
	}

	if(norm1 < norm2){
		return -2;
	}
	return 0;
}


//★★直線ではなく、線分の交差判定★★
bool is_Cross(Line a,Line b){

	if(func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[0].x,b.p[0].y)*
			func(a.p[0].x,a.p[0].y,a.p[1].x,a.p[1].y,b.p[1].x,b.p[1].y) <= 0 &&
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[0].x,a.p[0].y)*
			func(b.p[0].x,b.p[0].y,b.p[1].x,b.p[1].y,a.p[1].x,a.p[1].y) <= 0){
		return true;
	}
	return false;
}

//線分ではなく直線と点の距離
double getDistanceLP(Line l,Point p){
    return fabs(cross(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0]))/calc_len(calc_minus(l.p[1],l.p[0])));
}

//点と線分の距離
double getDistanceSP(Line l,Point p){
	if(dot(calc_minus(l.p[1],l.p[0]),calc_minus(p,l.p[0])) < 0.0)return calc_len(calc_minus(p,l.p[0]));
	if(dot(calc_minus(l.p[0],l.p[1]),calc_minus(p,l.p[1])) < 0.0)return calc_len(calc_minus(p,l.p[1]));
	return getDistanceLP(l,p);
}

//線分と線分の距離
double getDistance(Line A,Line B){
	if(is_Cross(A,B))return 0.0;
	return min(min(getDistanceSP(A,B.p[0]),getDistanceSP(A,B.p[1])),
			min(getDistanceSP(B,A.p[0]),getDistanceSP(B,A.p[1])));
}


//交点を求める関数
Point calc_Cross_Point(double x1,double x2,double x3,double x4,double y1,double y2,double y3,double y4){
	Point ret;
	ret.x = ((x2-x1)*(y3*(x4-x3)+x3*(y3-y4))-(x4-x3)*(y1*(x2-x1)+x1*(y1-y2)))/((y2-y1)*(x4-x3)-(y4-y3)*(x2-x1));
	if(x1 != x2){
		ret.y = ((y2-y1)*ret.x+y1*(x2-x1)+x1*(y1-y2))/(x2-x1);
	}else{
		ret.y = ((y4-y3)*ret.x+y3*(x4-x3)+x3*(y3-y4))/(x4-x3);
	}
	return ret;
}

//インタフェース関数
Point calc_Cross_Point(Point a,Point b,Point c,Point d){
	return calc_Cross_Point(a.x,b.x,c.x,d.x,a.y,b.y,c.y,d.y);
}

Point calc_Cross_Point(Line A,Line B){

	if(getDistanceSP(B,A.p[0]) < EPS){

		return A.p[0];

	}else if(getDistanceSP(B,A.p[1]) < EPS){

		return A.p[1];

	}else if(getDistanceSP(A,B.p[0]) < EPS){

		return B.p[0];

	}else if(getDistanceSP(A,B.p[1]) < EPS){

		return B.p[1];
	}

	return calc_Cross_Point(A.p[0],A.p[1],B.p[0],B.p[1]);
}


void recursive(int state,int pre_pre,int pre,int num_turn,int max_turn,double sum_dist){

	if(sum_dist >= ans)return;

	if(state == POW[N]-1){

		ans = min(ans,sum_dist);

		FLG = true;
		return;
	}
	if(sum_dist > dp[num_turn][state][pre_pre][pre]+EPS){

		return;
	}

	int next_state;
	double next_dist;

	Line from,to,PRE,NEXT;

	from.p[0] = point[pre_pre];
	from.p[1] = point[pre];
	double	tmp_slope = calc_slope(from),tmp_slope2;
	int next_num_turn;

	//preで降り曲がる
	for(int next = 0; next < N; next++){
		if(next == pre_pre || next == pre)continue;

		next_dist = sum_dist+calc_dist(point[pre],point[next]);
		next_state = state|POW[next]; //再訪あり

		to.p[0] = point[pre];
		to.p[1] = point[next];

		next_num_turn = num_turn+1;
		tmp_slope2 = calc_slope(to);
		if(fabs(tmp_slope-tmp_slope2) < EPS){ //傾きが同じ

			//引き返しを弾く
			if(fabs(tmp_slope2-DBL_MAX) < EPS){

				if((point[pre_pre].y > point[pre].y && point[pre].y > point[next].y) ||
						(point[pre_pre].y < point[pre].y && point[pre].y < point[next].y)){

					next_num_turn -= 1;
				}

			}else{

				if((point[pre_pre].x > point[pre].x && point[pre].x > point[next].x) ||
						(point[pre_pre].x < point[pre].x && point[pre].x < point[next].x)){

					next_num_turn -= 1;
				}
			}
		}
		if(next_num_turn > max_turn)continue;

		if(dp[next_num_turn][next_state][pre][next] > next_dist+EPS){
			dp[next_num_turn][next_state][pre][next] = next_dist;

			recursive(next_state,pre,next,next_num_turn,max_turn,next_dist);
		}
	}

	if(num_turn == max_turn)return;

	if(fabs(tmp_slope-DBL_MAX) < EPS){ //垂直

		if(point[pre_pre].y > point[pre].y){

			from.p[1] = Point(point[pre].x,point[pre].y-NUM);

		}else{

			from.p[1] = Point(point[pre].x,point[pre].y+NUM);
		}

	}else{

		if(point[pre_pre].x < point[pre].x){ //右方に伸ばす

			from.p[1] = Point(point[pre].x+NUM,point[pre].y+NUM*tmp_slope);

		}else{ //左方に伸ばす

			from.p[1] = Point(point[pre].x-NUM,point[pre].y+(-NUM)*tmp_slope);
		}

	}

	PRE.p[0] = point[pre_pre];
	PRE.p[1] = point[pre];

	Line line;

	//新しい2点との交点を求める
	for(int next = 0; next < N; next++){
		if(next == pre || next == pre_pre)continue;
		for(int next_next = 0; next_next < N; next_next++){
			if(next_next == next || next_next == pre || next_next == pre_pre)continue;

			to.p[0] = point[next_next];
			to.p[1] = point[next];
			tmp_slope = calc_slope(to);

			if(fabs(tmp_slope-DBL_MAX) < EPS){ //垂直

				if(point[next_next].y > point[next].y){

					to.p[1] = Point(point[next].x,point[next].y-NUM);

				}else{

					to.p[1] = Point(point[next].x,point[next].y+NUM);
				}

			}else{

				if(point[next_next].x < point[next].x){ //右方に伸ばす

					to.p[1] = Point(point[next].x+NUM,point[next].y+NUM*tmp_slope);

				}else{ //左方に伸ばす

					to.p[1] = Point(point[next].x-NUM,point[next].y+(-NUM)*tmp_slope);
				}
			}

			NEXT.p[0] = point[next_next];
			NEXT.p[1] = point[next];

			Point cross_point = calc_Cross_Point(from,to);

			if(getDistanceSP(PRE,cross_point) < EPS || getDistanceSP(NEXT,cross_point) < EPS){
				continue;
			}
			if(calc_dist(point[pre_pre],cross_point) < calc_dist(point[pre],cross_point) ||
					calc_dist(point[next_next],cross_point) < calc_dist(point[next],cross_point)){
				continue;
			}
			next_dist = sum_dist+calc_dist(cross_point,point[pre])+calc_dist(cross_point,point[next]);
			next_dist += calc_dist(point[next],point[next_next]);

			next_state = state|(POW[next]|POW[next_next]);

			if(dp[num_turn+1][next_state][next][next_next] > next_dist+EPS){

				dp[num_turn+1][next_state][next][next_next] = next_dist;

				recursive(next_state,next,next_next,num_turn+1,max_turn,next_dist);
			}
		}
	}
}

void init(int max_count){

	for(int count = 0; count <= max_count; count++){
		for(int state = 0; state < POW[N]; state++){
			for(int pre_pre = 0; pre_pre < N; pre_pre++){
				for(int pre = 0; pre < N; pre++){

					dp[count][state][pre_pre][pre] = BIG_NUM;
				}
			}
		}
	}
}



void func(){

	for(int i = 0; i < N; i++){

		scanf("%lf %lf",&point[i].x,&point[i].y);
	}

	int turn = -1;
	FLG = false;
	ans = BIG_NUM;

	Line line;

	//設問より、turn回数は最大で4回
	for(int max_turn = 0; max_turn <= 4; max_turn++){

		init(max_turn);

		//最初の2点を選ぶ
		for(int pre_pre = 0; pre_pre < N; pre_pre++){
			for(int pre = 0; pre < N; pre++){

				if(pre == pre_pre)continue;

				int first_state = POW[pre_pre]+POW[pre];
				double first_dist = calc_dist(point[pre_pre],point[pre]);

				line.p[0] = point[pre_pre];
				line.p[1] = point[pre];

				dp[0][first_state][pre_pre][pre] = first_dist;
				vector<Point> vec;
				vec.push_back(point[pre_pre]);
				vec.push_back(point[pre]);

				recursive(first_state,pre_pre,pre,0,max_turn,first_dist);
			}
		}

		if(FLG){
			turn = max_turn;
			break;
		}
	}

	printf("%d %.10lf\n",turn,ans);
}

int main(){

	POW[0] = 1;
	for(int i = 1; i < SIZE; i++){

		POW[i] = POW[i-1]*2;
	}

	while(true){

		scanf("%d",&N);
		if(N == 0)break;

		func();
	}
	return 0;
}



Measured memory_bytes: 7204