#include <bits/stdc++.h>
using namespace std;
int par[110]; 
int depth[110]; 
int siz[110];  
void init(){
	for(int i = 0; i < 110; i++){
		par[i] = i; depth[i] = 0; siz[i] = 1; 
	}
}
int find(int x){
	if(par[x] == x) return x;
	else return par[x] = find(par[x]); 
}
void unite(int x, int y){
	x = find(x); 
	y = find(y); 
	if(x == y) return;
	else if(depth[x] < depth[y]){
		par[x] = y; 
		siz[y] += siz[x]; 
	}else{
		par[y] = x; 
		siz[x] += siz[y];  
		if(depth[x] == depth[y]) depth[x] ++; 
	}
}
bool same(int x, int y){
	return find(x) == find(y); 
}
int sz(int x){
	return siz[find(x)]; 
}
int main(){
	ios::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
	int N; cin >> N; 
	int X[110], Y[110]; 
	for(int i = 1; i <= N; i++){
		cin >> X[i] >> Y[i]; 
	}
	double ok = 0; double ng = 114.514; 
	int T = 64; 
	while(T--){
		init(); 
		double mid = (ok + ng) * 0.5; 
 		init(); 
		for(int i = 1; i <= N; i++){
			if(Y[i] + mid * 2 >= 100) unite(0, i); 
			if(Y[i] - mid * 2 <= -100) unite(N+1, i); 
		}
		if(mid >= 100) unite(0, N+1);
		for(int i = 1; i <= N; i++){
			for(int j = i+1; j <= N; j++){
				double d = pow((X[j] - X[i]) * (X[j] - X[i]) + (Y[j] - Y[i]) * (Y[j] - Y[i]), 0.5); 
				if(d <= mid * 2) unite(i, j); 
			}
		}
		if(same(0, N+1)) ng = mid; 
		else ok = mid; 
	}
	cout.precision(12); 
	cout << ok << "\n"; 
}
#include <bits/stdc++.h>
#define rep(i, n) for (lli i = 0; i < (n); i++)
#define rrep(i, n) for (lli i = (n)-1; i >= 0; i--)
#define vall(x) (x).begin(), (x).end()
using namespace std;
namespace atcoder {}
using namespace atcoder;
using lli = long long int;
void YESNO(bool), YesNo(bool);
template <class T1, class T2> bool chmin(T1 &l, const T2 &r);
template <class T1, class T2> bool chmax(T1 &l, const T2 &r);
#define int long long int
int help(int st, int dst, int last) { return abs(st - dst) + abs(last - dst); }
signed main() {
  int n;
  cin >> n;
  map<int, vector<int>> m;
  rep(i, n) {
    int x, c;
    cin >> x >> c;
    m[c].push_back(x);
  }
  vector<vector<int>> dp(1e6, vector<int>(2, 1e18));
  vector<vector<int>> mem;

  for (auto &e : m) {
    sort(e.second.begin(), e.second.end());
    int f = e.second.front();
    int en = e.second.back();
    mem.push_back({f, en});
  }
  rep(i, mem.size()) {
    if (i) {
      chmin(dp[i][1], dp[i - 1][0] + help(mem[i - 1][0], mem[i][0], mem[i][1]));
      chmin(dp[i][0], dp[i - 1][0] + help(mem[i - 1][0], mem[i][1], mem[i][0]));
      chmin(dp[i][1], dp[i - 1][1] + help(mem[i - 1][1], mem[i][0], mem[i][1]));
      chmin(dp[i][0], dp[i - 1][1] + help(mem[i - 1][1], mem[i][1], mem[i][0]));
    } else {
      dp[i][0] = help(0, mem[i][1], mem[i][0]);
      dp[i][1] = help(0, mem[i][0], mem[i][1]);
    }
  }
  cout << min(dp[mem.size() - 1][0] + abs(mem.back()[0]),
              dp[mem.size() - 1][1] + abs(mem.back()[1]))
       << endl;

  return 0;
}

// -- lib
void YESNO(bool b) { cout << (b ? "YES" : "NO") << endl; }
void YesNo(bool b) { cout << (b ? "Yes" : "No") << endl; }

template <class T1, class T2> bool chmin(T1 &l, const T2 &r) {
  return (l > r) ? (l = r, true) : false;
}

template <class T1, class T2> bool chmax(T1 &l, const T2 &r) {
  return (l < r) ? (l = r, true) : false;
}

template <class T1, class T2> void vadd(vector<T1> &v, T2 x) {
  for (auto &s : v)
    s += T2(x);
}
