/*
* Problem :: 13302 / 리조트
*
* Kind :: Dynamic Programming
*
* Insight
* - min([첫번째 날, 쿠폰 0개])
* = min({하루 이용권 + [두번째 날, 쿠폰 0개],
* 연속 3일권 + [네번째 날, 쿠폰 1개],
* 연속 5일권 + [여섯번째 날, 쿠폰 2개]})
* + DP 로 풀어야 겠구나
* dp[n][c] = n번째 날, 쿠폰 c개를 가지고 N번째 날까지 KOI 리조트를 이용했을 때 최소비용
* # 쿠폰이 3개 이상이면 하루 이용권 한 장으로 교환할 수 있으므로
* 쿠폰 3장 + [n+1번째 날, 쿠폰 c-3개] 도 생각해주자
*
* Point
* - dp[n][c] 가 음수인 경우는 불가능하므로
* 이전에 방문했는지를 -1 로 확인할 수 있다
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
#define endl '\n'
// Set up : Global Variables
int N, M;
bool isImpossible[100+1];
int dp[100+1][40+1];
// Set up : Functions Declaration
int f(int n, int c);
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
cin >> N >> M;
for (int i=0; i<M; i++) {
int d; cin >> d;
isImpossible[d] = true; /* d 일에는 리조트에 갈 수 없다는 뜻 */
}
// Process
memset(dp, -1, sizeof(dp)); /* dp 초기화 */
int ans = f(1, 0);
// Control : Output
cout << ans << endl;
}
// Helper Functions
int f(int n, int c)
/* n번째 날, 쿠폰 c개를 가지고 N번째 날까지 KOI 리조트를 이용했을 때 최소비용을 반환 */
{
/* n > N 이면 N번째 날까지 KOI 리조트를 이용했다는 뜻이기에
* 추가 비용은 없고 탐색을 종료해야하므로 0 을 반환 */
if (n > N) return 0;
/* 이전에 방문된적 있으면 계산된 dp[n][c] 를 반환 */
if (dp[n][c] != -1) return dp[n][c];
/* n번째 날에 리조트에 갈 수 없다면 n+1번째 날을 탐색 */
if (isImpossible[n]) return dp[n][c] = f(n+1, c);
dp[n][c] = min({
10000 + f(n+1, c), /* 하루 이용권 구매 */
25000 + f(n+3, c+1), /* 연속 3일권 구매 */
37000 + f(n+5, c+2), /* 연속 5일권 구매 */
});
if (c >= 3) {
dp[n][c] = min(dp[n][c], f(n+1, c-3)); /* 쿠폰 3장 사용해서 하루 이용권 구매 */
}
return dp[n][c];
}