#define STOPIT
#include <bits/stdc++.h>
#define loop(n) for (lint ngtkana_is_a_genius = 0; ngtkana_is_a_genius < lint(n); ngtkana_is_a_genius++)
#define rep(i, begin, end) for (lint i = lint(begin); (i) < lint(end); i++)
#define all(v) v.begin(), v.end()
#define rand(l, r) std::uniform_int_distribution<>(l, r)(mt)
using lint = long long;
auto mt = std::mt19937_64(std::random_device{}());
auto cmn = [](auto& a, auto b){ if (a > b) {a = b; return true;} return false; };
auto cmx = [](auto& a, auto b){ if (a < b) {a = b; return true;} return false; };
void debug_impl() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) { std::cerr << " " << head; debug_impl(tail...); }
#ifndef STOPIT
#define debug(...)\
  do {\
    std::cerr << std::boolalpha << "[" << #__VA_ARGS__ << "]:";\
    debug_impl(__VA_ARGS__);\
    std::cerr << std::noboolalpha;\
  } while (false)
#else
#define debug(...) {}
#endif

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr>
std::istream& operator>> (std::istream& is, Container& v)
  { for (auto & x : v) { is >> x; } return is; }

template < typename Container, typename Value = typename Container::value_type, std::enable_if_t<!std::is_same< Container, std::string >::value, std::nullptr_t> = nullptr >
std::ostream& operator<< (std::ostream& os, Container const& v) {
 os << "{";
  for (auto it = v.begin(); it != v.end(); it++)
    {os << (it != v.begin() ? "," : "") << *it;}
  return os << "}";
}


template<
  typename Value1,    typename Value2,
  typename BinaryOp1, typename BinaryOp2, typename BinaryOp3,
  typename UnaryOp1,  typename UnaryOp2
  >
class lazy_segment_tree {
    struct node {
      int id, l, r;
      node(int id, int l, int r): id(id), l(l), r(r) {};
      auto size() const { return r - l; }
      auto left_child () const { assert(size() > 1); return node(id * 2,     l, (l + r) / 2); }
      auto right_child() const { assert(size() > 1); return node(id * 2 + 1, (l + r) / 2, r); }
    };

    int                   size;
    int                   n;
    int                   N;
    BinaryOp1             op1;
    BinaryOp2             op2;
    BinaryOp3             op3;
    Value1                id1;
    Value2                id2;
    UnaryOp1              expand;
    UnaryOp2              shrink;
    std::vector< Value1 > table;
    std::vector< Value2 > lazy;
    node                  initial_node;

    auto& op1_eq(Value1& x, Value1 y) {return x = op1(x, y);}
    auto& op2_eq(Value1& x, Value2 y) {return x = op2(x, y);}
    auto& op3_eq(Value2& x, Value2 y) {return x = op3(x, y);}

    void cal(int u)
      { table.at(u) = op1(table.at(2 * u), table.at(2 * u + 1)); }

    auto chain(int u) const {
      auto ret = std::vector<int>{};
      for (auto i = u; i > 0; i /= 2)
        { ret.emplace_back(i); }
      std::reverse(ret.begin(), ret.end());
      return ret;
    }

    auto prop(int u) {
      op2_eq(table.at(u), lazy.at(u));
      if (u < n) {
        op3_eq(lazy.at(2 * u),     shrink(lazy.at(u)));
        op3_eq(lazy.at(2 * u + 1), shrink(lazy.at(u)));
      }
      lazy.at(u)     = id2;
      return table.at(u);
    }

    auto query_base(int l, int r, Value2 val, const node& now) {
      prop(now.id);
      if (now.r <= l || r <= now.l) return id1;
      else if (l <= now.l && now.r <= r) {
        op3_eq(lazy.at(now.id), val);
        return prop(now.id);
      }
      else {
        auto ret =op1(
          query_base(l, r, shrink(val), now.left_child()),
          query_base(l, r, shrink(val), now.right_child())
        );
        cal(now.id);
        return ret;
      }
    }

  public:
    lazy_segment_tree(
      int        size,
      BinaryOp1  op1,
      BinaryOp2  op2,
      BinaryOp3  op3,
      Value1     id1,
      Value2     id2,
      UnaryOp1   expand,
      UnaryOp2   shrink
    ):
      size         (size),
      n            (std::pow(2, int(std::log2(size)) + 1)),
      N            (n * 2),
      op1          (op1),
      op2          (op2),
      op3          (op3),
      id1          (id1),
      id2          (id2),
      expand       (expand),
      shrink       (shrink),
      table        (N, id1),
      lazy         (N, id2),
      initial_node(1, 0, n)
      {
        std::mt19937 mt(std::random_device{}());
        std::uniform_int_distribution< int > dist(-1'000'000, 1'000'000);
        for (auto i = 0; i < 20; i++) {
          Value1 ex1 = dist(mt), ex1_ = dist(mt);
          Value2 ex2 = dist(mt);
          assert(op1(ex1, id1)       == ex1);
          assert(op2(ex1, id2)       == ex1);
          assert(op3(ex2, id2)       == ex2);
          assert(shrink(expand(ex2)) == ex2);
          assert(op2(op1(ex1, ex1_), expand(ex2)) == op1(op2(ex1, ex2), op2(ex1_, ex2)));
        }
      }

    void build(const Value1 x)
      { std::fill(table.begin(), table.end(), x); }

    void build(const std::vector< Value1 >& v) {
      assert(int(v.size()) <= n);
      std::copy(v.begin(), v.end(), table.begin() + n);
      for (int i = n - 1; i >= 0; i--)
        { cal(i); }
    }

    void act(int l, int r, Value2 val) {
      for (int i = 1; i < n; i *= 2)
        { val = expand(val); }
      query_base(l, r, val, initial_node);
    }

    auto query(int l, int r)
      { return query_base(l, r, id2, initial_node); }

    auto quiet_at(int i) const {
      i += n;
      auto actor = id2;
      for (auto j : chain(i)) {
        actor = shrink(actor);
        actor = op3(actor, lazy.at(j));
      }
      return op2(table.at(i), actor);
    }

    auto quiet_collect() const {
      auto ret = std::vector< Value1 >(size);
      for (auto i = 0; i < size; i++)
        { ret.at(i) = quiet_at(i); }
      return ret;
    }

    auto at(int i) {
      i += n;
      for (auto j : chain(i))
        { prop(j); }
      return table.at(i);
    }

    auto collect() {
      for (int i = 0; i < N; i++)
        { prop(i); }
      auto ret = std::vector< Value1 >(size);
      for (auto i = 0; i < size; i++)
        { ret.at(i) = table.at(i + n); }
      return ret;
    }
};

template< class Value1, class Value2, class BinaryOp1, class BinaryOp2, class BinaryOp3, class UnaryOp1, class UnaryOp2 >
auto make_lazy_segment_tree(
  int        size,
  BinaryOp1  op1,
  BinaryOp2  op2,
  BinaryOp3  op3,
  Value1     id1,
  Value2     id2,
  UnaryOp1   expand,
  UnaryOp2   shrink
) {
  return lazy_segment_tree<Value1, Value2, BinaryOp1, BinaryOp2, BinaryOp3, UnaryOp1, UnaryOp2 >(
    size, op1, op2, op3, id1, id2, std::move(expand), std::move(shrink));
}

template< class Value1, class Value2, class BinaryOp1, class BinaryOp2, class BinaryOp3 >
auto make_lazy_segment_tree(
  int        size,
  BinaryOp1  op1,
  BinaryOp2  op2,
  BinaryOp3  op3,
  Value1     id1,
  Value2     id2
) {
  auto f = [](auto x){return x;};
  return make_lazy_segment_tree(size, op1, op2, op3, id1, id2, f, f);
}

template < class Value >
struct vending_machine {
  Value i;
  vending_machine(Value i) : i(i) {}
  auto issue() { return i++; }
};

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  int n, mod; std::cin >> n >> mod;
  std::vector<lint> a(n);
  std::cin>>a;
  for (lint& x : a) x--;
  debug(a);

  auto seg = make_lazy_segment_tree<lint,lint>(
    mod+2,
    std::plus<>{},
    std::plus<>{},
    std::plus<>{},
    0ll,
    0ll,
    [](lint x){ return 2*x; },
    [](lint x){ return x/2; }
  );

  std::vector<lint> cache(mod+2,0);
  rep(i,0,n-1) {
    lint x = a.at(i);
    lint y = a.at(i+1);
    lint l = x + 2;
    lint r = y + 1;
    if (l == mod + 1) {
      l = 1;
    }
    debug(l,r);
    if (l == r) continue;
    if (l < r) {
      seg.act(l, r, 1);
      seg.act(r, r+1, l-r);
    } else {
      lint x = mod - l;
      lint y = r;
      seg.act(0, r, 1);
      seg.act(l, mod, 1);
      seg.act(0, 1, x);
      seg.act(r, r+1, -x-y);
      seg.act(mod, mod+1, -x);
    }

    // debug
    // {
    //   auto b = seg.quiet_collect();
    //   std::partial_sum(all(b), b.begin());
    //   auto c = b;
    //   rep(i,0,mod+2) {
    //     c.at(i) -= cache.at(i);
    //   }
    //   debug(c);
    //   cache = b;
    // }
  }

  auto basic = [&] {
    lint ans = 0;
    rep(i,0,n-1) {
      lint x = a.at(i);
      lint y = a.at(i+1);
      if (x > y) y += mod;
      lint now = y - x;
      ans += now;
    }
    return ans;
  }();
  debug(basic);
  std::vector<lint> cost(mod, basic);
  rep(i,0,mod) {
    cost.at(i) -= seg.query(0,i+1);
  }
  debug(cost);

  lint ans = *std::min_element(all(cost));
  std::cout << ans << std::endl;
  return 0;
}

Measured memory_bytes: 6784