#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
struct Edge
{
int from, to, flow, cost;
Edge(int _from, int _to, int _flow, int _cost) : from(_from), to(_to), flow(_flow), cost(_cost) { }
};
struct Graph
{
vector <vector <int>> adia;
vector <Edge> edges;
vector <int> potential, dist, father;
int n, d, s;
Graph(int _n, int _s, int _d) : n(_n), s(_s), d(_d), adia(vector <vector <int>>(_n + 1)) { }
void add_edge(Edge x) {
adia[x.from].push_back(edges.size()), edges.push_back(x);
adia[x.to].push_back(edges.size()), edges.push_back({ x.to, x.from, 0, -x.cost });
}
void bellman()
{
dist = vector <int>(n + 1, 1e9);
queue <int> q({ s });
vector <int> inqueue(n);
inqueue[s] = 1;
dist[s] = 0;
while (!q.empty()) {
int x = q.front();
inqueue[x] = 0;
q.pop();
for (auto i : adia[x]) {
if (edges[i].flow && dist[edges[i].to] > dist[x] + edges[i].flow) {
dist[edges[i].to] = dist[x] + edges[i].cost;
if (!inqueue[edges[i].to])
q.push(edges[i].to), inqueue[edges[i].to] = 1;
}
}
}
}
bool djk()
{
potential = dist;
dist = vector <int>(n + 1, 1e9);
father = vector <int>(n + 1, 1e9);
dist[s] = 0;
priority_queue <pair <int, int>> q;
q.push({ 0, s });
while (!q.empty()) {
int x(q.top().second), t(-q.top().first);
q.pop();
if (dist[x] != t)
continue;
for (auto i : adia[x]) {
int cost(-potential[edges[i].to] + potential[x] + edges[i].cost);
if (edges[i].flow && dist[edges[i].to] > dist[x] + cost) {
dist[edges[i].to] = dist[x] + cost;
father[edges[i].to] = i;
q.push({ -dist[edges[i].to], edges[i].to });
}
}
}
for (int i(1); i <= n; i++)
dist[i] += potential[i];
return father[d] != 1e9;
}
pair <int, int> mincostmaxflow()
{
bellman();
int cost(0), flow(0);
while (djk()) {
int mxm(1e9);
for (int i(d); i != s; i = edges[father[i]].from)
mxm = min(mxm, edges[father[i]].flow);
flow += mxm;
for (int i(d); i != s; i = edges[father[i]].from) {
edges[father[i]].flow -= mxm;
edges[father[i] ^ 1].flow += mxm;
cost += edges[father[i]].cost * mxm;
}
}
return { flow, cost };
}
};
Graph x(0, 0, 0);
int main()
{
/*ios_base::sync_with_stdio(0);
cin.tie(0);
int n;
cin >> n;
vector <int> v(n);
for (int i(0); i < n; i++)
cin >> v[i];
Graph x(2 * n + 4, 2 * n + 1, 2 * n + 3);
for (int i(1); i <= n; i++)
x.add_edge({ i, n + i, 1, -1 });
for (int i(1); i < n; i++)
for (int j(i + 1); j <= n; j++)
if (v[i - 1] == 1 + v[j - 1] || v[i - 1] == -1 + v[j - 1] || v[i - 1] % 7 == v[j - 1] % 7 || v[i - 1] == v[j - 1])
x.add_edge({ n + i, j, 1, 0 });
for (int i(1); i <= n; i++)
x.add_edge({ 2 * n + 1, i, 1, 0 }), x.add_edge({ n + i, 2 * n + 2, 1, 0 });
x.add_edge({ 2 * n + 2, 2 * n + 3, 4, 0 });
cout << -x.mincostmaxflow().second;
/*/int n, m, s, d;
ifstream in("fmcm.in");
ofstream out("fmcm.out");
in >> n >> m >> s >> d;
x = Graph(n + 1, s, d);
int a, b, c;
while (m--) {
in >> a >> b >> c >> d;
x.add_edge({ a, b, c, d });
}
out << x.mincostmaxflow().second;
//*/
return 0;
}