#include <bits/stdc++.h>
using namespace std;
// We need to store Slope (m) and Constant (c)
// Value at index i = (slope * i) + c
struct node {
long long slope;
long long c;
};
node tree[400009];
long long ans[400009]; // Use long long for the answer to prevent overflow
// Pushes the slope and constant down to children
void push(int node, int tl, int tr) {
// Left Child
tree[2*node].slope += tree[node].slope;
tree[2*node].c += tree[node].c;
// Right Child
tree[2*node+1].slope += tree[node].slope;
tree[2*node+1].c += tree[node].c;
// Reset current
tree[node].slope = 0;
tree[node].c = 0;
}
// Update adds 'm_add' to slope and 'c_add' to constant for range [l, r]
void update(int node, int l, int r, int tl, int tr, long long m_add, long long c_add) {
if (l > r) {
return;
}
if (l == tl && r == tr) {
tree[node].slope += m_add;
tree[node].c += c_add;
} else {
push(node, tl, tr);
int mid = (tl + tr) / 2;
update(2*node, l, min(r, mid), tl, mid, m_add, c_add);
update(2*node+1, max(l, mid+1), r, mid+1, tr, m_add, c_add);
}
}
// Traverse to leaves to calculate final values
void query(int node, int l, int r) {
if (l == r) {
// Calculate final value: y = mx + c
ans[l] = tree[node].slope * l + tree[node].c;
return;
}
push(node, l, r);
int mid = (l + r) / 2;
query(2*node, l, mid);
query(2*node+1, mid+1, r);
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
int n, m;
if (!(cin >> n >> m)) return 0;
vector<int> v(n);
for (int i = 0; i < n; i++) {
cin >> v[i];
}
long long base_cost = 0;
for (int i = 0; i < n - 1; i++) {
int start = v[i];
int target = v[i+1];
// 1. Calculate Standard Scrolling Cost (Cyclic distance)
int dist = target - start;
if (dist < 0) dist += m;
base_cost += dist;
// 2. Calculate Savings
// Using button 'x' costs: 1 + dist(x, target)
// We save: dist - (1 + dist(x, target))
// Max saving is (dist - 1) when x == target.
// As x moves back from target, saving drops by 1.
int max_save = dist - 1;
if (max_save <= 0) continue;
// We need to add a sequence 1, 2, 3... ending at 'target' with value 'max_save'
// Equation for line: y = 1*i + C
int len = max_save;
int start_idx = target - len + 1;
if (start_idx >= 1) {
// Case 1: The saving range is contiguous (e.g., indices 3, 4, 5)
// Sequence starts at index 'start_idx' with value 1.
// 1 = 1 * start_idx + C => C = 1 - start_idx
update(1, start_idx, target, 1, m, 1, 1 - start_idx);
} else {
// Case 2: The saving range wraps around (e.g., indices ..., m, 1, 2)
// Part A: Suffix of array [m - (needed_len) + 1, m]
// Length of part A
int len_suffix = len - target;
int suffix_start = m - len_suffix + 1;
// Starts with value 1 at suffix_start
// 1 = 1 * suffix_start + C => C = 1 - suffix_start
update(1, suffix_start, m, 1, m, 1, 1 - suffix_start);
// Part B: Prefix of array [1, target]
// This continues the sequence. Value at index 1 is not 1, but (len_suffix + 1).
// val = 1 * i + C
// (len_suffix + 1) = 1 * 1 + C => C = len_suffix
update(1, 1, target, 1, m, 1, len_suffix);
}
}
// Push all lazy values down to leaves
query(1, 1, m);
long long best_saving = 0;
for (int i = 1; i <= m; i++) {
if (ans[i] > best_saving) {
best_saving = ans[i];
}
}
cout << base_cost - best_saving << "\n";
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgovLyBXZSBuZWVkIHRvIHN0b3JlIFNsb3BlIChtKSBhbmQgQ29uc3RhbnQgKGMpCi8vIFZhbHVlIGF0IGluZGV4IGkgPSAoc2xvcGUgKiBpKSArIGMKc3RydWN0IG5vZGUgewogICAgbG9uZyBsb25nIHNsb3BlOwogICAgbG9uZyBsb25nIGM7Cn07Cgpub2RlIHRyZWVbNDAwMDA5XTsKbG9uZyBsb25nIGFuc1s0MDAwMDldOyAvLyBVc2UgbG9uZyBsb25nIGZvciB0aGUgYW5zd2VyIHRvIHByZXZlbnQgb3ZlcmZsb3cKCi8vIFB1c2hlcyB0aGUgc2xvcGUgYW5kIGNvbnN0YW50IGRvd24gdG8gY2hpbGRyZW4Kdm9pZCBwdXNoKGludCBub2RlLCBpbnQgdGwsIGludCB0cikgewogICAgLy8gTGVmdCBDaGlsZAogICAgdHJlZVsyKm5vZGVdLnNsb3BlICs9IHRyZWVbbm9kZV0uc2xvcGU7CiAgICB0cmVlWzIqbm9kZV0uYyAgICAgKz0gdHJlZVtub2RlXS5jOwogICAgCiAgICAvLyBSaWdodCBDaGlsZAogICAgdHJlZVsyKm5vZGUrMV0uc2xvcGUgKz0gdHJlZVtub2RlXS5zbG9wZTsKICAgIHRyZWVbMipub2RlKzFdLmMgICAgICs9IHRyZWVbbm9kZV0uYzsKICAgIAogICAgLy8gUmVzZXQgY3VycmVudAogICAgdHJlZVtub2RlXS5zbG9wZSA9IDA7CiAgICB0cmVlW25vZGVdLmMgPSAwOwp9CgovLyBVcGRhdGUgYWRkcyAnbV9hZGQnIHRvIHNsb3BlIGFuZCAnY19hZGQnIHRvIGNvbnN0YW50IGZvciByYW5nZSBbbCwgcl0Kdm9pZCB1cGRhdGUoaW50IG5vZGUsIGludCBsLCBpbnQgciwgaW50IHRsLCBpbnQgdHIsIGxvbmcgbG9uZyBtX2FkZCwgbG9uZyBsb25nIGNfYWRkKSB7CiAgICBpZiAobCA+IHIpIHsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBpZiAobCA9PSB0bCAmJiByID09IHRyKSB7CiAgICAgICAgdHJlZVtub2RlXS5zbG9wZSArPSBtX2FkZDsKICAgICAgICB0cmVlW25vZGVdLmMgKz0gY19hZGQ7CiAgICB9IGVsc2UgewogICAgICAgIHB1c2gobm9kZSwgdGwsIHRyKTsKICAgICAgICBpbnQgbWlkID0gKHRsICsgdHIpIC8gMjsKICAgICAgICB1cGRhdGUoMipub2RlLCBsLCBtaW4ociwgbWlkKSwgdGwsIG1pZCwgbV9hZGQsIGNfYWRkKTsKICAgICAgICB1cGRhdGUoMipub2RlKzEsIG1heChsLCBtaWQrMSksIHIsIG1pZCsxLCB0ciwgbV9hZGQsIGNfYWRkKTsKICAgIH0KfQoKLy8gVHJhdmVyc2UgdG8gbGVhdmVzIHRvIGNhbGN1bGF0ZSBmaW5hbCB2YWx1ZXMKdm9pZCBxdWVyeShpbnQgbm9kZSwgaW50IGwsIGludCByKSB7CiAgICBpZiAobCA9PSByKSB7CiAgICAgICAgLy8gQ2FsY3VsYXRlIGZpbmFsIHZhbHVlOiB5ID0gbXggKyBjCiAgICAgICAgYW5zW2xdID0gdHJlZVtub2RlXS5zbG9wZSAqIGwgKyB0cmVlW25vZGVdLmM7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgcHVzaChub2RlLCBsLCByKTsKICAgIGludCBtaWQgPSAobCArIHIpIC8gMjsKICAgIHF1ZXJ5KDIqbm9kZSwgbCwgbWlkKTsKICAgIHF1ZXJ5KDIqbm9kZSsxLCBtaWQrMSwgcik7Cn0KCmludCBtYWluKCkgewogICAgaW9zX2Jhc2U6OnN5bmNfd2l0aF9zdGRpbyhmYWxzZSk7CiAgICBjaW4udGllKE5VTEwpOwogICAgY291dC50aWUoTlVMTCk7CgogICAgaW50IG4sIG07CiAgICBpZiAoIShjaW4gPj4gbiA+PiBtKSkgcmV0dXJuIDA7CgogICAgdmVjdG9yPGludD4gdihuKTsKICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSB7CiAgICAgICAgY2luID4+IHZbaV07CiAgICB9CgogICAgbG9uZyBsb25nIGJhc2VfY29zdCA9IDA7CgogICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuIC0gMTsgaSsrKSB7CiAgICAgICAgaW50IHN0YXJ0ID0gdltpXTsKICAgICAgICBpbnQgdGFyZ2V0ID0gdltpKzFdOwoKICAgICAgICAvLyAxLiBDYWxjdWxhdGUgU3RhbmRhcmQgU2Nyb2xsaW5nIENvc3QgKEN5Y2xpYyBkaXN0YW5jZSkKICAgICAgICBpbnQgZGlzdCA9IHRhcmdldCAtIHN0YXJ0OwogICAgICAgIGlmIChkaXN0IDwgMCkgZGlzdCArPSBtOwogICAgICAgIGJhc2VfY29zdCArPSBkaXN0OwoKICAgICAgICAvLyAyLiBDYWxjdWxhdGUgU2F2aW5ncwogICAgICAgIC8vIFVzaW5nIGJ1dHRvbiAneCcgY29zdHM6IDEgKyBkaXN0KHgsIHRhcmdldCkKICAgICAgICAvLyBXZSBzYXZlOiBkaXN0IC0gKDEgKyBkaXN0KHgsIHRhcmdldCkpCiAgICAgICAgLy8gTWF4IHNhdmluZyBpcyAoZGlzdCAtIDEpIHdoZW4geCA9PSB0YXJnZXQuCiAgICAgICAgLy8gQXMgeCBtb3ZlcyBiYWNrIGZyb20gdGFyZ2V0LCBzYXZpbmcgZHJvcHMgYnkgMS4KICAgICAgICAKICAgICAgICBpbnQgbWF4X3NhdmUgPSBkaXN0IC0gMTsKICAgICAgICBpZiAobWF4X3NhdmUgPD0gMCkgY29udGludWU7CgogICAgICAgIC8vIFdlIG5lZWQgdG8gYWRkIGEgc2VxdWVuY2UgMSwgMiwgMy4uLiBlbmRpbmcgYXQgJ3RhcmdldCcgd2l0aCB2YWx1ZSAnbWF4X3NhdmUnCiAgICAgICAgLy8gRXF1YXRpb24gZm9yIGxpbmU6IHkgPSAxKmkgKyBDCiAgICAgICAgCiAgICAgICAgaW50IGxlbiA9IG1heF9zYXZlOyAKICAgICAgICBpbnQgc3RhcnRfaWR4ID0gdGFyZ2V0IC0gbGVuICsgMTsKCiAgICAgICAgaWYgKHN0YXJ0X2lkeCA+PSAxKSB7CiAgICAgICAgICAgIC8vIENhc2UgMTogVGhlIHNhdmluZyByYW5nZSBpcyBjb250aWd1b3VzIChlLmcuLCBpbmRpY2VzIDMsIDQsIDUpCiAgICAgICAgICAgIC8vIFNlcXVlbmNlIHN0YXJ0cyBhdCBpbmRleCAnc3RhcnRfaWR4JyB3aXRoIHZhbHVlIDEuCiAgICAgICAgICAgIC8vIDEgPSAxICogc3RhcnRfaWR4ICsgQyAgPT4gIEMgPSAxIC0gc3RhcnRfaWR4CiAgICAgICAgICAgIHVwZGF0ZSgxLCBzdGFydF9pZHgsIHRhcmdldCwgMSwgbSwgMSwgMSAtIHN0YXJ0X2lkeCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLy8gQ2FzZSAyOiBUaGUgc2F2aW5nIHJhbmdlIHdyYXBzIGFyb3VuZCAoZS5nLiwgaW5kaWNlcyAuLi4sIG0sIDEsIDIpCiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBQYXJ0IEE6IFN1ZmZpeCBvZiBhcnJheSBbbSAtIChuZWVkZWRfbGVuKSArIDEsIG1dCiAgICAgICAgICAgIC8vIExlbmd0aCBvZiBwYXJ0IEEKICAgICAgICAgICAgaW50IGxlbl9zdWZmaXggPSBsZW4gLSB0YXJnZXQ7CiAgICAgICAgICAgIGludCBzdWZmaXhfc3RhcnQgPSBtIC0gbGVuX3N1ZmZpeCArIDE7CiAgICAgICAgICAgIAogICAgICAgICAgICAvLyBTdGFydHMgd2l0aCB2YWx1ZSAxIGF0IHN1ZmZpeF9zdGFydAogICAgICAgICAgICAvLyAxID0gMSAqIHN1ZmZpeF9zdGFydCArIEMgPT4gQyA9IDEgLSBzdWZmaXhfc3RhcnQKICAgICAgICAgICAgdXBkYXRlKDEsIHN1ZmZpeF9zdGFydCwgbSwgMSwgbSwgMSwgMSAtIHN1ZmZpeF9zdGFydCk7CgogICAgICAgICAgICAvLyBQYXJ0IEI6IFByZWZpeCBvZiBhcnJheSBbMSwgdGFyZ2V0XQogICAgICAgICAgICAvLyBUaGlzIGNvbnRpbnVlcyB0aGUgc2VxdWVuY2UuIFZhbHVlIGF0IGluZGV4IDEgaXMgbm90IDEsIGJ1dCAobGVuX3N1ZmZpeCArIDEpLgogICAgICAgICAgICAvLyB2YWwgPSAxICogaSArIEMKICAgICAgICAgICAgLy8gKGxlbl9zdWZmaXggKyAxKSA9IDEgKiAxICsgQyA9PiBDID0gbGVuX3N1ZmZpeAogICAgICAgICAgICB1cGRhdGUoMSwgMSwgdGFyZ2V0LCAxLCBtLCAxLCBsZW5fc3VmZml4KTsKICAgICAgICB9CiAgICB9CgogICAgLy8gUHVzaCBhbGwgbGF6eSB2YWx1ZXMgZG93biB0byBsZWF2ZXMKICAgIHF1ZXJ5KDEsIDEsIG0pOwoKICAgIGxvbmcgbG9uZyBiZXN0X3NhdmluZyA9IDA7CiAgICBmb3IgKGludCBpID0gMTsgaSA8PSBtOyBpKyspIHsKICAgICAgICBpZiAoYW5zW2ldID4gYmVzdF9zYXZpbmcpIHsKICAgICAgICAgICAgYmVzdF9zYXZpbmcgPSBhbnNbaV07CiAgICAgICAgfQogICAgfQoKICAgIGNvdXQgPDwgYmFzZV9jb3N0IC0gYmVzdF9zYXZpbmcgPDwgIlxuIjsKfQ==