#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;
}