#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <climits>
#include <ctime>
#include <queue>
#include <stack>
#include <algorithm>
#include <list>
#include <vector>
#include <set>
#include <map>
#include <iostream>
#include <deque>
#include <complex>
#include <string>
#include <iomanip>
#include <sstream>
#include <bitset>
#include <valarray>
#include <iterator>
using namespace std;
typedef long long int ll;
typedef unsigned int uint;
typedef unsigned char uchar;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<int, double> pid;
typedef vector<int> vi;

#define REP(i,x) for(int i=0;i<(int)(x);i++)
#define FOR(i,c) for(__typeof((c).begin())i=(c).begin();i!=(c).end();i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RFOR(i,c) for(__typeof((c).rbegin())i=(c).rbegin();i!=(c).rend();i++)
#define ALL(container) container.begin(), container.end()
#define RALL(container) container.rbegin(), container.rend()
#define SZ(container) ((int)container.size())
#define mp(a,b) make_pair(a, b)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );

template<class T> bool chmax(T &a, const T &b) { if (a<b) { a=b; return 1; } return 0; }
template<class T> bool chmin(T &a, const T &b) { if (a>b) { a=b; return 1; } return 0; }
template<class T> ostream& operator<<(ostream &os, const vector<T> &t) {
os<<"["; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"]"; return os;
}
template<class T> ostream& operator<<(ostream &os, const set<T> &t) {
os<<"{"; FOR(it,t) {if(it!=t.begin()) os<<","; os<<*it;} os<<"}"; return os;
}
template<class S, class T> ostream& operator<<(ostream &os, const pair<S,T> &t) { return os<<"("<<t.first<<","<<t.second<<")";}
#include <complex>
#include <cmath>
#define EPS 1.0e-10
#define PI 3.1415926535897932384 

// 実数の符号関数
inline int signum(double x) { return (abs(x) < EPS ? 0 : x > 0 ? 1 : -1); }
//XY座標
#define X real()
#define Y imag()
// 点
typedef complex<double> P;
 

// 線分・半直線・直線
struct L { 
	P pos, dir;
	L(){}
	L(P p, P d):pos(p),dir(d){}
};
 
// 多角形
typedef vector<P> G;
 
// 円
struct C { P p; double r; };

// std::norm はabs(p)*abs(p)なので遅い
inline double norm(P p){
	return p.X*p.X+p.Y*p.Y;
}

// 二つのベクトルの内積を計算する
inline double inp(const P& a, const P& b) {
	return (conj(a)*b).real();
}
 
// 二つのベクトルの外積を計算する
inline double outp(const P& a, const P& b) {
	return (conj(a)*b).imag();
}

inline int ccw(const P& p, const P& r, const P& s) {
    P a(r-p), b(s-p);
    int sgn = signum(outp(a, b));
    if (sgn != 0)
        return sgn;
    if (a.real()*b.real() < -EPS || a.imag()*b.imag() < -EPS)
        return -1;
    if (norm(a) < norm(b) - EPS)
        return 1;
    return 0;
}

// ベクトルpをベクトルbに射影したベクトルを計算する
inline P proj(const P& p, const P& b) {
	return b*inp(p,b)/norm(b);
}
 
// 点pから直線lに引いた垂線の足となる点を計算する
inline P perf(const L& l, const P& p) {
	L m(l.pos - p, l.dir);
	return (p + (m.pos - proj(m.pos, m.dir)));
}
 
// 線分sを直線bに射影した線分を計算する
inline L proj(const L& s, const L& b) {
	 return L(perf(b, s.pos), proj(s.dir, b.dir));
}

bool ll_intersects(const L& l, const L& m) {
    return (abs(outp(l.dir, m.dir)) > EPS || abs(outp(l.dir, m.pos-l.pos)) < EPS);
}
P line_cross(const L& l, const L& m) {
    double num = outp(m.dir, m.pos-l.pos);
    double denom = outp(m.dir, l.dir);
    return P(l.pos + l.dir*num/denom);
}
bool ls_intersects(const L& l, const L& s) {
    return (signum(outp(l.dir, s.pos-l.pos)) *
            signum(outp(l.dir, s.pos+s.dir-l.pos)) <= 0);
}
bool sp_intersects(const L& s, const P& p) {
    return ( abs(s.pos - p) + abs(s.pos + s.dir - p) - abs(s.dir) < EPS );
}
bool ss_intersects(const L& s, const L& t) {
    return (ccw(s.pos, s.pos+s.dir, t.pos) *
            ccw(s.pos, s.pos+s.dir, t.pos+t.dir) <= 0 &&
            ccw(t.pos, t.pos+t.dir, s.pos) *
            ccw(t.pos, t.pos+t.dir, s.pos+s.dir) <= 0);
}
double lp_distance(const L& l, const P& p) {
    return abs(outp(l.dir, p-l.pos) / abs(l.dir));
}
double ll_distance(const L& l, const L& m) {
    return (ll_intersects(l, m) ? 0 : lp_distance(l, m.pos));
}
double ls_distance(const L& l, const L& s) {
    if (ls_intersects(l, s))
        return 0;
    return min(lp_distance(l, s.pos), lp_distance(l, s.pos+s.dir));
}
double sp_distance(const L& s, const P& p) {
    const P r = perf(s, p);
    const double pos = ((r-s.pos)/s.dir).real();
    if (-EPS <= pos && pos <= 1 + EPS)
        return norm(r - p);
    return min(norm(s.pos - p),
               norm(s.pos+s.dir - p));
}
double ss_distance(const L& s, const L& t) {
    if (ss_intersects(s, t))
        return 0;
    return (max(sp_distance(s, t.pos), max(sp_distance(s, t.pos+t.dir), max(sp_distance(t, s.pos), sp_distance(t, s.pos+s.dir)))));
}


const int INF = 1<<28;
const int MOD = 1000000007;


int n;

double dp[1<<10][11][25][25];
main(){
	int i,j;
	while(cin >> n, n){
		REP(i, 1<<n)REP(j, n)REP(k, 22)REP(l, 22) dp[i][j][k][l] = 10000;
		double ans(10000);
		vector<P> p(n);
		REP(i, n){
			double x, y;
			cin >> x >> y;
			p[i] = P(x, y);
		}
		vector<pii> dr;
		REP(i, n)REP(j, i){
			P dir = p[i]-p[j];
			int g = __gcd((int)abs(dir.X), (int)abs(dir.Y));
			dr.emplace_back((int)dir.X/g, (int)dir.Y/g);
			dr.emplace_back(-(int)dir.X/g, (int)dir.Y/g);
			dr.emplace_back((int)dir.X/g, -(int)dir.Y/g);
			dr.emplace_back(-(int)dir.X/g, -(int)dir.Y/g);
		}
		sort(ALL(dr));
		UNIQUE(dr);
		REP(i, 1<<n)REP(j, n)REP(d, dr.size()){
			int dx = dr[d].first;
			int dy = dr[d].second;
			double &t = dp[i][j][dx+10][dy+10];
			
			if(i == (1<<j)) t = .0;
			if(t > 9000) continue;
//			printf("dp[%d][%d][%d][%d] = (%d, %f)\n", i, j, dx, dy, t.first, t.second);
			if(i == (1<<n)-1){
				ans = min(ans, t);
				continue;
			}
			L l1(p[j], P(dx*200.0, dy*200.0));
			REP(k, n){
				if(1&(i>>k)) continue;
				int b = i | (1<<k);
				if(signum(sp_distance(l1, p[k])) == 0){
					chmin(dp[b][k][dx+10][dy+10], t + abs(p[j]-p[k]));
//					printf("!dq[%d][%d][%d][%d] = (%d, %f)\n", b, k, dx, dy, t.first, t.second + abs(p[j]-p[k]));
					continue;
				}
				P dir = p[k] - p[j];
				int g = __gcd((int)abs(dir.X), (int)abs(dir.Y));
				if(chmin(dp[b][k][(int)dir.X/g+10][(int)dir.Y/g+10], t + 1000 + abs(p[j]-p[k]))){
//					printf("dq[%d][%d][%d][%d] = (%d, %f)\n", b, k, (int)dir.X/g, (int)dir.Y/g, t.first+1, t.second + abs(p[j]-p[k]));
				}
				REP(l, n){
					if(1&(b>>l)) continue;
					L l2(p[k], (p[k]-p[l])*200.0);
					if(!ss_intersects(l1, l2)) continue;
					P is = line_cross(l1, l2);
					P dir = p[l] - p[k];
					int g = __gcd((int)(abs(dir.X)+EPS), (int)(abs(dir.Y)+EPS));
					chmin(dp[b][k][(int)dir.X/g+10][(int)dir.Y/g+10], t + 1000 + abs(p[j]-is) + abs(is-p[k]));
//					if(chmin(dp[b][k][(int)dir.X/g+10][(int)dir.Y/g+10], pid(t.first + 1, t.second + abs(p[j]-is) + abs(is-p[k]))) && t.second + abs(p[j]-is) + abs(is-p[k]) < 18.48683298)
//						printf("dq[%d][%d][%d][%d] = (%d, %f)\n", b, k, (int)dir.X/g, (int)dir.Y/g, t.first + 1, t.second + abs(p[j]-is) + abs(is-p[k]));
				}
			}
		}
		int t = (int)(ans)/1000;
		printf("%d %.9f\n", t, ans - t*1000);
	}
	return 0;
}

Measured memory_bytes: 56156