#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    vector<int> last(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
        if(i && arr[i-1] <= arr[i]) {
            last[i] = last[i-1];
        } else {
            last[i] = i;
        }
    }
    int res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<int> dp(n,0);
    for(int i = 0; i < n; ++i) {
        int mx = arr[i];
        int mn = arr[i];
        int curr = 0;
        for(int j = i, cnt = 30; j >= 0 && cnt--; --j) {
            mx = max(mx, arr[j]);
            mn = min(mn, arr[j]);
            int cost = mx-mn;
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        for(int j = i, cnt = 10; j >= 0 && cnt--; j = last[max(0,j-1)]) {
            int cost = stMax.query(j,i) - stMin.query(j,i);
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        res = max(res, curr);
        dp[i] = curr;
    }
    cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<int> arr(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    int res = 0;
    vector<int> dp(n,0);
    for(int i = 0; i < n; ++i) {
        int mx = arr[i];
        int mn = arr[i];
        for(int j = i, cnt = 50; j >= 0 && cnt--; --j) {
            mx = max(mx, arr[j]);
            mn = min(mn, arr[j]);
            int cost = mx-mn;
            if(j) cost += dp[j-1];
            dp[i] = max(dp[i], cost);
        }

        res = max(res, dp[i]);
    }
    cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    vector<vector<int> > index;
    vector<int> logTwo;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        logTwo.resize(n+1,0);
        for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        index.resize(maxPow, vector<int>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
            index[0][j] = j;
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                    index[i][j] = index[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                    index[i][j] = index[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return index[x][r-(1<<x)+1];
        }
        return index[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<int> arr(n);
    vector<int> last(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
        if(i && arr[i-1] <= arr[i]) {
            last[i] = last[i-1];
        } else {
            last[i] = i;
        }
    }
    /*
    cout << "lasts:\n";
    for(int i = 0; i < n; ++i) {
        cout << last[i] << " ";
    }
    cout << endl;
    */
    int res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<int> dp(n,0);
    for(int i = 0; i < n; ++i) {
        int mx = arr[i];
        int mn = arr[i];
        int curr = 0;
        for(int j = i, cnt = 30; j >= 0 && cnt--; --j) {
            mx = max(mx, arr[j]);
            mn = min(mn, arr[j]);
            int cost = mx-mn;
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        for(int j = i, cnt = 10; j >= 0 && cnt--; j = last[max(0,j-1)]) {
            //Node q = st.query(j,i);
            //int cost = q.mx - q.mn;
            int cost = arr[stMax.query(j,i)] - arr[stMin.query(j,i)];
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }

        res = max(res, curr);

        //st.update(i,i,curr);
        dp[i] = curr;
    }
    cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    vector<int> local;
    local.push_back(0);
    if(1 < n) local.push_back(1);
    if(n-2 >= 0) local.push_back(n-2);
    local.push_back(n-1);
    for(int i = 1; i+1 < n; ++i) {
        if(arr[i-1] > arr[i] && arr[i] < arr[i+1]) {
            local.push_back(i-1);
            local.push_back(i);
            local.push_back(i+1);
        } else if(arr[i-1] < arr[i] && arr[i] > arr[i+1]) {
            local.push_back(i-1);
            local.push_back(i);
            local.push_back(i+1);
        }
    }
    sort(local.begin(), local.end());
    local.erase(unique(local.begin(), local.end()), local.end());
    /*
    cout << "local:\n";
    for(int x : local) cout << x << " ";
    cout << endl;
    */
    ll res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<ll> dp(n,0);
    int pos = 0;
    for(int i = 0; i < n; ++i) {
        //cout << "i: " << i << endl;
        while(pos < local.size() && local[pos] <= i) ++pos;
        ll &curr = dp[i];
        for(int j = pos-1, cnt=30; j >= 0 && cnt--; --j) {
            //cout << "here\n";
            const int arrIndex = local[j];
            //cout << "arrIndex: " << arrIndex << endl;
            ll cost = -stMax.query(arrIndex,i) - stMin.query(arrIndex,i);
            if(arrIndex) cost += dp[arrIndex-1];
            //cout << "cost: " << cost << endl;
            curr = max(curr, cost);
        }

        res = max(res, curr);
    }
    /*
    cout << "dp\n";
    for(int i = 0; i < n; ++i) {
        cout << dp[i] << " ";
    }
    cout << endl;
    */
    cout << dp[n-1] << endl;
    //cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    vector<int> last(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
        if(i && arr[i-1] <= arr[i]) {
            last[i] = last[i-1];
        } else {
            last[i] = i;
        }
    }
    int res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<int> dp(n,0);
    for(int i = 0; i < n; ++i) {
        int mx = arr[i];
        int mn = arr[i];
        int curr = 0;
        for(int j = i, cnt = 30; j >= 0 && cnt--; --j) {
            mx = max(mx, arr[j]);
            mn = min(mn, arr[j]);
            int cost = mx-mn;
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        for(int j = i, cnt = 10; j >= 0 && cnt--; j = last[max(0,j-1)]) {
            Node q = st.query(j,i);
            int cost = q.mx - q.mn;
            int cost = stMax.query(j,i) - stMin.query(j,i);
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        res = max(res, curr);
        dp[i] = curr;
    }
    cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    vector<int> local;
    local.push_back(0);
    if(1 < n) local.push_back(1);
    if(n-2 >= 0) local.push_back(n-2);
    local.push_back(n-1);
    for(int i = 1; i < n; ++i) {
        if(arr[i-1] < arr[i]) {
            int j = i-1;
            while(j >= 0 && arr[j] == arr[i-1]) --j;
            if(j < 0 || arr[j] > arr[i-1]) {
                for(int diff = -2; diff <= 3; ++diff) {
                    if(j+diff >= 0 && j+diff < n) {
                        local.push_back(j+diff);
                    }
                }
            }
        }
    }
    for(int i = 1; i < n; ++i) {
        if(arr[i-1] > arr[i]) {
            int j = i-1;
            while(j >= 0 && arr[j] == arr[i-1]) --j;
            if(j < 0 || arr[j] < arr[i-1]) {
                for(int diff = -2; diff <= 3; ++diff) {
                    if(j+diff >= 0 && j+diff < n) {
                        local.push_back(j+diff);
                    }
                }
            }
        }
    }

    sort(local.begin(), local.end());
    local.erase(unique(local.begin(), local.end()), local.end());
    /*
    cout << "local:\n";
    for(int x : local) cout << x << " ";
    cout << endl;
    */
    ll res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<ll> dp(n,0);
    int pos = 0;
    for(int i = 0; i < n; ++i) {
        //cout << "i: " << i << endl;
        while(pos < local.size() && local[pos] <= i) ++pos;
        ll &curr = dp[i];
        for(int j = pos-1, cnt=30; j >= 0 && cnt--; --j) {
            //cout << "here\n";
            const int arrIndex = local[j];
            //cout << "arrIndex: " << arrIndex << endl;
            ll cost = -stMax.query(arrIndex,i) - stMin.query(arrIndex,i);
            if(arrIndex) cost += dp[arrIndex-1];
            //cout << "cost: " << cost << endl;
            curr = max(curr, cost);
        }

        res = max(res, curr);
    }
    /*
    cout << "dp\n";
    for(int i = 0; i < n; ++i) {
        cout << dp[i] << " ";
    }
    cout << endl;
    */
    cout << dp[n-1] << endl;
    //cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    vector<int> local;
    local.push_back(0);
    if(1 < n) local.push_back(1);
    if(n-2 >= 0) local.push_back(n-2);
    local.push_back(n-1);
    for(int i = 1; i+1 < n; ++i) {
        if(arr[i-1] > arr[i] && arr[i] < arr[i+1]) {
            local.push_back(i-1);
            local.push_back(i);
            local.push_back(i+1);
        } else if(arr[i-1] < arr[i] && arr[i] > arr[i+1]) {
            local.push_back(i-1);
            local.push_back(i);
            local.push_back(i+1);
        }
    }
    sort(local.begin(), local.end());
    local.erase(unique(local.begin(), local.end()), local.end());
    /*
    cout << "local:\n";
    for(int x : local) cout << x << " ";
    cout << endl;
    */
    ll res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<ll> dp(n,0);
    int pos = 0;
    for(int i = 0; i < n; ++i) {
        //cout << "i: " << i << endl;
        while(pos < local.size() && local[pos] <= i) ++pos;
        ll &curr = dp[i];
        for(int j = pos-1, cnt=5; j >= 0 && cnt--; --j) {
            //cout << "here\n";
            const int arrIndex = local[j];
            //cout << "arrIndex: " << arrIndex << endl;
            ll cost = -stMax.query(arrIndex,i) - stMin.query(arrIndex,i);
            if(arrIndex) cost += dp[arrIndex-1];
            //cout << "cost: " << cost << endl;
            curr = max(curr, cost);
        }

        res = max(res, curr);
    }
    /*
    cout << "dp\n";
    for(int i = 0; i < n; ++i) {
        cout << dp[i] << " ";
    }
    cout << endl;
    */
    cout << dp[n-1] << endl;
    //cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define endl '\n'
typedef long long ll;

struct Node {
    ll mx = 0;
    ll mn = 0;
};

struct SegmentTree {
    vector<Node> tree;
    vector<ll> lazy;
    int n, size;
    const ll inf = 1e18;

    /*implement these*/
    const Node zero = {-inf, inf};
    Node combine(const Node &L, const Node &R) {
        Node par;
        par.mx = max(L.mx, R.mx);
        par.mn = min(L.mn, R.mn);
        return par;
    }
    void combineRange(int node, int start, int end, ll delta) {
        tree[node].mx += delta;
        tree[node].mn += delta;
        if(start != end) {
            lazy[2*node] += delta;
            lazy[2*node+1] += delta;
        }
    }

    SegmentTree(int currSize) : n(currSize) {
        size = 1;
        while(size < n) size<<=1;
        size<<=1;
        tree.resize(size);
        lazy.resize(size, 0);
    }
    SegmentTree(const vector<ll> &arr) : n((int)arr.size()) {
        size = 1;
        while(size < n) size<<=1;
        size<<=1;
        tree.resize(size);
        lazy.resize(size, 0);
        build(arr, 1, 0, n-1);
    }
    void build(const vector<ll> &arr, int node, int start, int end) {
        if(start == end) {
            tree[node].mx = arr[start];
            tree[node].mn = arr[start];
        } else {
            int mid = (start+end)/2;
            build(arr, 2*node, start, mid);
            build(arr, 2*node+1, mid+1, end);
            tree[node] = combine(tree[2*node], tree[2*node+1]);
        }
    }
    void push(int node, int start, int end) {
        ll &currLazy = lazy[node];
        if(currLazy) {
            combineRange(node, start, end, currLazy);
            currLazy = 0;
        }
    }
    void update(int l, int r, ll diff) {update(1, 0, n-1, l, r, diff);}
    void update(int node, int start, int end, int l, int r, ll diff) {
        push(node, start, end);
        if(start > end || start > r || end < l) return;
        if(start >= l && end <= r) {
            combineRange(node, start, end, diff);
            return;
        }
        int mid = (start + end) / 2;
        update(2*node, start, mid, l, r, diff);
        update(2*node+1, mid+1, end, l, r, diff);
        tree[node] = combine(tree[2*node], tree[2*node+1]);
    }
    Node query(int l, int r) {return query(1, 0, n-1, l, r);}
    Node query(int node, int start, int end, int l, int r) {
        if(r < start || end < l) return zero;
        push(node, start, end);
        if(l <= start && end <= r) return tree[node];
        int mid = (start+end)/2;
        return combine(query(2*node, start, mid, l, r),
                       query(2*node+1, mid+1, end, l, r));
    }
};
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    vector<int> arr(n);
    vector<int> last(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
        if(i && arr[i-1] <= arr[i]) {
            last[i] = last[i-1];
        } else {
            last[i] = i;
        }
    }
    /*
    cout << "lasts:\n";
    for(int i = 0; i < n; ++i) {
        cout << last[i] << " ";
    }
    cout << endl;
    */
    int res = 0;
    SegmentTree st(arr);
    vector<int> dp(n,0);
    for(int i = 0; i < n; ++i) {
        int mx = arr[i];
        int mn = arr[i];
        int curr = 0;
        for(int j = i, cnt = 30; j >= 0 && cnt--; --j) {
            mx = max(mx, arr[j]);
            mn = min(mn, arr[j]);
            int cost = mx-mn;
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }
        for(int j = i, cnt = 10; j >= 0 && cnt--; j = last[max(0LL,j-1)]) {
            Node q = st.query(j,i);
            int cost = q.mx - q.mn;
            if(j) cost += dp[j-1];
            curr = max(curr, cost);
        }

        res = max(res, curr);

        //st.update(i,i,curr);
        dp[i] = curr;
    }
    cout << res << endl;
}


#include <bits/stdc++.h>
using namespace std;
#define endl '\n'
typedef long long ll;

vector<int> logTwo;

template <class T>
struct sparseTable {
    vector<vector<T> > dp;
    sparseTable(const vector<T> &arr) {
        int n = arr.size();
        int maxPow = logTwo[n]+1;
        dp.resize(maxPow, vector<T>(n));
        for(int j = 0; j < n; ++j) {
            dp[0][j] = arr[j];
        }
        for(int i = 1; i < maxPow; ++i) {
            for(int j = 0; j+(1<<i)-1<n; ++j) {
                if(dp[i-1][j] > dp[i-1][j+(1<<(i-1))]) {
                    dp[i][j] = dp[i-1][j+(1<<(i-1))];
                } else {
                    dp[i][j] = dp[i-1][j];
                }
            }
        }
    }
    int query(int l, int r) {//returns index in array of min element
        const int x = logTwo[r-l+1];
        if(dp[x][l] > dp[x][r-(1<<x)+1]) {
            return dp[x][r-(1<<x)+1];
        }
        return dp[x][l];
    }
};

signed main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n;
    cin >> n;
    logTwo.resize(n+1,0);
    for(int i = 2; i <= n; ++i) logTwo[i] = 1 + logTwo[i/2];
    vector<int> arr(n);
    for(int i = 0; i < n; ++i) {
        cin >> arr[i];
    }
    vector<int> local;
    local.push_back(0);
    if(1 < n) local.push_back(1);
    if(n-2 >= 0) local.push_back(n-2);
    local.push_back(n-1);
    for(int i = 1; i+1 < n; ++i) {
        if(arr[i-1] > arr[i] && arr[i] < arr[i+1]) {
            for(int diff = -3; diff <= 3; ++diff) {
                if(i+diff >= 0 && i+diff < n) local.push_back(i+diff);
            }
        } else if(arr[i-1] < arr[i] && arr[i] > arr[i+1]) {
            for(int diff = -3; diff <= 3; ++diff) {
                if(i+diff >= 0 && i+diff < n) local.push_back(i+diff);
            }
        }
    }
    sort(local.begin(), local.end());
    local.erase(unique(local.begin(), local.end()), local.end());
    /*
    cout << "local:\n";
    for(int x : local) cout << x << " ";
    cout << endl;
    */
    ll res = 0;
    sparseTable stMin(arr);
    for(int i = 0; i < n; ++i) {
        arr[i] = -arr[i];
    }
    sparseTable stMax(arr);
    vector<ll> dp(n,0);
    int pos = 0;
    for(int i = 0; i < n; ++i) {
        //cout << "i: " << i << endl;
        while(pos < local.size() && local[pos] <= i) ++pos;
        ll &curr = dp[i];
        for(int j = pos-1, cnt=30; j >= 0 && cnt--; --j) {
            //cout << "here\n";
            const int arrIndex = local[j];
            //cout << "arrIndex: " << arrIndex << endl;
            ll cost = -stMax.query(arrIndex,i) - stMin.query(arrIndex,i);
            if(arrIndex) cost += dp[arrIndex-1];
            //cout << "cost: " << cost << endl;
            curr = max(curr, cost);
        }

        res = max(res, curr);
    }
    /*
    cout << "dp\n";
    for(int i = 0; i < n; ++i) {
        cout << dp[i] << " ";
    }
    cout << endl;
    */
    cout << dp[n-1] << endl;
    //cout << res << endl;
}


#include<bits/stdc++.h>
using namespace std;

const int N = 1e6 + 10;
int a[N], dp[N], prv[N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    prv[0] = -1;
    prv[1] = 0;
    for (int i = 2; i < n; i++)
        prv[i] = (a[i] < a[i - 1] xor a[i] < a[prv[i - 1]]? i - 1: prv[i - 1]);
    dp[0] = 0;
    for (int i = 1; i < n; i++) {
        dp[i] = max(dp[prv[i]] + abs(a[prv[i] + 1] - a[i]), abs(a[prv[i]] - a[i]) + (prv[i] == 0? 0: dp[prv[i] - 1]));
    }
    cout << dp[n - 1] << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 1e6 + 10;
ll a[N], dp[N], prv[N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll n;
    cin >> n;
    for (ll i = 0; i < n; i++)
        cin >> a[i];
    prv[0] = -1;
    prv[1] = 0;
    for (ll i = 2; i < n; i++) {
        if (a[i - 1] == a[i])
            prv[i] = prv[i - 1];
        else if (a[i] > a[i - 1]) {
            if (a[i - 1] < a[prv[i - 1]])
                prv[i] = i - 1;
            else
                prv[i] = prv[i - 1];
        }
        else {
            if (a[i - 1] > a[prv[i - 1]])
                prv[i] = i - 1;
            else
                prv[i] = prv[i - 1];
        }
    }
    dp[0] = 0;
    for (ll i = 1; i < n; i++)
        dp[i] = max(dp[prv[i]] + abs(a[prv[i] + 1] - a[i]), abs(a[prv[i]] - a[i]) + (prv[i] == 0? 0: dp[prv[i] - 1]));
    cout << dp[n - 1] << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 1e6 + 10;
ll a[N], dp[N], prv[N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll n;
    cin >> n;
    for (ll i = 0; i < n; i++)
        cin >> a[i];
    prv[0] = -1;
    prv[1] = 0;
    for (ll i = 2; i < n; i++)
        prv[i] = (a[i] < a[i - 1] ^ a[i] < a[prv[i - 1]]? i - 1: prv[i - 1]);
    dp[0] = 0;
    for (ll i = 1; i < n; i++)
        dp[i] = max(dp[prv[i]] + abs(a[prv[i] + 1] - a[i]), abs(a[prv[i]] - a[i]) + (prv[i] == 0? 0: dp[prv[i] - 1]));
    cout << dp[n - 1] << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 1e6 + 10;
ll a[N], dp[N], prv[N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    ll n;
    cin >> n;
    for (ll i = 0; i < n; i++)
        cin >> a[i];
    prv[0] = -1;
    prv[1] = 0;
    for (ll i = 2; i < n; i++) {
        if (a[i - 1] == a[i])
            prv[i] = prv[i - 1];
        else if (a[i] > a[i - 1]) {
            if (a[i] < a[prv[i - 1]])
                prv[i] = i - 1;
            else
                prv[i] = prv[i - 1];
        }
        else {
            if (a[i] > a[prv[i - 1]])
                prv[i] = i - 1;
            else
                prv[i] = prv[i - 1];
        }
    }
    dp[0] = 0;
    for (ll i = 1; i < n; i++)
        dp[i] = max(dp[prv[i]] + abs(a[prv[i] + 1] - a[i]), abs(a[prv[i]] - a[i]) + (prv[i] == 0? 0: dp[prv[i] - 1]));
    cout << dp[n - 1] << "\n";
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

typedef long long ll;

const int N = 1e6 + 10;
ll a[N], dp[N], prv[N];

int main() {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n;
    cin >> n;
    for (int i = 0; i < n; i++)
        cin >> a[i];
    prv[0] = -1;
    prv[1] = 0;
    for (int i = 2; i < n; i++)
        prv[i] = (a[i] < a[i - 1] xor a[i] < a[prv[i - 1]]? i - 1: prv[i - 1]);
    dp[0] = 0;
    for (int i = 1; i < n; i++) {
        dp[i] = max(dp[prv[i]] + abs(a[prv[i] + 1] - a[i]), abs(a[prv[i]] - a[i]) + (prv[i] == 0? 0: dp[prv[i] - 1]));
    }
    cout << dp[n - 1] << "\n";
    return 0;
}


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back
#define SZ(x) ll(x.size())

using namespace std;
const int maxn = 1000*1000+5 ;
const int mod = 1000000007 /*998244353*/  ;
int n , a[maxn] , minf[maxn] , maxf[maxn] , minb[maxn] , maxb[maxn];
int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	minf[1] = a[1] ;
	maxf[1] = a[1] ;
	 for(int i = 2 ; i <= n ; i ++ )
	 {
	 	minf[i] = min(a[i] , minf[i-1]) ;
		 maxf[i] = max(a[i] , maxf[i-1]) ;
	 }
	minb[n] = a[n] ;
	maxb[n] = a[n] ;
	for(int i = n -1 ; i >= 1 ; i -- )
	{
		minb[i] = min(a[i] , minb[i+1]) ;
		maxb[i] = max(a[i] , maxb[i+1]) ;
	}
	int ans = 0 ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		ans = max(ans , ((maxf[i] - minf[i]) + (maxb[i+1] - minb[i+1]))) ;
	}
	cout<<ans ;
}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn][2];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	for(int i = 2 ; i <= n ; i ++ )
	{
		 if(a[i] < a[i-1]) dp[i][0] =  dp[i-1][0] + (a[i-1] - a[i])  ;
		 else dp[i][1] = dp[i-1][1] + ( a[i] - a[i-1] ) ;

		 dp[i][0] = max(dp[i][0] , max(dp[i-1][0] , dp[i-1][1]) ); dp[i][1] = max(dp[i][1] , max(dp[i-1][0] , dp[i-1][1])) ;
	}
	cout<<max(dp[n][0] , dp[n][1]) ;

}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	mx = a[1] ;
	mn = a[1] ;
	for(int i = 2 ; i <= n ; i ++ )
	{

		dp[i] = max(abs(a[i] - a[i-1]) + dp[i-2] , max( a[i] - mn + dp[posmn - 1] , mx - a[i] + dp[posmx - 1] ) ) ;

		if(a[i] <= mn )
		{
			posmn = i ;
			mn = a[i] ;
		 }
		 if(a[i] >= mx)
		 {
		 	posmx = i ;
		 	mx = a[i] ;
		  }
	//	cout<<i << " " << dp[i] << endl ;
	}
	cout<<dp[n] ;

}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	mx = a[1] ;
	mn = a[1] ;
	for(int i = 2 ; i <= n ; i ++ )
	{

		dp[i] = max(abs(a[i] - a[i-1]) + dp[i-2] , max( a[i] - mn + dp[posmn - 1] , mx - a[i] + dp[posmx - 1] ) ) ;
		dp[i] = max(dp[i] , dp[i-1]) ;
		if(a[i] <= mn )
		{
			posmn = i ;
			mn = a[i] ;
		 }
		 if(a[i] >= mx)
		 {
		 	posmx = i ;
		 	mx = a[i] ;
		  }
	//	cout<<i << " " << dp[i] << endl ;
	}
	cout<<dp[n] ;

}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn][2];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	for(int i = 2 ; i <= n ; i ++ )
	{
		 dp[i][0] = max(dp[i][0] , (dp[i-1][0] , dp[i-1][1])); dp[i][1] = max(dp[i][1] , max(dp[i-1][0] , dp[i-1][1])) ;

		 if(a[i] < a[i-1]) dp[i][0] = max( dp[i][0] , dp[i-1][0] + (a[i-1] - a[i]) ) ;
		 else dp[i][1] = max(dp[i-1][1] , dp[i][1] + ( a[i] - a[i-1] )) ;

	}
	cout<<max(dp[n][0] , dp[n][1]) ;

}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back
#define SZ(x) ll(x.size())

using namespace std;
const int maxn = 1000*1000+5 ;
const int mod = 1000000007 /*998244353*/  ;
int n , a[maxn] , minf[maxn] , maxf[maxn] , minb[maxn] , maxb[maxn];
int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	minf[1] = a[1] ;
	maxf[1] = a[1] ;
	 for(int i = 2 ; i <= n ; i ++ )
	 {
	 	minf[i] = min(a[i] , minf[i-1]) ;
		 maxf[i] = max(a[i] , maxf[i-1]) ;
	 }
	minb[n] = a[n] ;
	maxb[n] = a[n] ;
	for(int i = n -1 ; i >= 1 ; i -- )
	{
		minb[i] = min(a[i] , minb[i+1]) ;
		maxb[i] = max(a[i] , maxb[i+1]) ;
	}
	int ans = 0 ;
	for(int i = 1 ; i <= n-1 ; i ++ )
	{
		ans = max(ans , ((maxf[i] - minf[i]) + (maxb[i+1] - minb[i+1]))) ;
	}
	cout<<ans ;
}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	mx = a[1] ;
	mn = a[1] ;
	for(int i = 2 ; i <= n ; i ++ )
	{

		dp[i] = max(dp[i-1] , max( a[i] - mn + dp[posmn - 1] , mx - a[i] + dp[posmx - 1] ) ) ;

		if(a[i] <= mn )
		{
			posmn = i ;
			mn = a[i] ;
		 }
		 if(a[i] >= mx)
		 {
		 	posmx = i ;
		 	mx = a[i] ;
		  }
		//cout<<i << " " << dp[i] << endl ;
	}
	cout<<dp[n] ;

}
//////
////////
///////////


/*
    ____        __
   / __ \____  / /_  ____ _____ ___
  / /_/ / __ \/ __ \/ __ `/ __ `__ \
 / _, _/ /_/ / / / / /_/ / / / / / /
/_/ |_|\____/_/ /_/\__,_/_/ /_/ /_/
*/
#include<bits/stdc++.h>

typedef long long ll ;

#define pll pair<ll , ll >
#define X   first
#define Y   second
#define mp  make_pair
#define pii pair<int , int>
#define vec vector
#define vpii vector<pair<int , int>>
#define i_n   int i = 0 ; i< n ; i++
#define cn  int n ; cin>>n
#define file_io freopen("input.txt", "r", stdin);freopen("output.txt", "w", stdout);
#define migmig ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
#define cina int a[n] ; for(int i = 0 ; i < n ; i++) cin>>a[i]
#define pb push_back

using namespace std;
const int maxn = 1000*1000+5 ;
const ll inf = 9223372036854775807 ;
ll n , a[maxn] , posmx = 1 , posmn = 1 , mx , mn , dp[maxn][2];

int main()
{
	migmig ;
	cin>>n ;
	for(int i = 1 ; i <= n ; i ++ )
	{
		cin>>a[i] ;
	}
	for(int i = 2 ; i <= n ; i ++ )
	{
		 if(a[i] < a[i-1]) dp[i][0] = max( dp[i-1][0] , dp[i-1][0] + (a[i-1] - a[i]) ) ;
		 else dp[i][1] = max(dp[i-1][1] , dp[i-1][1] + ( a[i] - a[i-1] )) ;

		 dp[i][0] = max(dp[i][0] , (dp[i-1][0] , dp[i-1][1])); dp[i][1] = max(dp[i][1] , max(dp[i-1][0] , dp[i-1][1])) ;
	}
	cout<<max(dp[n][0] , dp[n][1]) ;

}
//////
////////
///////////


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N_MAX = 100002;

int n;

ll a[N_MAX];

ll dp[N_MAX];

ll prefmax[N_MAX], prefmin[N_MAX];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    prefmax[0] = a[1];
    prefmin[0] = -a[1];
    for(int i = 1; i <= n; i++)
    {
        dp[i] = max(prefmax[i - 1] - a[i], prefmin[i - 1] + a[i]);
        prefmax[i] = max(prefmax[i - 1], dp[i] + a[i + 1]);
        prefmin[i] = max(prefmin[i - 1], dp[i] - a[i + 1]);
    }
    cout << dp[n] << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N_MAX = 100002;

int n;

int a[N_MAX];

int dp[N_MAX];

int prefmax[N_MAX], prefmin[N_MAX];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    prefmax[0] = a[1];
    prefmin[0] = -a[1];
    for(int i = 1; i <= n; i++)
    {
        dp[i] = max(prefmax[i - 1] - a[i], prefmin[i - 1] + a[i]);
        prefmax[i] = max(prefmax[i - 1], dp[i] + a[i + 1]);
        prefmin[i] = max(prefmin[i - 1], dp[i] - a[i + 1]);
    }
    cout << dp[n] << "\n";
    return 0;
}


#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int N_MAX = 1000002;

int n;

ll a[N_MAX];

ll dp[N_MAX];

ll prefmax[N_MAX], prefmin[N_MAX];

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cin >> n;
    for(int i = 1; i <= n; i++)
        cin >> a[i];
    prefmax[0] = a[1];
    prefmin[0] = -a[1];
    for(int i = 1; i <= n; i++)
    {
        dp[i] = max(prefmax[i - 1] - a[i], prefmin[i - 1] + a[i]);
        prefmax[i] = max(prefmax[i - 1], dp[i] + a[i + 1]);
        prefmin[i] = max(prefmin[i - 1], dp[i] - a[i + 1]);
    }
    cout << dp[n] << "\n";
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

vector<string> vec_splitter(string s) {
	s += ',';
	vector<string> res;
	while(!s.empty()) {
		res.push_back(s.substr(0, s.find(',')));
		s = s.substr(s.find(',') + 1);
	}
	return res;
}
void debug_out(
vector<string> __attribute__ ((unused)) args,
__attribute__ ((unused)) int idx,
__attribute__ ((unused)) int LINE_NUM) { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
	if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
	stringstream ss; ss << H;
	cerr << args[idx] << " = " << ss.str();
	debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifdef XOX
#define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

#define ll long long
#define pll pair<ll,ll>
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define abs(x) ((x)<0?(-(x)):(x))
#define SZ(x) ((int)x.size())
#define all(x) x.begin(),x.end()

const int LOG = 19;
const int NN = (int)1e6+5;
const int MaxM = (int)10000+5;
const int INF = 1 << 27;

ll mul(ll x, ll y, ll MOD) { return (1LL * x * y) % MOD; }
ll add(ll x, ll y, ll MOD) {
	ll res = x;
	res += y;
	return (res % MOD + MOD) % MOD;
}
int two(int x) { return 1 << x; }
bool contain(int mask, int bit) { return (mask & two(bit)) > 0; }
int gcd(int a, int b) { return b == 0? a: gcd(b, a % b); }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }
int bit_count(int x) { return x == 0? 0: (x & 1) + bit_count(x >> 1); }

int a[NN];
ll dp[2][NN];
int n;

ll rec(int pre, int pos) {
	if(pos == n) {
		return 0;
	}
	ll& res = dp[pre][pos];
	if(~res) return res;

	res = 1LL << 57;
	if(pre == 0 && pos != n - 1 && pos != 0 &&
	((a[pos - 1] > a[pos] && a[pos] < a[pos + 1]) || (a[pos - 1] < a[pos] && a[pos] > a[pos + 1]))) {
			res = min(res, rec(0, pos + 1) + abs(a[pos] - a[pos - 1]));
			res = min(res, rec(1, pos + 1) + abs(a[pos] - a[pos + 1]));
		}
	else {
		res = min(res, rec(0, pos + 1));
		res = min(res, rec(1, pos + 1) + abs(a[pos] - a[pos + 1]));
	}
	return res;
}

int main() {
	#ifdef XOX
		freopen("in.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);

	// 2, 3, 3, 3, 2
	// 2 - {3, 3, 3}
	scanf("%d", &n);
	for(int i = 0; i < n; i ++) scanf("%d", &a[i]);
	ll tot = 0;
	for(int i = 1; i < n; i ++) tot += abs(a[i] - a[i - 1]);
	memset(dp, -1, sizeof(dp));
	for(int i = n - 1; i >= 0; i --) rec(1, i);
	ll mn = rec(0, 0);
	tot -= mn;
	printf("%lld\n", tot);

// 3 2  1 1000	 >> 3 1 1000 = 2 + 999 = 2 + 999 - 1
// 3 2 1000  >> ans =
//
// 1 + 1 + 2 + 1 = 5 -
// 1 3 1 2 = {1, 1
//
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

vector<string> vec_splitter(string s) {
	s += ',';
	vector<string> res;
	while(!s.empty()) {
		res.push_back(s.substr(0, s.find(',')));
		s = s.substr(s.find(',') + 1);
	}
	return res;
}
void debug_out(
vector<string> __attribute__ ((unused)) args,
__attribute__ ((unused)) int idx,
__attribute__ ((unused)) int LINE_NUM) { cerr << endl; }
template <typename Head, typename... Tail>
void debug_out(vector<string> args, int idx, int LINE_NUM, Head H, Tail... T) {
	if(idx > 0) cerr << ", "; else cerr << "Line(" << LINE_NUM << ") ";
	stringstream ss; ss << H;
	cerr << args[idx] << " = " << ss.str();
	debug_out(args, idx + 1, LINE_NUM, T...);
}
#ifdef XOX
#define debug(...) debug_out(vec_splitter(#__VA_ARGS__), 0, __LINE__, __VA_ARGS__)
#else
#define debug(...) 42
#endif

#define ll long long
#define pll pair<ll,ll>
#define min(x,y) ((x)<(y)?(x):(y))
#define max(x,y) ((x)>(y)?(x):(y))
#define abs(x) ((x)<0?(-(x)):(x))
#define SZ(x) ((int)x.size())
#define all(x) x.begin(),x.end()

const int LOG = 19;
const int NN = (int)1e7+5;
const int MaxM = (int)10000+5;
const int INF = 1 << 27;

ll mul(ll x, ll y, ll MOD) { return (1LL * x * y) % MOD; }
ll add(ll x, ll y, ll MOD) {
	ll res = x;
	res += y;
	return (res % MOD + MOD) % MOD;
}
int two(int x) { return 1 << x; }
bool contain(int mask, int bit) { return (mask & two(bit)) > 0; }
int gcd(int a, int b) { return b == 0? a: gcd(b, a % b); }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }
int bit_count(int x) { return x == 0? 0: (x & 1) + bit_count(x >> 1); }

int a[NN];
int freq[NN];

int main() {
	#ifdef XOX
		freopen("in.txt", "r", stdin);
	#endif
	ios_base::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);

	// 2, 3, 3, 3, 2
	// 2 - {3, 3, 3}
	int n; scanf("%d", &n);
	ll sum = 0;
	vector<ll> gap;
	for(int i = 0; i < n; i ++) scanf("%d", &a[i]);
	for(int i = 0; i < n; i ++) {
		if(i > 0) sum += abs(a[i] - a[i - 1]);
		if(i == n - 1 || i == 0) continue;
		if((a[i - 1] < a[i] && a[i] > a[i + 1]) || (a[i - 1] < a[i] && a[i] > a[i + 1])) {
			sum -= min(abs(a[i] - a[i - 1]), abs(a[i] - a[i + 1]));
		}
	}
	printf("%lld\n", sum);

// 3 2  1 1000	 >> 3 1 1000 = 2 + 999 = 2 + 999 - 1
// 3 2 1000  >> ans =
//
// 1 + 1 + 2 + 1 = 5 -
// 1 3 1 2 = {1, 1
//
	return 0;
}


#include<iostream>

using namespace std;

const int MAXN = 1e6 + 5;
const long long inf = 1e9 + 5;

int n;
int a[MAXN];

int l[MAXN];
long long dp[MAXN];

struct segment
{
    int minValue, maxValue;

    long long getDiff()
    {
        return this->maxValue - this->minValue;
    }
};

segment Merge(segment A, segment B)
{
    segment output;

    output.minValue = min(A.minValue, B.minValue);
    output.maxValue = max(A.maxValue, B.maxValue);

    return output;
}

struct sparseTable
{
    segment a[21][MAXN];

    sparseTable(int arr[], int n)
    {
        for(int i = 1;i<=n;i++)
        {
            this->a[0][i] = {arr[i], arr[i]};
        }
        for(int i = 1;i<21;i++)
        {
            for(int j = 1;j<=n;j++)
            {
                this->a[i][j] = this->a[i-1][j];
                if(j + (1<<(i-1)) <= n)
                {
                    this->a[i][j] = Merge(this->a[i][j], this->a[i-1][ j + (1<<(i-1)) ]);
                }
            }

        }
    }

    segment query(int ql, int qr)
    {
        return Merge(this->a[ l[qr-ql+1] ][ql], this->a[ l[qr-ql+1] ][ qr - (1<<l[qr-ql+1]) + 1 ]);
    }
};
sparseTable *T;

struct node
{
    int l, r;
    long long lazy;
    long long maxSum, maxValue;

    node *L, *R;

    node(int l, int r)
    {
        this->l = l;
        this->r = r;

        this->lazy = -inf;
        this->maxSum = -inf;
        this->maxValue = -inf;

        this->L = nullptr;
        this->R = nullptr;
    }

    void updateLazy()
    {
        if(this->lazy==-inf) return;

        this->maxSum = this->maxValue + this->lazy;
        if(this->l!=this->r)
        {
            this->L->lazy = max(this->L->lazy, this->lazy);
            this->R->lazy = max(this->R->lazy, this->lazy);
        }

        this->lazy = -inf;
    }

    void build(int l, int r)
    {
        if(l==r)
        {
            return;
        }

        this->L = new node(l, (l+r)/2);
        this->R = new node((l+r)/2+1, r);

        this->L->build(l, (l+r)/2);
        this->R->build((l+r)/2+1, r);
    }

    long long query(int ql, int qr)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr) return this->maxSum;
        if(this->r<ql || this->l>qr) return -2*inf;

        return max(this->L->query(ql, qr), this->R->query(ql, qr));
    }

    void update(int ql, int qr, long long value)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr)
        {
            //cout << this->l << " " << this->r << " --> " << this->maxValue << " + " << value << '\n';

            this->maxSum = this->maxValue + value;
            if(this->l!=this->r)
            {
                this->L->lazy = max(this->L->lazy, value);
                this->R->lazy = max(this->R->lazy, value);
            }

            return;
        }
        if(this->r<ql || this->l>qr) return;

        this->L->update(ql, qr, value);
        this->R->update(ql, qr, value);
        this->maxSum = max(this->L->maxSum, this->R->maxSum);
    }

    void setValue(int q, long long value, long long add)
    {
        this->updateLazy();

        if(this->l==this->r && this->l==q)
        {
            //cout << this->l << " --> " << value << " + " << add << '\n';

            this->maxValue = max(this->maxValue, value);
            this->maxSum = this->maxValue + add;

            return;
        }
        if(this->r<q || this->l>q) return;

        this->L->setValue(q, value, add);
        this->R->setValue(q, value, add);

        this->maxSum = max(this->L->maxSum, this->R->maxSum);
        this->maxValue = max(this->L->maxValue, this->R->maxValue);
    }
};

void Init()
{
    int curr = 0;

    l[0] = 0;
    for(int i = 1;i<=n;i++)
    {
        if(1<<(curr+1)==i) curr++;
        l[i] = curr;
    }

    T = new sparseTable(a, n);
}

node *minTree, *maxTree;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int index1, index2, index3;
    int lastIndex = 1;

    cin >> n;
    for(int i = 1;i<=n;i++)
    {
        cin >> a[i];
    }
    Init();

    maxTree = new node(0, n+1);
    maxTree->build(0, n+1);

    minTree = new node(0, n+1);
    minTree->build(0, n+1);

    dp[0] = 0;
    maxTree->setValue(0, 0, max(a[1], a[2]));
    minTree->setValue(0, 0, -min(a[1], a[2]));

    dp[1] = 0;
    maxTree->setValue(1, 0, max(a[2], a[2]));
    minTree->setValue(1, 0, -min(a[2], a[2]));

    dp[2] = max(a[1], a[2]) - min(a[1], a[2]);
    maxTree->setValue(2, dp[2], 0);
    minTree->setValue(2, dp[2], 0);

    for(int i = 3;i<=n;i++)
    {
        index2 = -1;
        index3 = -1;
        index1 = lastIndex;

        int l = 1, r = i, mid;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).maxValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).maxValue == a[i]) index2 = l;
        else if(T->query(r, i).maxValue == a[i]) index2 = r;

        maxTree->update(index2-1, i-1, a[i]);

        l = 1;
        r = i;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).minValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).minValue == a[i]) index3 = l;
        else if(T->query(r, i).minValue == a[i]) index3 = r;

        minTree->update(index3-1, i-1, -a[i]);

        //for(int j = 0;j<i;j++)
        //{
        //    cout << minTree->query(j, j) << " ";
        //}
        //cout << '\n';

        dp[i] = dp[i-1];
        if(index2!=i) dp[i] = max(dp[i], minTree->query(index2-1, i-1) + a[i]);
        if(index3!=i) dp[i] = max(dp[i], maxTree->query(index3-1, i-1) - a[i]);

        maxTree->setValue(i, dp[i], 0);
        minTree->setValue(i, dp[i], 0);

        //cout << dp[i] << '\n';
    }

    cout << dp[n] << '\n';
}


#include<iostream>

using namespace std;

const int MAXN = 1e6 + 5;
const int intInf = 1e9 + 5;
const long long inf = 1e15 + 5;

int n;
int a[MAXN];

int l[MAXN];
long long dp[MAXN];

struct segment
{
    int minValue, maxValue;

    long long getDiff()
    {
        return this->maxValue - this->minValue;
    }
};

segment Merge(segment A, segment B)
{
    segment output;

    output.minValue = min(A.minValue, B.minValue);
    output.maxValue = max(A.maxValue, B.maxValue);

    return output;
}

struct sparseTable
{
    segment a[21][MAXN];

    sparseTable(int arr[], int n)
    {
        for(int i = 1;i<=n;i++)
        {
            this->a[0][i] = {arr[i], arr[i]};
        }
        for(int i = 1;i<21;i++)
        {
            for(int j = 1;j<=n;j++)
            {
                this->a[i][j] = this->a[i-1][j];
                if(j + (1<<(i-1)) <= n)
                {
                    this->a[i][j] = Merge(this->a[i][j], this->a[i-1][ j + (1<<(i-1)) ]);
                }
            }
        }
    }

    segment query(int ql, int qr)
    {
        return Merge(this->a[ l[qr-ql+1] ][ql], this->a[ l[qr-ql+1] ][ qr - (1<<l[qr-ql+1]) + 1 ]);
    }
};
sparseTable *T;

struct node
{
    int l, r;
    int lazy;
    long long maxSum, maxValue;

    node *L, *R;

    node(int l, int r)
    {
        this->l = l;
        this->r = r;

        this->lazy = -inf;
        this->maxSum = -inf;
        this->maxValue = -inf;

        this->L = nullptr;
        this->R = nullptr;
    }

    void updateLazy()
    {
        if(this->lazy==-intInf) return;

        this->maxSum = this->maxValue + this->lazy;
        if(this->l!=this->r)
        {
            this->L->lazy = max(this->L->lazy, this->lazy);
            this->R->lazy = max(this->R->lazy, this->lazy);
        }

        this->lazy = -intInf;
    }

    void build(int l, int r)
    {
        if(l==r)
        {
            return;
        }

        this->L = new node(l, (l+r)/2);
        this->R = new node((l+r)/2+1, r);

        this->L->build(l, (l+r)/2);
        this->R->build((l+r)/2+1, r);
    }

    long long query(int ql, int qr)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr) return this->maxSum;
        if(this->r<ql || this->l>qr) return -2*inf;

        return max(this->L->query(ql, qr), this->R->query(ql, qr));
    }

    void update(int ql, int qr, int value)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr)
        {
            //cout << this->l << " " << this->r << " --> " << this->maxValue << " + " << value << '\n';

            this->maxSum = this->maxValue + value;
            if(this->l!=this->r)
            {
                this->L->lazy = max(this->L->lazy, value);
                this->R->lazy = max(this->R->lazy, value);
            }

            return;
        }
        if(this->r<ql || this->l>qr) return;

        this->L->update(ql, qr, value);
        this->R->update(ql, qr, value);
        this->maxSum = max(this->L->maxSum, this->R->maxSum);
    }

    void setValue(int q, long long value, long long add)
    {
        this->updateLazy();

        if(this->l==this->r && this->l==q)
        {
            //cout << this->l << " --> " << value << " + " << add << '\n';

            this->maxValue = max(this->maxValue, value);
            this->maxSum = this->maxValue + add;

            return;
        }
        if(this->r<q || this->l>q) return;

        this->L->setValue(q, value, add);
        this->R->setValue(q, value, add);

        this->maxSum = max(this->L->maxSum, this->R->maxSum);
        this->maxValue = max(this->L->maxValue, this->R->maxValue);
    }
};

void Init()
{
    int curr = 0;

    l[0] = 0;
    for(int i = 1;i<=n;i++)
    {
        if(1<<(curr+1)==i) curr++;
        l[i] = curr;
    }

    T = new sparseTable(a, n);
}

node *minTree, *maxTree;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int index1, index2, index3;
    int lastIndex = 1;

    cin >> n;
    for(int i = 1;i<=n;i++)
    {
        cin >> a[i];
    }
    Init();

    maxTree = new node(0, n+1);
    maxTree->build(0, n+1);

    minTree = new node(0, n+1);
    minTree->build(0, n+1);

    dp[0] = 0;
    maxTree->setValue(0, 0, max(a[1], a[2]));
    minTree->setValue(0, 0, -min(a[1], a[2]));

    dp[1] = 0;
    maxTree->setValue(1, 0, max(a[2], a[2]));
    minTree->setValue(1, 0, -min(a[2], a[2]));

    dp[2] = max(a[1], a[2]) - min(a[1], a[2]);
    maxTree->setValue(2, dp[2], 0);
    minTree->setValue(2, dp[2], 0);

    for(int i = 3;i<=n;i++)
    {
        index2 = -1;
        index3 = -1;
        index1 = lastIndex;

        int l = 1, r = i, mid;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).maxValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).maxValue == a[i]) index2 = l;
        else if(T->query(r, i).maxValue == a[i]) index2 = r;

        maxTree->update(index2-1, i-1, a[i]);

        l = 1;
        r = i;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).minValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).minValue == a[i]) index3 = l;
        else if(T->query(r, i).minValue == a[i]) index3 = r;

        minTree->update(index3-1, i-1, -a[i]);

        //for(int j = 0;j<i;j++)
        //{
        //    cout << minTree->query(j, j) << " ";
        //}
        //cout << '\n';

        dp[i] = dp[i-1];
        if(index2!=i) dp[i] = max(dp[i], minTree->query(index2-1, i-1) + a[i]);
        if(index3!=i) dp[i] = max(dp[i], maxTree->query(index3-1, i-1) - a[i]);

        maxTree->setValue(i, dp[i], 0);
        minTree->setValue(i, dp[i], 0);

        //cout << dp[i] << '\n';
    }

    cout << dp[n] << '\n';
}


#include<iostream>
#include<stack>

using namespace std;

const int MAXN = 1e6 + 5;
const int intInf = 1e9 + 5;
const long long inf = 1e15 + 5;

int n;
int a[MAXN];

int l[MAXN];
long long dp[MAXN];

struct segment
{
    int minValue, maxValue;

    long long getDiff()
    {
        return this->maxValue - this->minValue;
    }
};

segment Merge(segment A, segment B)
{
    segment output;

    output.minValue = min(A.minValue, B.minValue);
    output.maxValue = max(A.maxValue, B.maxValue);

    return output;
}

struct sparseTable
{
    segment a[21][MAXN];

    sparseTable(int arr[], int n)
    {
        for(int i = 1;i<=n;i++)
        {
            this->a[0][i] = {arr[i], arr[i]};
        }
        for(int i = 1;i<21;i++)
        {
            for(int j = 1;j<=n;j++)
            {
                this->a[i][j] = this->a[i-1][j];
                if(j + (1<<(i-1)) <= n)
                {
                    this->a[i][j] = Merge(this->a[i][j], this->a[i-1][ j + (1<<(i-1)) ]);
                }
            }
        }
    }

    segment query(int ql, int qr)
    {
        return Merge(this->a[ l[qr-ql+1] ][ql], this->a[ l[qr-ql+1] ][ qr - (1<<l[qr-ql+1]) + 1 ]);
    }
};
sparseTable *T;

struct node
{
    int l, r;
    int lazy;
    long long maxSum, maxValue;

    node *L, *R;

    node(int l, int r)
    {
        this->l = l;
        this->r = r;

        this->lazy = -inf;
        this->maxSum = -inf;
        this->maxValue = -inf;

        this->L = nullptr;
        this->R = nullptr;
    }

    void updateLazy()
    {
        if(this->lazy==-intInf) return;

        this->maxSum = this->maxValue + this->lazy;
        if(this->l!=this->r)
        {
            this->L->lazy = max(this->L->lazy, this->lazy);
            this->R->lazy = max(this->R->lazy, this->lazy);
        }

        this->lazy = -intInf;
    }

    void build(int l, int r)
    {
        if(l==r)
        {
            return;
        }

        this->L = new node(l, (l+r)/2);
        this->R = new node((l+r)/2+1, r);

        this->L->build(l, (l+r)/2);
        this->R->build((l+r)/2+1, r);
    }

    long long query(int ql, int qr)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr) return this->maxSum;
        if(this->r<ql || this->l>qr) return -2*inf;

        return max(this->L->query(ql, qr), this->R->query(ql, qr));
    }

    void update(int ql, int qr, int value)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr)
        {
            //cout << this->l << " " << this->r << " --> " << this->maxValue << " + " << value << '\n';

            this->maxSum = this->maxValue + value;
            if(this->l!=this->r)
            {
                this->L->lazy = max(this->L->lazy, value);
                this->R->lazy = max(this->R->lazy, value);
            }

            return;
        }
        if(this->r<ql || this->l>qr) return;

        this->L->update(ql, qr, value);
        this->R->update(ql, qr, value);
        this->maxSum = max(this->L->maxSum, this->R->maxSum);
    }

    void setValue(int q, long long value, long long add)
    {
        this->updateLazy();

        if(this->l==this->r && this->l==q)
        {
            //cout << this->l << " --> " << value << " + " << add << '\n';

            this->maxValue = max(this->maxValue, value);
            this->maxSum = this->maxValue + add;

            return;
        }
        if(this->r<q || this->l>q) return;

        this->L->setValue(q, value, add);
        this->R->setValue(q, value, add);

        this->maxSum = max(this->L->maxSum, this->R->maxSum);
        this->maxValue = max(this->L->maxValue, this->R->maxValue);
    }
};

void Init()
{
    int curr = 0;

    l[0] = 0;
    for(int i = 1;i<=n;i++)
    {
        if(1<<(curr+1)==i) curr++;
        l[i] = curr;
    }

    T = new sparseTable(a, n);
}

node *minTree, *maxTree;
stack < pair <int, int> > st1, st2;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int index1, index2, index3;
    int lastIndex = 1;

    cin >> n;
    for(int i = 1;i<=n;i++)
    {
        cin >> a[i];
    }
    //Init();

    maxTree = new node(0, n+1);
    maxTree->build(0, n+1);

    minTree = new node(0, n+1);
    minTree->build(0, n+1);

    dp[0] = 0;
    maxTree->setValue(0, 0, max(a[1], a[2]));
    minTree->setValue(0, 0, -min(a[1], a[2]));

    dp[1] = 0;
    maxTree->setValue(1, 0, max(a[2], a[2]));
    minTree->setValue(1, 0, -min(a[2], a[2]));

    dp[2] = max(a[1], a[2]) - min(a[1], a[2]);
    maxTree->setValue(2, dp[2], 0);
    minTree->setValue(2, dp[2], 0);

    st1.push({a[1], 1});
    st1.push({a[2], 2});

    st2.push({a[1], 1});
    st2.push({a[2], 2});

    for(int i = 3;i<=n;i++)
    {
        index2 = -1;
        index3 = -1;
        index1 = lastIndex;

        index2 = i;
        while(st1.empty()==false && st1.top().first<=a[i])
        {
            index2 = st1.top().second;
            st1.pop();
        }

        maxTree->update(index2-1, i-1, a[i]);

        index3 = i;
        while(st2.empty()==false && st2.top().first>=a[i])
        {
            index3 = st2.top().second;
            st2.pop();
        }

        minTree->update(index3-1, i-1, -a[i]);

        //for(int j = 0;j<i;j++)
        //{
        //    cout << minTree->query(j, j) << " ";
        //}
        //cout << '\n';

        dp[i] = dp[i-1];
        if(index2!=i) dp[i] = max(dp[i], minTree->query(index2-1, i-1) + a[i]);
        if(index3!=i) dp[i] = max(dp[i], maxTree->query(index3-1, i-1) - a[i]);

        maxTree->setValue(i, dp[i], 0);
        minTree->setValue(i, dp[i], 0);

        st1.push({a[i], index2});
        st2.push({a[i], index3});

        //cout << dp[i] << '\n';
    }

    cout << dp[n] << '\n';
}


#include<iostream>

using namespace std;

const int MAXN = 1e6 + 5;
const long long inf = 1e9 + 5;

int n;
int a[MAXN];

int l[MAXN];
long long dp[MAXN];

struct segment
{
    int minValue, maxValue;

    long long getDiff()
    {
        return this->maxValue - this->minValue;
    }
};

segment Merge(segment A, segment B)
{
    segment output;

    output.minValue = min(A.minValue, B.minValue);
    output.maxValue = max(A.maxValue, B.maxValue);

    return output;
}

struct sparseTable
{
    segment a[25][MAXN];

    sparseTable(int arr[], int n)
    {
        for(int i = 1;i<=n;i++)
        {
            this->a[0][i] = {arr[i], arr[i]};
        }
        for(int i = 1;i<25;i++)
        {
            for(int j = 1;j<=n;j++)
            {
                this->a[i][j] = this->a[i-1][j];
                if(j + (1<<(i-1)) <= n)
                {
                    this->a[i][j] = Merge(this->a[i][j], this->a[i-1][ j + (1<<(i-1)) ]);
                }
            }

        }
    }

    segment query(int ql, int qr)
    {
        return Merge(this->a[ l[qr-ql+1] ][ql], this->a[ l[qr-ql+1] ][ qr - (1<<l[qr-ql+1]) + 1 ]);
    }
};
sparseTable *T;

struct node
{
    int l, r;
    long long lazy;
    long long maxSum, maxValue;

    node *L, *R;

    node(int l, int r)
    {
        this->l = l;
        this->r = r;

        this->lazy = -inf;
        this->maxSum = -inf;
        this->maxValue = -inf;

        this->L = nullptr;
        this->R = nullptr;
    }

    void updateLazy()
    {
        if(this->lazy==-inf) return;

        this->maxSum = this->maxValue + this->lazy;
        if(this->l!=this->r)
        {
            this->L->lazy = max(this->L->lazy, this->lazy);
            this->R->lazy = max(this->R->lazy, this->lazy);
        }

        this->lazy = -inf;
    }

    void build(int l, int r)
    {
        if(l==r)
        {
            return;
        }

        this->L = new node(l, (l+r)/2);
        this->R = new node((l+r)/2+1, r);

        this->L->build(l, (l+r)/2);
        this->R->build((l+r)/2+1, r);
    }

    long long query(int ql, int qr)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr) return this->maxSum;
        if(this->r<ql || this->l>qr) return -2*inf;

        return max(this->L->query(ql, qr), this->R->query(ql, qr));
    }

    void update(int ql, int qr, long long value)
    {
        this->updateLazy();

        if(this->l>=ql && this->r<=qr)
        {
            //cout << this->l << " " << this->r << " --> " << this->maxValue << " + " << value << '\n';

            this->maxSum = this->maxValue + value;
            if(this->l!=this->r)
            {
                this->L->lazy = max(this->L->lazy, value);
                this->R->lazy = max(this->R->lazy, value);
            }

            return;
        }
        if(this->r<ql || this->l>qr) return;

        this->L->update(ql, qr, value);
        this->R->update(ql, qr, value);
        this->maxSum = max(this->L->maxSum, this->R->maxSum);
    }

    void setValue(int q, long long value, long long add)
    {
        this->updateLazy();

        if(this->l==this->r && this->l==q)
        {
            //cout << this->l << " --> " << value << " + " << add << '\n';

            this->maxValue = max(this->maxValue, value);
            this->maxSum = this->maxValue + add;

            return;
        }
        if(this->r<q || this->l>q) return;

        this->L->setValue(q, value, add);
        this->R->setValue(q, value, add);

        this->maxSum = max(this->L->maxSum, this->R->maxSum);
        this->maxValue = max(this->L->maxValue, this->R->maxValue);
    }
};

void Init()
{
    int curr = 0;

    l[0] = 0;
    for(int i = 1;i<=n;i++)
    {
        if(1<<(curr+1)==i) curr++;
        l[i] = curr;
    }

    T = new sparseTable(a, n);
}

node *minTree, *maxTree;

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    int index1, index2, index3;
    int lastIndex = 1;

    cin >> n;
    for(int i = 1;i<=n;i++)
    {
        cin >> a[i];
    }
    Init();

    maxTree = new node(0, n+1);
    maxTree->build(0, n+1);

    minTree = new node(0, n+1);
    minTree->build(0, n+1);

    dp[0] = 0;
    maxTree->setValue(0, 0, max(a[1], a[2]));
    minTree->setValue(0, 0, -min(a[1], a[2]));

    dp[1] = 0;
    maxTree->setValue(1, 0, max(a[2], a[2]));
    minTree->setValue(1, 0, -min(a[2], a[2]));

    dp[2] = max(a[1], a[2]) - min(a[1], a[2]);
    maxTree->setValue(2, dp[2], 0);
    minTree->setValue(2, dp[2], 0);

    for(int i = 3;i<=n;i++)
    {
        index2 = -1;
        index3 = -1;
        index1 = lastIndex;

        int l = 1, r = i, mid;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).maxValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).maxValue == a[i]) index2 = l;
        else if(T->query(r, i).maxValue == a[i]) index2 = r;

        maxTree->update(index2-1, i-1, a[i]);

        l = 1;
        r = i;
        while(l+1<r)
        {
            mid = (l+r)/2;

            if(T->query(mid, i).minValue == a[i]) r = mid;
            else l = mid + 1;
        }

        if(T->query(l, i).minValue == a[i]) index3 = l;
        else if(T->query(r, i).minValue == a[i]) index3 = r;

        minTree->update(index3-1, i-1, -a[i]);

        //for(int j = 0;j<i;j++)
        //{
        //    cout << minTree->query(j, j) << " ";
        //}
        //cout << '\n';

        dp[i] = dp[i-1];
        if(index2!=i) dp[i] = max(dp[i], minTree->query(index2-1, i-1) + a[i]);
        if(index3!=i) dp[i] = max(dp[i], maxTree->query(index3-1, i-1) - a[i]);

        maxTree->setValue(i, dp[i], 0);
        minTree->setValue(i, dp[i], 0);

        //cout << dp[i] << '\n';
    }

    cout << dp[n] << '\n';
}


#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define eb emplace_back
#define mid ((l + r)/2)
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int N = 1000007;
int v[N];
int n;
ll f[N], seg[4 * N], lazy[4 * N];

void prop(int p, int l, int r) {
	if(lazy[p]) {
		seg[p] += lazy[p];
	}

	if(l != r) {
		lazy[2 * p] += lazy[p];
		lazy[2 * p + 1] += lazy[p];
	}
	lazy[p] = 0;
}

void update(int p, int l, int r, int a, int b, ll x) {
	prop(p, l, r);
	if(r < a or l > b) return;
	if(l >= a and r <= b) {
		lazy[p] += x;
		prop(p, l, r);
	} else {
		update(2 * p, l, mid, a, b, x);
		update(2 * p + 1, mid+1, r, a, b, x);
		seg[p] = max(seg[2 * p], seg[2 * p + 1]);
	}
}

ll query(int p, int l, int r, int a, int b) {
	prop(p, l, r);
	if(r < a or l > b) return -1e17;
	if(l >= a and r <= b)
		return seg[p];
	else
		return max(query(2 * p, l, mid, a, b), query(2 * p + 1, mid+1, r, a, b));
}

inline void add(ii x, bool men) {
	update(1, 1, n, x.se, x.fi, men? -v[x.fi] : v[x.fi]);
}

inline void remove(ii x, bool men) {
	update(1, 1, n, x.se, x.fi, men? v[x.fi] : -v[x.fi]);
}

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n;

	for(int i = 1; i <= n; ++i) cin >> v[i];

	f[0] = 0;

	stack<ii> men, mai;
	for(int i = 1; i <= n; ++i) {
		// f[i] = max_j <= i {max(j, i) - min(j, i) + f[j-1]}
		while(men.size() and v[men.top().fi] > v[i]) {
			remove(men.top(), true);
			men.pop();
		}
		int j = men.size()? men.top().fi + 1 : 1;
		men.push({i, j});
		add(ii(i, j), true);

		while(mai.size() and v[mai.top().fi] < v[i]) {
			remove(mai.top(), false);
			mai.pop();
		}
		j = mai.size()? mai.top().fi + 1 : 1;
		mai.push({i, j});
		add(ii(i, j), false);

		update(1, 1, n, i, i, f[i-1]);
		f[i] = query(1, 1, n, 1, i);
	}

	cout << f[n] << endl;

}


#include <bits/stdc++.h>

#define pb push_back
#define fi first
#define se second
#define eb emplace_back
#define mid ((l + r)/2)
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int N = 1000007;
int v[N];
int n;
ll f[N], seg[2 * N];

void update(int p, ll val) {
	for(seg[p += N] = val; p > 1; p >>= 1)
		seg[p >> 1] = max(seg[p], seg[p^1]);
}

ll query(int l, int r) {
	ll ans = -1e18;
	for(l += N, r += N; l < r; l >>= 1, r >>= 1) {
		if(l&1) ans = max(ans, seg[l++]);
		if(r&1) ans = max(ans, seg[--r]);
	}
	return ans;
}

struct range {
	int l, r;
	ll best_f;

	bool operator < (range r) const {
		return best_f < r.best_f;
	}
};

template< typename T>
struct max_stack {
	stack<pair<T, T>> st;
	void push(T a) {
		st.push(make_pair(a, std::max(a, this->max())));
	}

	void pop() { st.pop(); }

	T top() { return st.top().fi; }
	T max() { return st.size() == 0? range({0, 0, ll(-1e18)}) : st.top().se;}
	int size() {return st.size();}
};

int main() {
	ios::sync_with_stdio(0); cin.tie(0);
	cin >> n;

	for(int i = 1; i <= n; ++i) cin >> v[i];

	f[0] = 0;

	max_stack<range> men, mai;
	for(int i = 1; i <= n; ++i) {
		// f[i] = max_j <= i {max(j, i) - min(j, i) + f[j-1]}

		update(i, f[i-1]);

		f[i] = f[i-1]; // caso em que v[i] nao eh maximo nem minimo
		while(men.size() and v[men.top().r] > v[i])
			men.pop();

		int j = men.size()? men.top().r + 1 : 1;
		men.push({j, i, query(j, i+1) - v[i]});

		while(mai.size() and v[mai.top().r] < v[i]) {
			mai.pop();
		}
		j = mai.size()? mai.top().r + 1 : 1;
		mai.push({j, i, query(j, i + 1) + v[i]});

		// se v[i] eh maximo
		f[i] = max(f[i], v[i] + men.max().best_f);
		// se v[i] eh minimo
		f[i] = max(f[i], mai.max().best_f - v[i]);
	}

	cout << f[n] << endl;

}


#include <iostream>

using namespace std;
int n,i,lmin,lmax;
long long a[1000005];
long long dp[1000005];
bool vmin(int p)
{
    if(a[p]<=a[p-1] && a[p]<=a[p+1])
        return true;

    if(p==1 && a[p]<=a[p+1])
        return true;

    if(p==n && a[p]<=a[p-1])
        return true;

    return false;
}
bool vmax(int p)
{
    if(a[p]>=a[p-1] && a[p]>=a[p+1])
        return true;

    if(p==1 && a[p]>=a[p+1])
        return true;

    if(p==n && a[p]>=a[p-1])
        return true;

    return false;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];

    for(i=1;i<=n;i++)
    {
        dp[i]=dp[i-1];

        if(lmin)
            dp[i]=max(dp[i], dp[lmin-1]+a[i]-a[lmin]);
        if(lmax)
            dp[i]=max(dp[i], dp[lmax-1]+a[lmax]-a[i]);

        if(vmin(i))
            lmin=i;
        if(vmax(i))
            lmax=i;
    }

    cout<<dp[n];
    return 0;
}


#include <iostream>

using namespace std;
int n,i,lmin,lmax;
long long a[1000005];
long long dp[1000005];
bool vmin(int p)
{
    if(a[p]<a[p-1] && a[p]<a[p+1])
        return true;

    if(p==1 && a[p]<a[p+1])
        return true;

    if(p==n && a[p]<a[p-1])
        return true;

    return false;
}
bool vmax(int p)
{
    if(a[p]>a[p-1] && a[p]>a[p+1])
        return true;

    if(p==1 && a[p]>a[p+1])
        return true;

    if(p==n && a[p]>a[p-1])
        return true;

    return false;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];

    for(i=1;i<=n;i++)
    {
        dp[i]=dp[i-1];

        if(lmin)
            dp[i]=max(dp[i], dp[lmin-1]+a[i]-a[lmin]);
        if(lmax)
            dp[i]=max(dp[i], dp[lmax-1]+a[lmax]-a[i]);

        if(vmin(i))
            lmin=i;
        if(vmax(i))
            lmax=i;
    }

    cout<<dp[n];
    return 0;
}


#include <iostream>

using namespace std;
int n,i,lmin,lmax;
long long a[1000005];
long long dp[1000005];
bool vmin(int p)
{
    if(a[p]<=a[p-1] && a[p]<=a[p+1])
        return true;

    if(p==1 && a[p]<=a[p+1])
        return true;

    if(p==n && a[p]<=a[p-1])
        return true;

    return false;
}
bool vmax(int p)
{
    if(a[p]>=a[p-1] && a[p]>=a[p+1])
        return true;

    if(p==1 && a[p]>=a[p+1])
        return true;

    if(p==n && a[p]>=a[p-1])
        return true;

    return false;
}
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);

    cin>>n;
    for(i=1;i<=n;i++)
        cin>>a[i];

    for(i=1;i<=n;i++)
    {
        dp[i]=dp[i-1];

        if(lmin)
        {
            dp[i]=max(dp[i], dp[lmin-1]+a[i]-a[lmin]);
            dp[i]=max(dp[i], dp[lmin]+a[i]-a[lmin+1]);
        }

        if(lmax)
        {
            dp[i]=max(dp[i], dp[lmax-1]+a[lmax]-a[i]);
            dp[i]=max(dp[i], dp[lmax]+a[lmax+1]-a[i]);
        }

        if(vmin(i))
            lmin=i;
        if(vmax(i))
            lmax=i;
    }

    cout<<dp[n];
    return 0;
}


#include <bits/stdc++.h>
#define lld long long
#define nmax 1000005
using namespace std;
int n, a[nmax];
lld dp[nmax];
bool interest[nmax];
vector<int>v;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]);
    interest[1] = 1;
    for (int i=2; i<n; ++i)
    {
        if (a[i] > a[i-1] && a[i] > a[i+1]) interest[i] = 1, interest[i+1] = 1, interest[i-1] = 1;
        if (a[i] < a[i-1] && a[i] < a[i+1]) interest[i] = 1, interest[i+1] = 1, interest[i-1] = 1;
    }
    dp[1] = 0;
    v.push_back(1);
    for (int i=2; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        for (int j=v.size()-1,nr=0; j>=0 && nr <= 9; --j,++nr)
            dp[i] = max(dp[i], dp[v[j]-1] + abs(a[v[j]]-a[i]));
        if (interest[i])
            v.push_back(i);
    }
    cout<<dp[n]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define lld long long
#define nmax 1000005
using namespace std;
int n, a[nmax];
lld dp[nmax];
bool interest[nmax];
vector<int>v;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]);
    interest[1] = 1;
    for (int i=2; i<n; ++i)
    {
        if (a[i] > a[i-1] && a[i] > a[i+1]) interest[i] = 1;
        if (a[i] < a[i-1] && a[i] < a[i+1]) interest[i] = 1;
    }
    dp[1] = 0;
    v.push_back(1);
    for (int i=2; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        for (int j=v.size()-1,nr=0; j>=0 && nr <= 5; --j,++nr)
            dp[i] = max(dp[i], dp[v[j]-1] + abs(a[v[j]]-a[i]));
        if (interest[i])
            v.push_back(i);
    }
    cout<<dp[n]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define lld long long
#define nmax 1000005
using namespace std;
int n, a[nmax];
lld dp[nmax];
bool interest[nmax];
vector<int>v;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]);
    interest[1] = 1;
    for (int i=2; i<n; ++i)
    {
        if (a[i] > a[i-1] && a[i] > a[i+1]) interest[i] = 1;
        if (a[i] < a[i-1] && a[i] < a[i+1]) interest[i] = 1;
    }
    dp[1] = 0;
    v.push_back(1);
    for (int i=2; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        for (int j=v.size()-1,nr=0; j>=0 && nr < 3; --j,++nr)
            dp[i] = max(dp[i], dp[v[j]-1] + abs(a[v[j]]-a[i]));
        if (interest[i])
            v.push_back(i);
    }
    cout<<dp[n]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define lld long long
#define nmax 1000005
using namespace std;
int n, a[nmax];
lld dp[nmax];
bool interest[nmax];
vector<int>v;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]);
    interest[1] = 1;
    for (int i=2; i<n; ++i)
    {
        if (a[i] >= a[i-1] && a[i] >= a[i+1]) interest[i] = 1, interest[i+1] = 1, interest[i-1] = 1;
        if (a[i] <= a[i-1] && a[i] <= a[i+1]) interest[i] = 1, interest[i+1] = 1, interest[i-1] = 1;
    }
    dp[1] = 0;
    v.push_back(1);
    for (int i=2; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        for (int j=v.size()-1,nr=0; j>=0 && nr <= 50; --j,++nr)
            dp[i] = max(dp[i], dp[v[j]-1] + abs(a[v[j]]-a[i]));
        if (interest[i])
            v.push_back(i);
    }
    cout<<dp[n]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
#define lld long long
#define nmax 1000005
using namespace std;
int n, a[nmax];
lld dp[nmax];
bool interest[nmax];
vector<int>v;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; ++i)
        scanf("%d",&a[i]);
    interest[1] = 1;
    for (int i=2; i<n; ++i)
    {
        if (a[i] > a[i-1] && a[i] > a[i+1]) interest[i] = 1;
        if (a[i] < a[i-1] && a[i] < a[i+1]) interest[i] = 1;
    }
    dp[1] = 0;
    v.push_back(1);
    for (int i=2; i<=n; ++i)
    {
        dp[i] = dp[i-1];
        for (int j=v.size()-1,nr=0; j>=0 && nr < 3; --j,++nr)
            dp[i] = max(dp[i], dp[v[j]-1] + abs(a[j]-a[i]));
        if (interest[i])
            v.push_back(i);
    }
    cout<<dp[n]<<'\n';
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int a[N];
int dp[N];
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		int mx=-1e17;
		int mn=1e17;
		for(int j=i;j>=1;j--)
		{
			if(i-j+1>5) break;
			mx=max(mx,a[j]);
			mn=min(mn,a[j]);
			dp[i]=max(dp[i],dp[j-1]+mx-mn);
		}
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int get(vector<int> x)
{
	return (*max_element(all(x)))-(*min_element(all(x)));
}
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	int a[n+1]={0};
	int dp[n+1]={0};
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		vector<int> o;
		for(int j=i;j>=1;j--)
		{
			if(j-i+1>10) break;
			o.pb(a[j]);
			// cout<<a[i]<<" ";
			dp[i]=max(dp[i],dp[j-1]+get(o));
		}
		// cout<<"\n";
		// cout<<dp[i]<<" ";
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int a[N];
int dp[N];
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	for(int i=1;i<=n;i++) cin>>a[i];
	int ans=0;
	int mx1=a[1];
	int mx2=-a[1];
	for(int i=1;i<=n;i++)
	{
		ans=max(ans,mx1-a[i]);
		ans=max(ans,mx2+a[i]);
		if(i==n) continue;
		mx1=max(mx1,ans+a[i+1]);
		mx2=max(mx2,ans-a[i+1]);
	}
	cout<<ans;
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;

int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	int a[n+1]={0};
	int dp[n+1]={0};
	for(int i=1;i<=n;i++) cin>>a[i];
	dp[1]=0;
	for(int i=2;i<=n;i++)
	{
		dp[i]=dp[i-1];
		dp[i]=max(dp[i],(i-2>=0?dp[i-2]:0)+abs(a[i]-a[i-1]));
		// cout<<dp[i]<<" ";
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;

int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	int a[n+1]={0};
	int dp[n+1]={0};
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		int mx=-1e17;
		int mn=1e17;
		for(int j=i;j>=1;j--)
		{
			if(j-i+1>5) break;
			mx=max(mx,a[j]);
			mn=min(mn,a[j]);
			// cout<<a[i]<<" ";
			dp[i]=max(dp[i],dp[j-1]+mx-mn);
		}
		// cout<<"\n";
		// cout<<dp[i]<<" ";
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int get(vector<int> x)
{
	return (*max_element(all(x)))-(*min_element(all(x)));
}
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	int a[n+1]={0};
	int dp[n+1]={0};
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		vector<int> o;
		for(int j=i;j>=1;j--)
		{
			if(j-i+1>5) break;
			o.pb(a[j]);
			// cout<<a[i]<<" ";
			dp[i]=max(dp[i],dp[j-1]+get(o));
		}
		// cout<<"\n";
		// cout<<dp[i]<<" ";
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int a[N];
int dp[N];
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;

	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		int mx=-1e17;
		int mn=1e17;
		for(int j=i;j>=1;j--)
		{
			if(j-i+1>4) break;
			mx=max(mx,a[j]);
			mn=min(mn,a[j]);
			dp[i]=max(dp[i],dp[j-1]+mx-mn);
		}
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int get(int x,int y,int z)
{
	return max({x,y,z})-min({x,y,z});
}
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;
	int a[n+1]={0};
	int dp[n+1]={0};
	for(int i=1;i<=n;i++) cin>>a[i];
	dp[1]=0;
	for(int i=2;i<=n;i++)
	{
		dp[i]=dp[i-1];
		dp[i]=max(dp[i],(i-2>=0?dp[i-2]:0)+abs(a[i]-a[i-1]));
		if(i-3>=0)
		{
			dp[i]=max(dp[i],dp[i-3]+get(a[i],a[i-1],a[i-2]));
		}
		// cout<<dp[i]<<" ";
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include <bits/stdc++.h>
using namespace std;
#define int long long
#define ld double
#define fi first
#define se second
#define pb push_back
#define pii pair<int,int>
#define all(x) (x).begin(), (x).end()
const int MOD =1e9+7;
int mpow(int a,int b,int p=MOD){a=a%p;int res=1;while(b>0){if(b&1)res=(res*a)%p;a=(a*a)%p;b=b>>1LL;}return res%p;}
const int N=1e6+2,M=1e6+2;
int a[N];
int dp[N];
int32_t main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	#ifdef LOCAL
	freopen("input.txt", "r", stdin);
	// freopen("out10.txt","w",stdout);
	#endif
	int n;
	cin>>n;

	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=2;i<=n;i++)
	{
		int mx=-1e17;
		int mn=1e17;
		for(int j=i;j>=1;j--)
		{
			if(j-i+1>3) break;
			mx=max(mx,a[j]);
			mn=min(mn,a[j]);
			dp[i]=max(dp[i],dp[j-1]+mx-mn);
		}
	}
	cout<<dp[n];
}
//
// dp[i]=max(dp[j]+max(j+1,i)-min(j+1,i));
//
// Don't be afraid to fail. Be afraid not to try.
// "Become grindian instead of greendian" - aryanc403
// When you want to succeed as bad as you want to breathe, only then you’ll Be Successful!
// No Matter,How Fast You Are Driving If You Are Driving in a Wrong Direction You Will Never Reach Your Destination
// When failures hit you, you hit the failures back with Bounce Back!
// When you face failures, Don’t change your goal, Change your strategy!


#include<stdio.h>
int main(){
    int n;
    char map[101][101];
    int answer = 0;
    int count = 0;
    int i,j;
    int clean_row;
    int is_same;
    //while(1){
        memset(map,0,sizeof(map));
        answer = 0;
        scanf("%d",&n);
        for(i = 0 ; i < n ; i++){
            scanf("%s",map[i]);
        }

        for(clean_row = 0 ; clean_row < n ; clean_row++){
            count = 1;
            for(i = clean_row+1; i < n; i++){
                is_same = 1;
                for(j = 0 ; j < n ;j++){

                    if(map[i][j] != map[clean_row][j]){
                        is_same = 0;
                        break;
                    }
                }
                if(is_same == 1) count++;
            }
            if(count > answer){
                answer = count;
            }
        }
        printf("%d\n",answer);
    //}
    return 0;
}


#include<stdio.h>
#include<stdlib.h>
int main()
{
    int n;
    int i,j,num,tmp;
    int count;
    int flag;
    int is_prime[10001],mark[10001];
    int need_check = 0;
    while(1)
    {
        count = 0;
        scanf("%d",&n);
        memset(is_prime,0,sizeof(is_prime));
        memset(mark,0,sizeof(mark));
        is_prime[2] = 1;
        for(i = 3; i <=n ; i++)
        {
            flag = 0;
            for(j = 2; j <i ; j++)
            {
                if(i%j==0)
                {
                    flag = 1;
                    break;
                }
            }
            if(flag == 0)
            {
                is_prime[i] = 1;
            }
        }
        for(i = 2; i <=n; i++)
        {
            if(is_prime[i] == 1)
            {
                num = i;
                while(num <= n)
                {
                    mark[num] =1;
                    count++;
                    num *= i;
                }
            }
        }
        printf("%d\n",count);
        /*for(i = 2 ; i <=n; i++) 这个部分是输出一个具体的方案
            if(mark[i] == 1)
                printf("%d ",i);
        puts("");*/
    }
    return 0;
}

/*
1
0

15
9

19
12

20
12

37
19

211
61

1000
193

894
178
*/


#include<stdio.h>
#include<string.h>
int main()
{
    int i,n,j,cnt=1,chg=0,max=1;
    char str[111][111];
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%s",str[i]);
    }
    for(i=0;i<n;i++){
            cnt=1;
        for(j=0;j<n;j++){
            if(i!=j){
                if(strcmp(str[i],str[j])==0){
                        cnt++;
                        chg++;
                        str[j][0]=49+chg;
                        if(cnt>max) max=cnt;

                }
            }
        }
    }
    printf("%d\n",max);
    return 0;
}


//http://codeforces.com/problemset/problem/554/B
#include<stdio.h>
#include<math.h>
#include<string.h>
#define False 0
#define True 1
#define Max_Aloha 26
// int small(char ch)
// int capital(char ch);
// int prime(int number);
// void bubble_sort(int arr[], int n);
//void upper(char *ptr);
//void lower(char *ptr);
// void sort(char *ptr, int n);
// void RemoveDuplicates(char * arr, char * new_str, int arr_size);
// int Contains(char * arr, char elem, int arr_size);
// int Times_of_shapes(char * str, int len);

int main(void)
{
    int number, times=1, result=1, i, j, len;
    scanf("%d", &number);
    char str[number][number+1];
    for(i=0;i<number;i++)
    {
    	scanf("%s", str[i]);
    }
    len=strlen(str[0]);
    for(i=0;i<number;i++)
    {
    	str[i][len]='\0';
    }
    for(i=0;i<number;i++)
    {
    	times=1;
    	for(j=i+1;j<number;j++)
    	{
    		if(strcmp(str[i], str[j])==False)
    		{
    			times++;
    		}
    		if(times>result)
    		{
    			result=times;
    		}
    	}
    }
    printf("%d\n", result);
	return 0;
}

// int Times_of_shapes(char * str, int len)
// {

// 	int j, i, times=0, result=0;
// 	str[len]='\0';
// 	char temp[len][len+1];
// 	for(i=0;i<=len;i++)
// 	{
// 		temp[0][i]=str[i];
// 	}
// 	for(i=1;i<len;i++)
// 	{
// 		temp[i][0]=temp[i-1][len-1];
// 		for(j=1;j<len;j++)
// 		{
// 			temp[i][j]=temp[i-1][j-1];
// 		}
// 		temp[i][len]='\0';
// 	}

// 	for(i=0;i<len;i++)
// 	{
// 		times=0;
// 		for(j=i+1;j<len;j++)
// 		{
// 			if(strcmp(temp[i], temp[j])==False)
// 			{
// 				times++;
// 			}
// 		}
// 		if(times==False)
// 		{
// 			result++;
// 		}
// 	}
// 	return result;

// }

// int Contains(char * arr, char elem, int arr_size)
// {

//     int index = 0;

//     for(index = 0; index < arr_size; index++)
//     {

//         if(arr[index] == elem)
//         {
//             return True;
//         }
//     }

//     return False;

// }

// void RemoveDuplicates(char * arr, char * new_str, int arr_size)
// {

//     int index = 0, new_index = 0;

//     //clear temp string
//     for(index = 0; index < arr_size; index++)
//     {
//         new_str[index] = 0;
//     }

//     for(index = 0; index < arr_size; index++)
//     {

//         if(Contains(new_str, arr[index], arr_size) == False)
//         {
//             new_str[new_index] = arr[index];
//             new_index++;
//         }
//         if(index==arr_size-1)
//         {
//             new_str[new_index]='\0';
//         }
//     }

// }

// void sort(char *ptr, int n)
// {
// 	int i, j, temp;
// 	for(i=0;i<n-1;i++)
// 	{
// 		for(j=0;j<n-i-1;j++)
// 		{
// 			if(ptr[j]>ptr[j+1])
// 				{
// 					temp=ptr[j];
// 					ptr[j]=ptr[j+1];
// 					ptr[j+1]=temp;
// 				}

// 		}
// 	}

// }

/*
void upper(char *ptr)
{
	int i=0;
	while(ptr[i]!='\0')
	{
		if(ptr[i]>='a'&&ptr[i]<='z')
			ptr[i]-=32;
		i++;
	}

}*/

/*
void lower(char *ptr)
{
	int i=0;
	while(ptr[i]!='\0')
	{
		if(ptr[i]>='A'&&ptr[i]<='Z')
			ptr[i]+=32;
		i++;
	}
}*/

// void bubble_sort(int ptr[], int n)
// {
// 	int i, j, temp;
// 	for(i=0;i<n-1;i++)
// 	{
// 		for(j=0;j<n-i-1;j++)
// 		{
// 			if(ptr[j]>ptr[j+1])
// 				{
// 					temp=ptr[j];
// 					ptr[j]=ptr[j+1];
// 					ptr[j+1]=temp;
// 				}

// 		}
// 	}

//  }

// int capital(char ch)
// {
// 	int flag=0;
// 	if(ch>=65&&ch<=90)
// 		flag=1;
// 	return flag;

// }

// int small(char ch)
// {
// 	int flag=0;
// 	if(ch>='a'&&ch<='z')
// 		flag=1;
// 	return flag;

// }
// int prime(int number)
// {
// 	int flag=1, i;
// 	for(i=2;i<=number/2;i++)
// 	{
// 		if(number%i==0)
// 		{
// 			flag=0;
// 			break;
// 		}
// 	}
// 	if(number<=1)
// 		flag=1;
// 	return flag;
// }


#include <stdio.h>
#include<string.h>
int main(void) {
	int n,i,j,max,c=0;
	scanf("%d",&n);
    char a[n+1][n+1];
    for(i=0;i<n;i++)
      scanf("%s",a[i]);
    for(i=0;i<n;i++)
    {
       c=1;
      for(j=i+1;j<n;j++)
      {
      	  if(strcmp(a[i],a[j])==0)
      	    c++;
      }
      if(c>max)
        max=c;
    }
    printf("%d\n",max);
	return 0;
}


#include <stdio.h>
#include<string.h>
int main(void) {
	int n,i,j,max=0,c=0;
	scanf("%d",&n);
    char a[n+1][n+1];
    for(i=0;i<n;i++)
      scanf("%s",a[i]);
    for(i=0;i<n;i++)
    {
       c=1;
      for(j=i+1;j<n;j++)
      {
      	  if(strcmp(a[i],a[j])==0)
      	    c++;
      }
      if(c>max)
        max=c;
    }
    printf("%d\n",max);
	return 0;
}


/*interface*/
#include<stdio.h>
/*interface implementation*/
#define N 100
/*client*/
int main() {
    int n;
    scanf("%d",&n);
    char room[N][N+1];
    int i,j,k;
    for(i=0; i<n; i++) {
        scanf("%s",room[i]);
    }
    int res=0;
    for(i=0; i<n; i++) {
        int all_one=1;
        for(j=0; j<n; j++) {
            if(room[i][j]=='0') {
                all_one=0;
                break;
            }
        }
        if(!all_one) {
            for(j=0; j<n; j++) {
                if(room[i][j]=='0') {
                    for(k=0; k<n; k++) {
                        if(room[k][j]=='0') room[k][j]='1';
                        else room[k][j]='0';
                    }
                }
            }
        }
        int counter=0;
        for(j=0; j<n; j++) {
            all_one=1;
            for(k=0; k<n; k++) {
                if(room[j][k]=='0') {
                    all_one=0;
                    break;
                }
            }
            if(all_one)counter++;
        }
        if(counter>res) res=counter;
    }
    printf("%d\n",res);
    return 0;
}