#include <bits/stdc++.h>
using namespace std;
// (Giữ nguyên các defines và hàm phụ trợ)
const int maxn = 20000 + 5;
const int max_tool_id = 10000 + 5;
const int max_steps = 1000 + 5;
int n, k, a[maxn], ans = 0;
int cur[max_tool_id], nxt[maxn];
struct ToolInfo {
int next_use;
int id;
bool operator<(const ToolInfo& other) const {
if (next_use != other.next_use) {
return next_use > other.next_use;
}
return id < other.id;
}
};
set<ToolInfo> g[max_steps];
bool is_present[max_steps][max_tool_id];
inline void rf()
{
ios_base::sync_with_stdio(false);
cin.tie(nullptr); cout.tie(nullptr);
}
// KHAI BÁO SỚM
inline int can_lay_len(int i, int x);
inline int can_dat_xuong(int i, int x);
// Chi phí để lấy vật x từ i-1 lên i (sau khi đã đảm bảo i có chỗ)
inline int can_lay_len(int i, int x)
{
if (i <= 0) return 0;
// 1. Nếu đã có trên i, không cần làm gì
if (is_present[i][x]) return 0;
// 2. Nếu chưa có trên i, phải lấy từ i-1 lên.
int cost = can_lay_len(i-1, x);
// 3. Thực hiện chuyển i-1 -> i (chi phí 1)
cost += 1;
// 4. Đảm bảo bậc i có chỗ (tính chi phí đẩy vật xuống)
cost += can_dat_xuong(i, x);
// 5. Cập nhật trạng thái
// Xóa vật x khỏi bậc i-1 (Nếu i-1 > 0)
if (i > 1) {
set<ToolInfo>::iterator it;
for(it = g[i-1].begin(); it != g[i-1].end(); ++it) {
if (it->id == x) break;
}
if (it != g[i-1].end()) {
g[i-1].erase(it);
is_present[i-1][x] = false;
}
}
// Đặt vật x lên bậc i
g[i].insert({cur[x], x});
is_present[i][x] = true;
return cost;
}
// Chi phí để đảm bảo bậc i có chỗ cho vật x (bằng cách đẩy vật cần dùng xa nhất xuống)
inline int can_dat_xuong(int i, int x)
{
if (i <= 0) return 0;
if (g[i].size() < 2) return 0; // Đã có chỗ
// Bậc i đầy: Phải đẩy vật Y xa nhất xuống.
ToolInfo to_remove = *g[i].begin();
// 1. Xóa vật Y khỏi bậc i
g[i].erase(g[i].begin());
is_present[i][to_remove.id] = false;
// 2. Chuyển vật Y xuống i-1 (chi phí 1)
int cost = 1;
// 3. Đảm bảo vật Y có chỗ trên bậc i-1 (sẽ gây chuỗi đẩy vật)
cost += can_dat_xuong(i-1, to_remove.id);
// 4. Đặt vật Y lên bậc i-1
if (i > 1) { // Chỉ đặt nếu i-1 > 0
g[i-1].insert(to_remove);
is_present[i-1][to_remove.id] = true;
}
return cost;
}
signed main()
{
rf();
cin >> n >> k;
for(int i = 1; i <= k; ++i) cin >> a[i];
// 1. Pre-calculate
for(int i = 1; i < max_tool_id; ++i) cur[i] = k+1;
for(int i = k; i >= 1; --i)
{
int x=a[i];
nxt[i]=cur[x]; cur[x]=i;
}
// 2. Vòng lặp chính
for(int i = 1; i <= k; ++i)
{
int x = a[i];
// A. Cập nhật next_use
cur[x] = nxt[i];
// B. Tính chi phí lấy lên bậc N
ans += can_lay_len(n, x);
// C. Vật X được sử dụng và rơi về sàn (BẬC 0).
// Xóa vật X khỏi bậc N
if (is_present[n][x]) {
set<ToolInfo>::iterator it;
for(it = g[n].begin(); it != g[n].end(); ++it) {
if (it->id == x) break;
}
if (it != g[n].end()) {
g[n].erase(it);
is_present[n][x] = false;
}
}
}
// 3. Chi phí kết thúc (mang tất cả vật từ 1..N về sàn)
// Mỗi vật trên bậc i cần i thao tác xuống.
for(int i = 1; i <= n; ++i) {
ans += g[i].size() * i;
}
cout << ans << "\n";
return 0;
}