#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, srt, end) for (long long i = (srt); i < (long long)(end); i++)
// For debug
// Ref: https://qiita.com/ysuzuki19/items/d89057d65284ba1a16ac
#define dump(var)  do{std::cerr << #var << " : ";view(var);}while(0)
template<typename T> void view(T e){std::cerr << e << "\n";}
template<typename T> void view(const std::vector<T>& v){for(const auto& e : v){ std::cerr << e << " "; } std::cerr << "\n";}
template<typename T> void view(const std::vector<std::vector<T> >& vv){ std::cerr << "\n"; for(const auto& v : vv){ view(v); } }
template<typename T> void dump_cout(const T& v) { for(long long i = 0; i < v.size(); i++) std::cout << v[i] << (i == v.size()-1 ? "\n" : " "); }

void solve() {
    ll n, m;
    cin >> n >> m;
    vector<vector<bool>> G(n, vector<bool>(n, false));
    rep(i, 0, m) {
        ll a, b;
        cin >> a >> b;
        a--; b--;
        G[a][b] = G[b][a] = true;
    }
    vector<bool> ok(1<<n, true);
    rep(bit, 0, 1<<n) {
        vector<ll> vs;
        rep(i, 0, n) if(bit & (1<<i)) vs.push_back(i);
        rep(i, 0, vs.size()) {
            if(!ok[bit]) break;
            rep(j, i+1, vs.size()) {
                if(!ok[bit]) break;
                if(!G[vs[i]][vs[j]]) ok[bit] = false;
            }
        } 
    }
    const ll inf = 1LL<<60;
    vector<ll> dp(1<<n, inf);
    dp[0] = 0;
    rep(bit, 0, 1<<n) {
        if(dp[bit] >= inf) continue;
        ll cbit = (1<<n) - 1 - bit;
        for(ll add = cbit; ; add = (add-1) & cbit) {
            if(!add) break;
            if(ok[add]) dp[bit|add] = min(dp[bit|add], dp[bit]+1);
        }
    }
    cout << dp[(1<<n)-1] << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    solve();
    return 0;
}

#include <iostream>
#include <algorithm>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <string.h>
#include <vector>
#include <queue>
#include <cmath>
#include <complex>
#include <functional>
#include <numeric>
#include <iomanip>
#include <cassert>
#include <random>
#include <chrono>

/* #include <atcoder/all> */
/* using namespace atcoder; */
using namespace std;

void debug_out(){ cout << "\n"; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  cout << H << " ";
  debug_out(T...);
}
#ifdef _DEBUG
#define debug(...) debug_out(__VA_ARGS__)
#else
#define debug(...)
#endif

#define SPBR(w, n) std::cout<<(w + 1 == n ? '\n' : ' ');
#define YES cout << "YES" << endl
#define Yes cout << "Yes" << endl
#define NO cout << "NO" << endl
#define No cout << "No" << endl
#define ALL(i) (i).begin(), (i).end()
#define FOR(i, a, n) for(int i=(a);i<(n);++i)
#define RFOR(i, a, n) for(int i=(n)-1;i>=(a);--i)
#define REP(i, n) for(int i=0;i<int(n);++i)
#define RREP(i, n) for(int i=int(n)-1;i>=0;--i)
#define IN(a, x, b) (a<=x && x<b)
#define OUT(a, x, b) (x<a || b<=x)
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }

#define int ll
using ll = long long;
using ull = unsigned long long;
using ld = long double;
const ll MOD = 1000000007;
/* const ll MOD = 998244353; */
const ll INF = 1ll<<60;
const double PI = acos(-1);

struct INIT { INIT(){
  cin.tie(0); ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);
}}INIT;

vector<int> compress(vector<int> &v){
  int N = v.size();
  vector<int> ret = v;
  sort(ALL(ret));
  ret.erase(unique(ALL(ret)), ret.end());
  REP(i, N){
    v[i] = lower_bound(ALL(ret), v[i])-ret.begin();
  }
  return ret;
}

// a -> b -> cの最短距離
int f(int a, int b, int c){
  return abs(b-a) + abs(c-b);
}


signed main() {
  int N;
  cin >> N;

  vector<int> X(N), C(N);
  REP(i, N) cin >> X[i] >> C[i];

  vector<int> c = compress(C);

  REP(i, C.size()){
    C[i]++;
  }

  int MAX = 0;
  REP(i, N) chmax(MAX, C[i]);
  MAX++;

  vector<int> r(MAX, -INF), l(MAX, INF);
  REP(i, N){
    chmax(r[C[i]], X[i]);
    chmin(l[C[i]], X[i]);
  }
  r[0] = 0;
  l[0] = 0;

  // dp[i][j]: i番目の左右に来た時の最小値
  vector<vector<int>> v(MAX, vector<int>(2, INF));
  v[0][0] = 0;
  v[0][1] = 0;
  FOR(i, 1, MAX){
    chmin(v[i][0], v[i-1][0]+f(r[i-1], l[i], r[i]));
    chmin(v[i][0], v[i-1][1]+f(l[i-1], l[i], r[i]));

    chmin(v[i][1], v[i-1][0]+f(r[i-1], r[i], l[i]));
    chmin(v[i][1], v[i-1][1]+f(l[i-1], r[i], l[i]));
  }

  int ans = min(v[MAX-1][0]+abs(r[MAX-1]), v[MAX-1][1]+abs(l[MAX-1]));

  cout << ans << "\n";

  return 0;
}
