#include <iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
using namespace std;
const int N = 2050;
const int inf = 0x3f3f3f3f;
int w[N][N];
int dist[N];
bool st[N];
int gcd(int a, int b) {
return !b ? a : gcd(b, a % b);
}
int lcm(int x, int y) {
return x * y / gcd(x, y);
}
//
////常规dijkstra
//int dijstra() {
// //初始化第一个点
// dist[1] = 0;
// //循坏n次,与i无关
// for (int i = 1; i <= 2021; i++) {
// //找一个dist距离最短的
// int t = -1;
// for (int j = 1; j <= 2021; j++) {
// if (!st[j] && (t == -1 || dist[t] > dist[j])) {
// t = j;
// }
// }
//
// if (t == -1) break;
// //标记找到
// st[t] = true;
// //根据t点更新dist数组
// for (int j = 1; j <= 2021; j++) {
// if (!st[j]) {
// dist[j] = min(dist[j], dist[t] + w[t][j]);
// }
// }
//
// }
//
// if (dist[2021] > inf / 2) return -1;
// else return dist[2021];
//}
typedef pair<int, int> PII;
priority_queue<PII, vector<PII>, greater<PII>> q;
//堆优化的dijkstra,适合稀疏图
int dijkstra() {
//初始化第一个点
dist[1] = 0;
//初始化队列
q.push({ 0,1 });//distance,ver
while (q.size()) {
auto t = q.top();
q.pop();
//提取pair
int di = t.first;
int ver = t.second;
//如果走过就continue
if (st[ver]) continue;
else st[ver] = true;
//找最新的最小点
for (int i = 1; i <= 2021; i++) {
if (!st[i]) {
if (dist[i] > dist[ver] + w[i][ver]) {
dist[i] = dist[ver] + w[i][ver];
//记得push进去更新的点
q.push({ dist[i], i });
}
}
}
}
if (dist[2021] > inf / 2) return -1;
else return dist[2021];
}
int main()
{
memset(dist, inf, sizeof dist);
memset(w, inf, sizeof w);
for (int i = 1; i <= 2021; i++) {
for (int j = i + 1; j <= i + 21; j++) {
//if(i==j) w[i][j]=0;
w[i][j] = lcm(i, j);
w[j][i] = w[i][j];
}
}
cout<<dijkstra()<<endl;
return 0;
}