Problem:
Score : 900 points

Problem Statement

There are N squares in a row. The squares are numbered 1, 2, ..., N from left to right.

You have two pieces, initially placed on square A and B, respectively.
You will be asked to process Q queries of the following kind, in the order received:

Given an integer x_i, move one of the two pieces of your choice to square x_i.

Here, it takes you one second to move a piece one square.
That is, the time it takes to move a piece from square X to Y is |X-Y| seconds.

Your objective is to process all the queries in the shortest possible time.

You may only move the pieces in response to queries, and you may not move both pieces at the same time.
Also, it is not allowed to rearrange the order in which queries are given.
It is, however, allowed to have both pieces in the same square at the same time.

Constraints

1 ≤ N, Q ≤ 200,000

1 ≤ A, B ≤ N

1 ≤ x_i ≤ N

Input

Input is given from Standard Input in the following format:

N Q A B
x_1 x_2 ... x_Q

Output

Let the shortest possible time to process all the queries be X seconds. Print X.

Sample Input 1

8 3 1 8
3 5 1

Sample Output 1

7

All the queries can be processed in seven seconds, by:

moving the piece at square 1 to 3

moving the piece at square 8 to 5

moving the piece at square 3 to 1

Sample Input 2

9 2 1 9
5 1

Sample Output 2

4

The piece at square 9 should be moved first.

Sample Input 3

9 2 1 9
5 9

Sample Output 3

4

The piece at square 1 should be moved first.

Sample Input 4

11 16 8 1
1 1 5 1 11 4 5 2 5 3 3 3 5 5 6 7

Sample Output 4

21

Solution in C++14 (GCC 5.4.1) (judge verdict: Accepted)

#define _USE_MATH_DEFINES
#include <cstdio>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <complex>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <limits>
#include <climits>
#include <cfloat>
#include <functional>
#include <iterator>
using namespace std;

// セグメント木（遅延評価あり）
class SegmentTree
{
private:
    typedef long long T1;
    typedef long long T2;

    // データの初期値、以下の条件を満たすこと
    // uniteData(v, INIT_DATA) == v
    static const T1 INIT_DATA;
    // 遅延の初期値、以下の条件を満たすこと
    // updateData(prev, size, INIT_DELAY) == prev
    // updateDelay(x, INIT_DELAY) == x
    static const T2 INIT_DELAY;

    // 長さがsizeの区間における前回の計算結果prevに対して、
    // 区間の各要素にパラメータxを用いた更新処理を適用した後の計算結果を返す
    T1 updateData(T1 prev, int size, T2 x){
        return prev + x;
    }
    // パラメータx1,x2による2つの更新処理を順に適用した場合に対して、
    // 同じ結果になるような1つの更新処理のパラメータを返す
    T2 updateDelay(T2 x1, T2 x2){
        return x1 + x2;
    }
    // 2つの区間の計算結果v1,v2に対して、
    // その2つの区間を統合した区間における計算結果を返す
    T1 uniteData(T1 v1, T1 v2){
        return min(v1, v2);
    }

    int n;
    vector<T1> data;
    vector<T2> delay;
    void updateTree(int a, int b, int k, int l, int r, T2 x){
        if(a <= l && r <= b){
            data[k] = updateData(data[k], r - l + 1, x);
            delay[k] = updateDelay(delay[k], x);
        }
        else if(a <= r && l <= b){
            for(int i=0; i<2; ++i){
                data[k*2+1+i] = updateData(data[k*2+1+i], (r - l + 1) / 2, delay[k]);
                delay[k*2+1+i] = updateDelay(delay[k*2+1+i], delay[k]);
            }
            delay[k] = INIT_DELAY;
            updateTree(a, b, k*2+1, l, (l+r)/2, x);
            updateTree(a, b, k*2+2, (l+r+1)/2, r, x);
            data[k] = uniteData(data[k*2+1], data[k*2+2]);
        }
    }
    T1 getValue(int a, int b, int k, int l, int r){
        if(a <= l && r <= b){
            return data[k];
        }
        else if(a <= r && l <= b){
            T1 v1 = getValue(a, b, k*2+1, l, (l+r)/2);
            T1 v2 = getValue(a, b, k*2+2, (l+r+1)/2, r);
            return uniteData(v1, v2);
        }
        else{
            return INIT_DATA;
        }
    }
public:
    SegmentTree(int n0){
        n = 1;
        while(n < n0)
            n *= 2;
        data.assign(2*n-1, INIT_DATA);
        delay.assign(2*n-1, INIT_DELAY);
    }
    SegmentTree(const vector<T1>& v) : SegmentTree((int)v.size()){
        for(unsigned i=0; i<v.size(); ++i)
            data[n-1+i] = v[i];
        for(int k=n-2; k>=0; --k)
            data[k] = uniteData(data[k*2+1], data[k*2+2]);
    }
    // 区間[a,b]の要素にパラメータxによる更新処理を適用
    void update(int a, int b, T2 x){
        updateTree(a, b, 0, 0, n-1, x);
    }
    // 区間[a,b]の計算結果を返す
    T1 get(int a, int b){
        updateTree(a, b, 0, 0, n-1, 0);
        return getValue(a, b, 0, 0, n-1);
    }
};
const SegmentTree::T1 SegmentTree::INIT_DATA = LLONG_MAX;
const SegmentTree::T2 SegmentTree::INIT_DELAY = 0;

const long long INF = LLONG_MAX / 4;

int main()
{
    int n, q, a, b;
    cin >> n >> q >> a >> b;
    -- a;
    -- b;
    if(b < a)
        swap(a, b);

    vector<int> x(q);
    for(int i=0; i<q; ++i){
        cin >> x[i];
        -- x[i];
    }

    vector<long long> tmp1(n, INF);
    vector<long long> tmp2(n, INF);
    tmp1[a] = abs(b - x[0]) - a;
    tmp1[b] = abs(a - x[0]) - b;
    tmp2[a] = abs(b - x[0]) + a;
    tmp2[b] = abs(a - x[0]) + b;
    SegmentTree st1(tmp1);
    SegmentTree st2(tmp2);

    for(int i=1; i<q; ++i){
        long long cost = st1.get(x[i-1], x[i-1]) + x[i-1] + abs(x[i] - x[i-1]);
        cost = min(cost, st1.get(0, x[i]) + x[i]);
        cost = min(cost, st2.get(x[i], n-1) - x[i]);
        long long add1 = cost - x[i-1] - st1.get(x[i-1], x[i-1]);
        cerr << st2.get(x[i-1], x[i-1]) << endl;
        cerr << st2.get(x[i-1], x[i-1]) << endl;
        long long add2 = cost + x[i-1] - st2.get(x[i-1], x[i-1]);
        st1.update(x[i-1], x[i-1], add1);
        st2.update(x[i-1], x[i-1], add2);

        long long add = abs(x[i] - x[i-1]);
        st1.update(0, x[i-1]-1, add);
        st1.update(x[i-1]+1, n-1, add);
        st2.update(0, x[i-1]-1, add);
        st2.update(x[i-1]+1, n-1, add);
    }

    long long ans = INF;
    for(int i=0; i<n; ++i)
        ans = min(ans, st1.get(i, i) + i);
    cout << ans << endl;

    return 0;
}