#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <vector>
#include <cmath>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <functional>
#include <random>
#include <ctime>
#include <cassert>
#include <bitset>
#include <unordered_map>
#include <math.h>
#include <queue>

using namespace std;

#define N 200005
#define M 20
#define F 200
mt19937 gen(time(NULL));
#define forn(i, n) for (int i = 0; i < n; i++)
#define fornv(i, n) for (int i = n - 1; i >= 0; i--)
#define pii pair<int, int>
#define forlr(i, l, r) for (int i = l; i <= r; i++)
#define forlrv(i, l, r) for (int i = r; i >= l; i--)
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define mp make_pair
typedef long long ll;
typedef unsigned long long ull;
const long double eps = 1e-9;
const int inf = 1e9;
const int mod = 1e9 + 7;
const ll infinity = 2 * 1e18;
#define p p2
#define endl '\n'

struct flow
{
private:
	struct edge
	{
		int to, c, f, w;
	};

	vector<vector<int>> g;
	vector<edge> e;
	int n, m = 0;
	vector<bool> used;
	vector<ll> d;
	vector<int> inqueue, p;

public:
	flow() {}
	flow(int n) : n(n)
	{
		g.resize(n + 1);
		used.resize(n + 1);
		d.resize(n + 1);
		inqueue.resize(n + 1);
		p.resize(n + 1);
	}

	void add(int u, int v, int c, int w)
	{
		g[u].push_back(2 * m), g[v].push_back(2 * m + 1);
		e.push_back({ v, c, 0, w });
		e.push_back({ u, 0, 0, -w });
		m++;
	}

	bool spfa(int u, int to)
	{
		fill(d.begin(), d.end(), infinity);
		fill(p.begin(), p.end(), -1);
		d[u] = 0;
		deque<int> q;
		inqueue[u] = 1;
		q.push_front(u);

		while (q.size())
		{
			int x = q.front();
			q.pop_front();
			inqueue[x] = 0;

			for (auto v : g[x])
				if (e[v].c - e[v].f > 0 && d[e[v].to] > d[x] + e[v].w)
				{
					p[e[v].to] = v;
					d[e[v].to] = d[x] + e[v].w;
					if (!inqueue[e[v].to])
					{
						inqueue[e[v].to] = 1;
						if (q.empty() || d[q.front()] > d[e[v].to])
							q.push_front(e[v].to);
						else
							q.push_back(e[v].to);
					}
				}
		}

		return d[to] != infinity;
	}

	ll mincost(int u, int v, int k)
	{
		ll cost = 0;
		while (spfa(u, v) && k)
		{
			k--;
			for (int x = p[v]; x != -1; x = p[e[x ^ 1].to])
			{
				e[x].f++;
				e[x ^ 1].f--;
			}
			cost += d[v];
		}

		return cost;
	}
};

int n, w[N];

int main()
{
	cin >> n;

	flow f = flow(2 * n + 1);

	forlr(i, 1, n)
		cin >> w[i];

	forlr(i, 1, n)
		f.add(0, 2 * i - 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i, 2 * n + 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i - 1, 2 * i, 1, -1);

	forlr(i, 1, n)
		forlr(j, i + 1, n)
			if (abs(w[i] - w[j]) == 1 || abs(w[i] - w[j]) % 7 == 0)
				f.add(2 * i, 2 * j - 1, 1, 0);

	cout << -f.mincost(0, 2 * n + 1, 4);
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <vector>
#include <cmath>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <functional>
#include <random>
#include <ctime>
#include <cassert>
#include <bitset>
#include <unordered_map>
#include <math.h>
#include <queue>

using namespace std;

#define N 200005
#define M 20
#define F 200
mt19937 gen(time(NULL));
#define forn(i, n) for (int i = 0; i < n; i++)
#define fornv(i, n) for (int i = n - 1; i >= 0; i--)
#define pii pair<int, int>
#define forlr(i, l, r) for (int i = l; i <= r; i++)
#define forlrv(i, l, r) for (int i = r; i >= l; i--)
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define mp make_pair
typedef long long ll;
typedef unsigned long long ull;
const long double eps = 1e-9;
const int inf = 1e9;
const int mod = 1e9 + 7;
const ll infinity = 2 * 1e18;
#define p p2
#define endl '\n'

struct flow
{
private:
	struct edge
	{
		int to, c, f, w;
	};

	vector<vector<int>> g;
	vector<edge> e;
	int n, m = 0;
	vector<bool> used;
	vector<ll> d;
	vector<int> p;

public:
	flow() {}
	flow(int n) : n(n)
	{
		g.resize(n + 1);
		used.resize(n + 1);
		d.resize(n + 1);
		p.resize(n + 1);
	}

	void add(int u, int v, int c, int w)
	{
		g[u].push_back(2 * m), g[v].push_back(2 * m + 1);
		e.push_back({ v, c, 0, w });
		e.push_back({ u, 0, 0, -w });
		m++;
	}

	bool spfa(int from, int to)
	{
		fill(d.begin(), d.end(), infinity);
		fill(p.begin(), p.end(), -1);
		d[from] = 0;
		priority_queue<pii, vector<pii>, greater<pii>> q;
		q.push(mp(0, from));

		while (q.size())
		{
			pii x = q.top();
			q.pop();

			if (d[x.second] < x.first) continue;

			for (auto v : g[x.second])
			{
				auto &ee = e[v];
				if (ee.c - ee.f > 0 && d[ee.to] > d[x.second] + ee.w)
				{
					p[ee.to] = v;
					d[ee.to] = d[x.second] + ee.w;
					q.push(mp(d[ee.to], ee.to));
				}
			}
		}

		return d[to] != infinity;
	}

	ll mincost(int u, int v, int k)
	{
		ll cost = 0;
		while (spfa(u, v) && k)
		{
			k--;
			for (int x = p[v]; x != -1; x = p[e[x ^ 1].to])
			{
				e[x].f++;
				e[x ^ 1].f--;
			}
			cost += d[v];
		}

		return cost;
	}
};

int n, w[N];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
	cin >> n;

	flow f = flow(2 * n + 1);

	forlr(i, 1, n)
		cin >> w[i];

	forlr(i, 1, n)
		f.add(0, 2 * i - 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i, 2 * n + 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i - 1, 2 * i, 1, -1);

	forlr(i, 1, n)
		forlr(j, i + 1, n)
			if (abs(w[i] - w[j]) == 1 || abs(w[i] - w[j]) % 7 == 0)
				f.add(2 * i, 2 * j - 1, 1, 0);

	cout << -f.mincost(0, 2 * n + 1, 4);
}


#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <unordered_set>
#include <vector>
#include <cmath>
#include <string>
#include <set>
#include <map>
#include <cstdio>
#include <functional>
#include <random>
#include <ctime>
#include <cassert>
#include <bitset>
#include <unordered_map>
#include <math.h>
#include <queue>

using namespace std;

#define N 200005
#define M 20
#define F 200
mt19937 gen(time(NULL));
#define forn(i, n) for (int i = 0; i < n; i++)
#define fornv(i, n) for (int i = n - 1; i >= 0; i--)
#define pii pair<int, int>
#define forlr(i, l, r) for (int i = l; i <= r; i++)
#define forlrv(i, l, r) for (int i = r; i >= l; i--)
#define debug(...) fprintf(stderr, __VA_ARGS__), fflush(stderr)
#define mp make_pair
typedef long long ll;
typedef unsigned long long ull;
const long double eps = 1e-9;
const int inf = 1e9;
const int mod = 1e9 + 7;
const ll infinity = 2 * 1e18;
#define p p2
#define endl '\n'

struct flow
{
private:
	struct edge
	{
		int to, c, f, w;
	};

	vector<vector<int>> g;
	vector<edge> e;
	int n, m = 0;
	vector<bool> used;
	vector<ll> d;
	vector<int> inqueue, p;

public:
	flow() {}
	flow(int n) : n(n)
	{
		g.resize(n + 1);
		used.resize(n + 1);
		d.resize(n + 1);
		inqueue.resize(n + 1);
		p.resize(n + 1);
	}

	void add(int u, int v, int c, int w)
	{
		g[u].push_back(2 * m), g[v].push_back(2 * m + 1);
		e.push_back({ v, c, 0, w });
		e.push_back({ u, 0, 0, -w });
		m++;
	}

	bool spfa(int u, int to)
	{
		fill(d.begin(), d.end(), infinity);
		fill(p.begin(), p.end(), -1);
		d[u] = 0;
		deque<int> q;
		inqueue[u] = 1;
		q.push_front(u);

		while (q.size())
		{
			int x = q.front();
			q.pop_front();
			inqueue[x] = 0;

			for (auto v : g[x])
			{
				auto &ee = e[v];
				if (ee.c - ee.f > 0 && d[ee.to] > d[x] + ee.w)
				{
					p[ee.to] = v;
					d[ee.to] = d[x] + ee.w;
					if (!inqueue[ee.to])
					{
						inqueue[ee.to] = 1;
						if (q.empty() || d[q.front()] > d[ee.to])
							q.push_front(ee.to);
						else
							q.push_back(ee.to);
					}
				}
			}
		}

		return d[to] != infinity;
	}

	ll mincost(int u, int v, int k)
	{
		ll cost = 0;
		while (spfa(u, v) && k)
		{
			k--;
			for (int x = p[v]; x != -1; x = p[e[x ^ 1].to])
			{
				e[x].f++;
				e[x ^ 1].f--;
			}
			cost += d[v];
		}

		return cost;
	}
};

int n, w[N];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);

	cin >> n;

	flow f = flow(2 * n + 1);

	forlr(i, 1, n)
		cin >> w[i];

	forlr(i, 1, n)
		f.add(0, 2 * i - 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i, 2 * n + 1, 1, 0);
	forlr(i, 1, n)
		f.add(2 * i - 1, 2 * i, 1, -1);

	forlr(i, 1, n)
		forlr(j, i + 1, n)
			if (abs(w[i] - w[j]) == 1 || abs(w[i] - w[j]) % 7 == 0)
				f.add(2 * i, 2 * j - 1, 1, 0);

	cout << -f.mincost(0, 2 * n + 1, 4);
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
#include <bits/stdc++.h>
using std::cerr;using std::cin;using std::cout;using std::abs;using std::min;using std::max;using std::swap;using std::map;using std::pair;using std::set;using std::string;using std::vector;
using ll = long long;using uint = unsigned int;using pii = pair<int, int>;using pll = pair<ll, ll>;
#define ff first
#define ss second
#define pb emplace_back
template<typename T> void _dbg(const char* _s,T _h){cerr<<_s<<" = "<<_h <<"\n";}
template<typename T,typename... Ts>void _dbg(const char* _s,T _h,Ts... _t){int _b = 0;while(((_b+=*_s=='(')-=*_s==')')!=0||*_s!=',')cerr<<*_s++;cerr<<" = "<<_h<<",";_dbg(_s+1,_t...);}
#ifdef LOCAL
#define dbg(...) _dbg(#__VA_ARGS__, __VA_ARGS__)
#else
#define dbg(...)
#endif

struct init { init() {cin.tie(0);std::iostream::sync_with_stdio(0);cout << std::fixed << std::setprecision(10);cerr << std::fixed << std::setprecision(5);}~init() {
        #ifdef LOCAL
        cerr << "Time elapsed: " << (double)clock() / CLOCKS_PER_SEC << "s.\n";
        #endif
}} init;

const int MAXN = 11111, INF = 1e9 + 7;
int a[MAXN];

struct edge {
    int from, to, flow, capacity, cost;
    edge(int _from, int _to, int _capacity, int _cost) : from(_from), to(_to), flow(0), capacity(_capacity), cost(_cost) {}
};

vector<int> g[MAXN];
vector<edge> es;

void add_edge(int from, int to, int capacity, int cost) {
    es.pb(from, to, capacity, cost);
    g[from].pb(es.size() - 1);
    es.pb(to, from, 0, -cost);
    g[to].pb(es.size() - 1);
}

int phi[MAXN], dist[MAXN];
void bellmanford(int n, int start) {
    std::fill(dist + 1, dist + n + 1, INF);
    dist[start] = 0;
    for (int i = 1; i < n; ++i)
        for (edge e : es)
            if (e.capacity && dist[e.to] > dist[e.from] + e.cost)
                dist[e.to] = dist[e.from] + e.cost;
}

int from[MAXN];
vector<int> johnson(int n, int start, int finish) {
    std::fill(dist + 1, dist + n + 1, INF);
    std::fill(from + 1, from + n + 1, -1);
    dist[start] = 0;
    set<pii> s;
    s.insert({0, start});
    while (!s.empty()) {
        auto p = *(s.begin());
        s.erase(s.begin());
        if (dist[p.ss] != p.ff)
            continue;
        for (int x : g[p.ss]) {
            edge & e = es[x];
            if (e.flow < e.capacity && dist[e.to] > dist[p.ss] + phi[p.ss] + e.cost - phi[e.to]) {
                s.erase({dist[e.to], e.to});
                dist[e.to] = dist[p.ss] + phi[p.ss] + e.cost - phi[e.to];
                s.insert({dist[e.to], e.to});
                from[e.to] = x;
            }
        }
    }
    vector<int> ans;
    if (dist[finish] == INF)
        return ans;
    while (finish != start) {
        ans.pb(from[finish]);
        finish = es[from[finish]].from;
    }
    for (int i = 1; i <= n; i++)
        phi[i] += dist[i];
    reverse(ans.begin(), ans.end());
    return ans;
}

bool mincost(int n, int s, int t, int k) {
    bellmanford(n, s);
    for (int i = 0; i < k; i++) {
        vector<int> way = johnson(n, s, t);
        if (way.empty())
            return 0;
        for (int x : way) {
            dbg(es[x].from / 2);
            es[x].flow++;
            es[x ^ 1].flow--;
        }
        dbg("===");
    }
    return 1;
}

int main() {

    int n;
    cin >> n;
    int k = 4;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
        int p = 4;
        for (int j = i - 1; p && j >= 0; --j)
            if (a[j] == a[i] - 1) {
                add_edge(2 * j + 1, 2 * i, 1, 0);
                p--;
            }
        p = 4;
        for (int j = i - 1; p && j >= 0; --j)
            if (a[j] == a[i] + 1) {
                add_edge(2 * j + 1, 2 * i, 1, 0);
                p--;
            }
        p = 4;
        for (int j = i - 1; p && j >= 0; --j)
            if (a[j] % 7 == a[i] % 7) {
                add_edge(2 * j + 1, 2 * i, 1, 0);
                p--;
            }

        add_edge(1, 2 * i, 1, 0);
        add_edge(2 * i, 2 * i + 1, 1, -1);
        add_edge(2 * i + 1, 2 * n + 2, 1, 0);
    }

    mincost(2 * n + 3, 1, 2 * n + 2, k);
    int sum = 0;
    for (int i = 0; i < k; ++i) {
        int v = 1;
        while (v != 2 * n + 2) {
            for (int x : g[v]) {
                edge & e = es[x];
                if (e.flow > 0) {
                    sum += e.cost;
                    e.flow--;
                    es[x^1].flow++;
                    v = e.to;
                    break;
                }
            }
        }
    }
    cout << -sum << '\n';

    return 0;
}


#include <bits/stdc++.h>
#define N 10000
#define inf 0x3fffffff
using namespace std;

struct edge{int v,next,c,w;}vs[200010];
int ee=1,st[N],a[N],las1[200010],las2[10];
int n,frm[N],dis[N],S,T,vis[N],cost;
queue <int> q;
inline void addedge(int u,int v,int c,int w)
{
	vs[++ee].v=v;vs[ee].next=st[u];st[u]=ee;
	vs[ee].c=c;vs[ee].w=w;
}
inline void insert(int u,int v,int c,int w)
{
	addedge(u,v,c,w); addedge(v,u,-c,0);
}
inline bool spfa()
{
	memset(vis,0,sizeof vis);
	for(int i=S;i<=T;i++) dis[i]=-inf;
	dis[S]=0; q.push(S); vis[S]=1;
	while(!q.empty())
	{
		int lx=q.front(); q.pop();
		for(int i=st[lx];i;i=vs[i].next)
			if(vs[i].w&&dis[vs[i].v]<dis[lx]+vs[i].c)
			{
				dis[vs[i].v]=dis[lx]+vs[i].c; frm[vs[i].v]=i;
				if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1;
			}
		vis[lx]=0;
	}
	return dis[T]!=-inf;
}
inline void mcmf()
{
	int nw=inf;
	for(int i=T;i!=S;i=vs[frm[i]^1].v)
		nw=min(nw,vs[frm[i]].w);
	for(int i=T;i!=S;i=vs[frm[i]^1].v)
		cost+=nw*vs[frm[i]].c,
		vs[frm[i]].w-=nw,
		vs[frm[i]^1].w+=nw;
}
int main()
{
	cin>>n; S=0; T=n+n+1;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) insert(S,i,0,1),insert(i+n,T,0,1);
	for(int i=n;i>=1;i--)
	{
		if(las1[a[i]+1]) insert(i+n,las1[a[i]+1],0,inf);
		if(las1[a[i]-1]) insert(i+n,las1[a[i]-1],0,inf);
		if(las2[a[i]%7]) insert(i+n,las2[a[i]%7],0,inf);
		las1[a[i]]=i; las2[a[i]%7]=i;
	}
	for(int i=1;i<=n;i++) insert(i,i+n,1,1), insert(i,i+n,0,inf);
	for(int i=1;i<=4&&spfa();i++) mcmf();
	cout << cost << endl;
}


#include <bits/stdc++.h>
#define N 10000
#define inf 0x3fffffff
using namespace std;

inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}

struct edge{int u,v,next,c,w;}vs[200010];
int ee=1,st[N],a[N],las1[200010],las2[10];
int n,frm[N],dis[N],S,T,vis[N],cost;
queue <int> q;
inline void addedge(int u,int v,int c,int w)
{
	vs[++ee].v=v;vs[ee].next=st[u];st[u]=ee;
	vs[ee].c=c;vs[ee].w=w;vs[ee].u=u;
}
inline void insert(int u,int v,int c,int w)
{
	// cerr << u << " " << v << " " << c << " " << w << endl;
	addedge(u,v,c,w); addedge(v,u,-c,0);
}
inline bool spfa()
{
	memset(vis,0,sizeof vis);
	for(int i=S;i<=T;i++) dis[i]=-inf;
	dis[S]=0; q.push(S); vis[S]=1;
	while(!q.empty())
	{
		int lx=q.front(); q.pop();
		for(int i=st[lx];i;i=vs[i].next)
			if(vs[i].w&&dis[vs[i].v]<dis[lx]+vs[i].c)
			{
				dis[vs[i].v]=dis[lx]+vs[i].c; frm[vs[i].v]=i;
				if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1;;
			}
	}
	return dis[T]!=-inf;
}
inline void mcmf()
{
	int nw=inf;
	for(int i=T;i!=S;i=vs[frm[i]].u)
		nw=min(nw,vs[frm[i]].w);
	for(int i=T;i!=S;i=vs[frm[i]].u)
		cost+=nw*vs[frm[i]].c,
		vs[frm[i]].w-=nw,
		vs[frm[i]^1].w+=nw;
}
int main()
{
	n=read(); S=0; T=n+n+1;
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) insert(S,i,0,1),insert(i+n,T,0,1);
	for(int i=n;i>=1;i--)
	{
		if(las1[a[i]+1]) insert(i+n,las1[a[i]+1],0,inf);
		if(las1[a[i]-1]) insert(i+n,las1[a[i]-1],0,inf);
		if(las2[a[i]%7]) insert(i+n,las2[a[i]%7],0,inf);
		las1[a[i]]=i; las2[a[i]%7]=i;
	}
	for(int i=1;i<=n;i++) insert(i,i+n,1,1), insert(i,i+n,0,inf);
	for(int i=1;i<=4&&spfa();i++) mcmf();
	cout << cost << endl;
}


#include <bits/stdc++.h>
#define N 10000
#define inf 0x3fffffff
using namespace std;

struct edge{int u,v,next,c,w;}vs[200010];
int ee=1,st[N],a[N],las1[200010],las2[10];
int n,frm[N],dis[N],S,T,vis[N],cost;
queue <int> q;
inline void addedge(int u,int v,int c,int w)
{
	vs[++ee].v=v;vs[ee].next=st[u];st[u]=ee;
	vs[ee].c=c;vs[ee].w=w;vs[ee].u=u;
}
inline void insert(int u,int v,int c,int w)
{
	addedge(u,v,c,w); addedge(v,u,-c,0);
}
inline bool spfa()
{
	memset(vis,0,sizeof vis);
	for(int i=S;i<=T;i++) dis[i]=-inf;
	dis[S]=0; q.push(S); vis[S]=1;
	while(!q.empty())
	{
		int lx=q.front(); q.pop();
		for(int i=st[lx];i;i=vs[i].next)
			if(vs[i].w&&dis[vs[i].v]<dis[lx]+vs[i].c)
			{
				dis[vs[i].v]=dis[lx]+vs[i].c; frm[vs[i].v]=i;
				if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1;
			}
		vis[lx]=0;
	}
	return dis[T]!=-inf;
}
inline void mcmf()
{
	int nw=inf;
	for(int i=T;i!=S;i=vs[frm[i]].u)
		nw=min(nw,vs[frm[i]].w);
	for(int i=T;i!=S;i=vs[frm[i]].u)
		cost+=nw*vs[frm[i]].c,
		vs[frm[i]].w-=nw,
		vs[frm[i]^1].w+=nw;
}
int main()
{
	cin>>n S=0; T=n+n+1;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=n;i++) insert(S,i,0,1),insert(i+n,T,0,1);
	for(int i=n;i>=1;i--)
	{
		if(las1[a[i]+1]) insert(i+n,las1[a[i]+1],0,inf);
		if(las1[a[i]-1]) insert(i+n,las1[a[i]-1],0,inf);
		if(las2[a[i]%7]) insert(i+n,las2[a[i]%7],0,inf);
		las1[a[i]]=i; las2[a[i]%7]=i;
	}
	for(int i=1;i<=n;i++) insert(i,i+n,1,1), insert(i,i+n,0,inf);
	for(int i=1;i<=4&&spfa();i++) mcmf();
	cout << cost << endl;
}


#include <bits/stdc++.h>
#define N 10000
#define inf 0x3fffffff
using namespace std;

inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}

struct edge{int u,v,next,c,w;}vs[200010];
int ee=1,st[N],a[N],las1[200010],las2[10];
int n,frm[N],dis[N],S,T,vis[N],cost;
queue <int> q;
inline void addedge(int u,int v,int c,int w)
{
	vs[++ee].v=v;vs[ee].next=st[u];st[u]=ee;
	vs[ee].c=c;vs[ee].w=w;vs[ee].u=u;
}
inline void insert(int u,int v,int c,int w)
{
	// cerr << u << " " << v << " " << c << " " << w << endl;
	addedge(u,v,c,w); addedge(v,u,-c,0);
}
inline bool spfa()
{
	memset(vis,0,sizeof vis);
	for(int i=S;i<=T;i++) dis[i]=-inf;
	dis[S]=0; q.push(S); vis[S]=1;
	while(!q.empty())
	{
		int lx=q.front(); q.pop();
		for(int i=st[lx];i;i=vs[i].next)
			if(vs[i].w&&dis[vs[i].v]<dis[lx]+vs[i].c)
			{
				dis[vs[i].v]=dis[lx]+vs[i].c; frm[vs[i].v]=i;
				if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1;
			}
		vis[lx]=0;
	}
	return dis[T]!=-inf;
}
inline void mcmf()
{
	int nw=inf;
	for(int i=T;i!=S;i=vs[frm[i]].u)
		nw=min(nw,vs[frm[i]].w);
	for(int i=T;i!=S;i=vs[frm[i]].u)
		cost+=nw*vs[frm[i]].c,
		vs[frm[i]].w-=nw,
		vs[frm[i]^1].w+=nw;
}
int main()
{
	n=read(); S=0; T=n+n+1;
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) insert(S,i,0,1),insert(i+n,T,0,1);
	for(int i=n;i>=1;i--)
	{
		if(las1[a[i]+1]) insert(i+n,las1[a[i]+1],0,inf);
		if(las1[a[i]-1]) insert(i+n,las1[a[i]-1],0,inf);
		if(las2[a[i]%7]) insert(i+n,las2[a[i]%7],0,inf);
		las1[a[i]]=i; las2[a[i]%7]=i;
	}
	for(int i=1;i<=n;i++) insert(i,i+n,1,1), insert(i,i+n,0,inf);
	for(int i=1;i<=4&&spfa();i++) mcmf();
	cout << cost << endl;
}


#include <bits/stdc++.h>
#define N 10000
#define inf 0x3fffffff
using namespace std;

inline int read()
{
	int x=0,f=1; char ch=getchar();
	while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}
	while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
	return x*f;
}

struct edge{int u,v,next,c,w;}vs[200010];
int ee=1,st[N],a[N],las1[200010],las2[10];
int n,frm[N],dis[N],S,T,vis[N],cost;
queue <int> q;
inline void addedge(int u,int v,int c,int w)
{
	vs[++ee].v=v;vs[ee].next=st[u];st[u]=ee;
	vs[ee].c=c;vs[ee].w=w;vs[ee].u=u;
}
inline void insert(int u,int v,int c,int w)
{
	// cerr << u << " " << v << " " << c << " " << w << endl;
	addedge(u,v,c,w); addedge(v,u,-c,0);
}
inline bool spfa()
{
	memset(vis,0,sizeof vis);
	for(int i=S;i<=T;i++) dis[i]=-inf;
	dis[S]=0; q.push(S); vis[S]=1;
	while(!q.empty())
	{
		int lx=q.front(); q.pop();
		for(int i=st[lx];i;i=vs[i].next)
			if(vs[i].w&&dis[vs[i].v]<dis[lx]+vs[i].c)
			{
				dis[vs[i].v]=dis[lx]+vs[i].c; frm[vs[i].v]=i;
				if(!vis[vs[i].v]) q.push(vs[i].v),vis[vs[i].v]=1;
			}
		vis[lx]=0;
	}
	return dis[T]!=-inf;
}
inline void mcmf()
{
	int nw=inf;
	for(int i=T;i!=S;i=vs[frm[i]].u)
		nw=min(nw,vs[frm[i]].w);
	for(int i=T;i!=S;i=vs[frm[i]].u)
		cost+=nw*vs[frm[i]].c,
		vs[frm[i]].w-=nw,
		vs[frm[i]^1].w+=nw;
}
int main()
{
	n=read(); S=0; T=n+n+1;
	for(int i=1;i<=n;i++) a[i]=read();
	for(int i=1;i<=n;i++) insert(S,i,0,1),insert(i+n,T,0,1);
	for(int i=n;i>=1;i--)
	{
		if(las1[a[i]+1]) insert(i+n,las1[a[i]+1],0,inf);
		if(las1[a[i]-1]) insert(i+n,las1[a[i]-1],0,inf);
		if(las2[a[i]%7]) insert(i+n,las2[a[i]%7],0,inf);
		las1[a[i]]=i; las2[a[i]%7]=i;
	}
	for(int i=1;i<=n;i++) insert(i,i+n,1,1), insert(i,i+n,0,inf);
	for(int i=1;i<=2&&spfa();i++) mcmf();
	cout << cost << endl;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <iomanip>
#include <queue>
#include <stack>

#define mp make_pair
#define pb push_back
#define FI first
#define SI second

#ifdef _MSC_VER
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif

using namespace std;

typedef long long ll;

const int mod = 1000000007;
const int inf = 1000000007;
const int maxn = 3007;
const int maxc = 100003;

struct edge { int to, w, c, f, rev; };

vector<edge> g[3 * maxn];
pair<int, int> from[3 * maxn];
int d[3 * maxn], p[3 * maxn];
int a[maxn], le[maxc], lg[maxc], ls[maxc], lm[10], n;
int s, t;

void addEdge(int v, int u, int w, int c) {
    int rv = (int)g[v].size(), ru = (int)g[u].size();
    g[v].pb({u, w, c, 0, ru});
    g[u].pb({v, -w, 0, 0, rv});
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    int s = 0, t = 3 * n + 1, flow = 0, cost = 0;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    fill(le, le + maxc, -1), fill(lg, lg + maxc, -1), fill(ls, ls + maxc, -1), fill(lm, lm + 10, -1);
    for (int i = 1; i <= n; ++i) {
        int c = a[i];
        addEdge(s, 3 * i - 1, 0, 1);
        addEdge(3 * i - 2, 3 * i - 1, 0, inf);
        addEdge(3 * i - 1, 3 * i, -1, 1);
        addEdge(3 * i, t, 0, 1);
        if (le[c] != -1) addEdge(3 * le[c] - 1, 3 * i - 1, 0, inf);
        if (ls[c - 1] != -1) addEdge(3 * ls[c - 1] - 1, 3 * i - 1, 0, inf);
        if (lg[c + 1] != -1) addEdge(3 * lg[c + 1] - 1, 3 * i - 1, 0, inf);
        if (lm[c % 7] != -1) addEdge(3 * lm[c % 7] - 2, 3 * i - 2, 0, inf);
        ls[c - 1] = lg[c + 1] = -1;
        le[c] = ls[c] = lg[c] = lm[c % 7] = i;
    }
    fill(p, p + 3 * maxn, inf), p[s] = 0;
    for (int v = 1; v <= 3 * n; ++v)
        for (edge e: g[v])
            if (e.to > v) p[e.to] = min(p[e.to], p[v] + e.w);
    while (flow < 4) {
        fill(d, d + 3 * maxn, inf), fill(from, from + 3 * maxn, mp(-1, -1));
        d[s] = 0;
        set<pair<int,int> > q;
        q.insert(mp(d[s], s));
        while (!q.empty()) {
            int v = q.begin()->SI;
            q.erase (q.begin());
            for (edge e: g[v]) {
                int u = e.to, w = e.w + p[v] - p[u];
                if (e.f < e.c && d[v] + w < d[u]) {
                    q.erase(mp(d[u], u));
                    d[u] = d[v] + w;
                    from[u] = mp(v, e.rev);
                    q.insert(mp(d[u], u));
                }
            }
        }
        if (d[t] == inf) break;
        int af = inf;
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            edge *e = &g[pv][g[v][from[v].SI].rev];
            af = min(af, e->c - e->f);
        }
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            int vr = from[v].SI;
            int pvr = g[v][vr].rev;
            g[v][vr].f -= af;
            g[pv][pvr].f += af;
            cost += af * g[pv][pvr].c;
        }
        flow += af;
    }
    cout << cost << endl;
    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <iomanip>
#include <queue>
#include <stack>

#define mp make_pair
#define pb push_back
#define FI first
#define SI second

#ifdef _MSC_VER
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif

using namespace std;

typedef long long ll;

const int inf = 1000000007;
const int maxn = 3007;

struct edge { int to, w, c, f, rev; };

vector<edge> g[3 * maxn];
pair<int, int> from[3 * maxn];
int d[3 * maxn], p[3 * maxn];
int a[maxn], le[100007], lm[10], n, s, t;

void addEdge(int v, int u, int w, int c) {
    int rv = (int)g[v].size(), ru = (int)g[u].size();
    g[v].pb({u, w, c, 0, ru});
    g[u].pb({v, -w, 0, 0, rv});
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    int s = 0, t = 3 * n + 1, flow = 0, cost = 0;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    fill(le, le + 100007, -1), fill(lm, lm + 10, -1);
    for (int i = n; i >= 1; --i) {
        int c = a[i];
        addEdge(s, 3 * i - 1, 0, 1);
        addEdge(3 * i - 2, 3 * i - 1, 0, inf);
        addEdge(3 * i - 1, 3 * i, -1, 1);
        addEdge(3 * i, t, 0, 1);
        int ie = le[c], ig = le[c + 1], il = le[c - 1], im = lm[c % 7];
        if (ie != -1) addEdge(3 * i - 1, 3 * ie - 1, 0, inf);
        if (ig != -1 && (ig < ie || ie == -1)) addEdge(3 * i, 3 * ig - 1, 0, 1);
        if (il != -1 && (il < ie || ie == -1)) addEdge(3 * i, 3 * il - 1, 0, 1);
        if (im != -1) addEdge(3 * i, 3 * im - 2, 0, 1), addEdge(3 * i - 2, 3 * im - 2, 0, inf);
        le[c] = lm[c % 7] = i;
    }
    fill(p, p + 3 * maxn, inf), p[s] = 0;
    for (int v = 0; v <= 3 * n; ++v)
        for (edge e: g[v])
            if (e.to > v) p[e.to] = min(p[e.to], p[v] + e.w);
    while (flow < 4) {
        fill(d, d + 3 * maxn, inf), fill(from, from + 3 * maxn, mp(-1, -1));
        d[s] = 0;
        set<pair<int,int> > q;
        q.insert(mp(d[s], s));
        while (!q.empty()) {
            int v = q.begin()->SI;
            q.erase(q.begin());
            for (edge e: g[v]) {
                int u = e.to, w = e.w + p[v] - p[u];
                if (e.f < e.c && d[v] + w < d[u]) {
                    q.erase(mp(d[u], u));
                    d[u] = d[v] + w;
                    from[u] = mp(v, e.rev);
                    q.insert(mp(d[u], u));
                }
            }
        }
        if (d[t] == inf) break;
        int af = inf;
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            edge *e = &g[pv][g[v][from[v].SI].rev];
            af = min(af, e->c - e->f);
        }
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            int vr = from[v].SI;
            int pvr = g[v][vr].rev;
            g[v][vr].f -= af;
            g[pv][pvr].f += af;
            cost += af * g[pv][pvr].w;
        }
        for (int i = t; i > 0; --i) if (d[i] != inf) p[i] += d[i];
        flow += af;
    }
    cout << -cost << endl;
    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <iomanip>
#include <queue>
#include <stack>

#define mp make_pair
#define pb push_back
#define FI first
#define SI second

#ifdef _MSC_VER
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif

using namespace std;

typedef long long ll;

const int inf = 1000000007;
const int maxn = 3007;

struct edge { int to, w, c, f, rev; };

map<int, int> le;
vector<edge> g[3 * maxn];
pair<int, int> from[3 * maxn];
int d[3 * maxn], p[3 * maxn];
int a[maxn], lm[10], n, s, t;

void addEdge(int v, int u, int w, int c) {
    int rv = (int)g[v].size(), ru = (int)g[u].size();
    g[v].pb({u, w, c, 0, ru});
    g[u].pb({v, -w, 0, 0, rv});
}

int main() {
    scanf("%d", &n);
    int s = 0, t = 3 * n + 1, flow = 0, cost = 0;
    for (int i = 1; i <= n; ++i) scanf("%d", a + i);
    for (int i = n; i >= 1; --i) {
        int c = a[i];
        addEdge(s, 3 * i - 1, 0, 1);
        addEdge(3 * i - 2, 3 * i - 1, 0, inf);
        addEdge(3 * i - 1, 3 * i, -1, 1);
        addEdge(3 * i, t, 0, 1);
        int ie = le[c], ig = le[c + 1], il = le[c - 1], im = lm[c % 7];
        if (ie) addEdge(3 * i - 1, 3 * ie - 1, 0, inf);
        if (ig && (ig < ie || !ie)) addEdge(3 * i, 3 * ig - 1, 0, 1);
        if (il && (il < ie || !ie)) addEdge(3 * i, 3 * il - 1, 0, 1);
        if (im) addEdge(3 * i, 3 * im - 2, 0, 1), addEdge(3 * i - 2, 3 * im - 2, 0, inf);
        le[c] = lm[c % 7] = i;
    }
    fill(p, p + 3 * maxn, inf), p[s] = 0;
    for (int v = 0; v <= 3 * n; ++v)
        for (edge e: g[v])
            if (e.to > v) p[e.to] = min(p[e.to], p[v] + e.w);
    while (flow < 4) {
        fill(d, d + 3 * maxn, inf), fill(from, from + 3 * maxn, mp(-1, -1));
        d[s] = 0;
        set<pair<int,int> > q;
        q.insert(mp(d[s], s));
        while (!q.empty()) {
            int v = q.begin()->SI;
            q.erase(q.begin());
            for (edge e: g[v]) {
                int u = e.to, w = e.w + p[v] - p[u];
                if (e.f < e.c && d[v] + w < d[u]) {
                    q.erase(mp(d[u], u));
                    d[u] = d[v] + w;
                    from[u] = mp(v, e.rev);
                    q.insert(mp(d[u], u));
                }
            }
        }
        if (d[t] == inf) break;
        int af = inf;
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            edge *e = &g[pv][g[v][from[v].SI].rev];
            af = min(af, e->c - e->f);
        }
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            int vr = from[v].SI;
            int pvr = g[v][vr].rev;
            g[v][vr].f -= af;
            g[pv][pvr].f += af;
            cost += af * g[pv][pvr].w;
        }
        for (int i = t; i > 0; --i) if (d[i] != inf) p[i] += d[i];
        flow += af;
    }
    printf("%d\n", -cost);
    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <iomanip>
#include <queue>
#include <stack>

#define mp make_pair
#define pb push_back
#define FI first
#define SI second

#ifdef _MSC_VER
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif

using namespace std;

typedef long long ll;

const int mod = 1000000007;
const int inf = 1000000007;
const int maxn = 3007;
const int maxc = 100003;

struct edge { int to, w, c, f, rev; };

vector<edge> g[3 * maxn];
pair<int, int> from[3 * maxn];
int d[3 * maxn], p[3 * maxn];
int a[maxn], le[maxc], lg[maxc], ls[maxc], lm[10], n;
int s, t;

void addEdge(int v, int u, int w, int c) {
    int rv = (int)g[v].size(), ru = (int)g[u].size();
    g[v].pb({u, w, c, 0, ru});
    g[u].pb({v, -w, 0, 0, rv});
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    int s = 0, t = 3 * n + 1, flow = 0, cost = 0;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    fill(le, le + maxc, -1), fill(lg, lg + maxc, -1), fill(ls, ls + maxc, -1), fill(lm, lm + 10, -1);
    for (int i = 1; i <= n; ++i) {
        int c = a[i];
        addEdge(s, 3 * i - 1, 0, 1);
        addEdge(3 * i - 2, 3 * i - 1, 0, inf);
        addEdge(3 * i - 1, 3 * i, -1, 1);
        addEdge(3 * i, t, 0, 1);
        if (le[c] != -1) addEdge(3 * le[c] - 1, 3 * i - 1, 0, inf);
        if (ls[c - 1] != -1) addEdge(3 * ls[c - 1], 3 * i - 1, 0, 1);
        if (lg[c + 1] != -1) addEdge(3 * lg[c + 1], 3 * i - 1, 0, 1);
        if (lm[c % 7] != -1) addEdge(3 * lm[c % 7], 3 * i - 2, 0, 1), addEdge(3 * lm[c % 7] - 2, 3 * i - 2, 0, inf);
        ls[c - 1] = lg[c + 1] = -1;
        le[c] = ls[c] = lg[c] = lm[c % 7] = i;
    }
    fill(p, p + 3 * maxn, inf), p[s] = 0;
    for (int v = 0; v <= 3 * n; ++v)
        for (edge e: g[v])
            if (e.to > v) p[e.to] = min(p[e.to], p[v] + e.w);
    while (flow < 4) {
        fill(d, d + 3 * maxn, inf), fill(from, from + 3 * maxn, mp(-1, -1));
        d[s] = 0;
        set<pair<int,int> > q;
        q.insert(mp(d[s], s));
        while (!q.empty()) {
            int v = q.begin()->SI;
            q.erase(q.begin());
            for (edge e: g[v]) {
                int u = e.to, w = e.w + p[v] - p[u];
                if (e.f < e.c && d[v] + w < d[u]) {
                    q.erase(mp(d[u], u));
                    d[u] = d[v] + w;
                    from[u] = mp(v, e.rev);
                    q.insert(mp(d[u], u));
                }
            }
        }
        if (d[t] == inf) break;
        int af = inf;
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            edge *e = &g[pv][g[v][from[v].SI].rev];
            af = min(af, e->c - e->f);
        }
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            int vr = from[v].SI;
            int pvr = g[v][vr].rev;
            g[v][vr].f -= af;
            g[pv][pvr].f += af;
            cost += af * g[pv][pvr].w;
        }

        for (int i = t; i > 0; --i) if (d[i] != inf) p[i] += d[i];
        flow += af;
    }
    cout << -cost << endl;
    return 0;
}


#include <iostream>
#include <string>
#include <algorithm>
#include <unordered_set>
#include <algorithm>
#include <functional>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <cstdio>
#include <vector>
#include <string>
#include <set>
#include <map>
#include <bitset>
#include <unordered_map>
#include <iomanip>
#include <queue>
#include <stack>

#define mp make_pair
#define pb push_back
#define FI first
#define SI second

#ifdef _MSC_VER
#define ALIGN(x) __declspec(align(x))
#else
#define ALIGN(x) __attribute__((aligned(x)))
#endif

using namespace std;

typedef long long ll;

const int inf = 1000000007;
const int maxn = 3007;

struct edge { int to, w, c, f, rev; };

vector<edge> g[3 * maxn];
pair<int, int> from[3 * maxn];
int d[3 * maxn], p[3 * maxn];
int a[maxn], le[100007], lm[10], n, s, t;

void addEdge(int v, int u, int w, int c) {
    int rv = (int)g[v].size(), ru = (int)g[u].size();
    g[v].pb({u, w, c, 0, ru});
    g[u].pb({v, -w, 0, 0, rv});
}

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cin >> n;
    int s = 0, t = 3 * n + 1, flow = 0, cost = 0;
    for (int i = 1; i <= n; ++i) cin >> a[i];
    fill(le, le + 100007, -1), fill(lm, lm + 10, -1);
    for (int i = n; i >= 1; --i) {
        int c = a[i];
        addEdge(s, 3 * i - 1, 0, 1);
        addEdge(3 * i - 2, 3 * i - 1, 0, inf);
        addEdge(3 * i - 1, 3 * i, -1, 1);
        addEdge(3 * i, t, 0, 1);
        int ie = le[c], ig = le[c + 1], il = le[c - 1], im = lm[c % 7];
        if (ie != -1) addEdge(3 * i - 1, 3 * ie - 1, 0, inf);
        if (ig != -1 && ie > ig) addEdge(3 * i, 3 * ig - 1, 0, 1);
        if (il != -1 && ie > il) addEdge(3 * i, 3 * il - 1, 0, 1);
        if (im != -1) addEdge(3 * i, 3 * im - 2, 0, 1), addEdge(3 * i - 2, 3 * im - 2, 0, inf);
        le[c] = lm[c % 7] = i;
    }
    fill(p, p + 3 * maxn, inf), p[s] = 0;
    for (int v = 0; v <= 3 * n; ++v)
        for (edge e: g[v])
            if (e.to > v) p[e.to] = min(p[e.to], p[v] + e.w);
    while (flow < 4) {
        fill(d, d + 3 * maxn, inf), fill(from, from + 3 * maxn, mp(-1, -1));
        d[s] = 0;
        set<pair<int,int> > q;
        q.insert(mp(d[s], s));
        while (!q.empty()) {
            int v = q.begin()->SI;
            q.erase(q.begin());
            for (edge e: g[v]) {
                int u = e.to, w = e.w + p[v] - p[u];
                if (e.f < e.c && d[v] + w < d[u]) {
                    q.erase(mp(d[u], u));
                    d[u] = d[v] + w;
                    from[u] = mp(v, e.rev);
                    q.insert(mp(d[u], u));
                }
            }
        }
        if (d[t] == inf) break;
        int af = inf;
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            edge *e = &g[pv][g[v][from[v].SI].rev];
            af = min(af, e->c - e->f);
        }
        for (int v = t; v != s; v = from[v].FI) {
            int pv = from[v].FI;
            int vr = from[v].SI;
            int pvr = g[v][vr].rev;
            g[v][vr].f -= af;
            g[pv][pvr].f += af;
            cost += af * g[pv][pvr].w;
        }
        for (int i = t; i > 0; --i) if (d[i] != inf) p[i] += d[i];
        flow += af;
    }
    cout << -cost << endl;
    return 0;
}


/****** BISMILLAH HIR RAHMANIR RAHIM ******/

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#pragma GCC optimize("unroll-loops")

#include <bits/stdc++.h>
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// #include <ext/pb_ds/detail/standard_policies.hpp>

using namespace std;
// using namespace __gnu_pbds;
// using namespace __gnu_cxx;

typedef long long ll;
typedef unsigned int ul;
typedef unsigned long long ull;
typedef vector <int> vi;
typedef map<string,string> mss;
typedef map<int, vector<int> > mvii;
typedef map<int, int> mii;
typedef queue <int> qi;
typedef map <int, vector<string> > mvis;
typedef map <string, vector<int> > mvsi;
typedef vector <string> vs;
typedef pair <int, int> pii;
typedef vector<pair<int,int> > vpii;

// Order Statistic Tree

/* Special functions:

		find_by_order(k) --> returns iterator to the kth largest element counting from 0
		order_of_key(val) --> returns the number of items in a set that are strictly smaller than our item
*/

// typedef tree<
// int,
// null_type,
// less<int>,
// rb_tree_tag,
// tree_order_statistics_node_update>
// ordered_set;

#define MP make_pair
#define SORT(a) sort (a.begin(), a.end())
#define REVERSE(a) reverse (a.begin(), a.end())
#define ALL(a) a.begin(), a.end()
#define PI acos(-1)
#define ms(x,y) memset (x, y, sizeof (x))
#define pb push_back
#define debug cout<<"A"<<"\n"
#define prnt(a) cout<<a<<"\n"
#define mod 1000000007LL
#define FOR(i,a,b) for (int i=(a); i<(b); i++)
#define FORr(i,a,b) for (int i=(a); i>=b; i--)
#define itrALL(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
#define lc ((node)<<1)
#define rc ((node)<<1|1)
#define VecPrnt(v) FOR(J,0,v.size()) cout<<v[J]<<" "; cout<<endl
#define endl "\n"
#define PrintPair(x) cout<<x.first<<" "<<x.second<<endl
#define ClearQ(x); while(!x.empty()) x.pop()
#define EPS 1e-9
#define ArrPrint(a,st,en) for(int J=st; J<=en; J++) cout<<a[J]<<" "; cout<<endl;

/* Direction Array */

// int fx[]={1,-1,0,0};
// int fy[]={0,0,1,-1};
// int fx[]={0,0,1,-1,-1,1,-1,1};
// int fy[]={-1,1,0,0,1,1,-1,-1};

template <class T> inline T bigmod(T p,T e,T M)
{
    ll ret = 1;
    for(; e > 0; e >>= 1)
    {
        if(e & 1) ret = (ret * p) % M;
        p = (p * p) % M;
    } return (T)ret;
}

template <class T> inline T gcd(T a,T b){if(b==0)return a;return gcd(b,a%b);}
template <class T> inline T modinverse(T a,T M){return bigmod(a,M-2,M);}
template <class T> inline T lcm(T a,T b) {a=abs(a);b=abs(b); return (a/gcd(a,b))*b;}
template <class T, class X> inline bool getbit(T a, X i) { T t=1; return ((a&(t<<i))>0);}
template <class T, class X> inline T setbit(T a, X i) { T t=1;return (a|(t<<i)); }
template <class T, class X> inline T resetbit(T a, X i) { T t=1;return (a&(~(t<<i)));}

inline ll getnum()
{
    char c = getchar();
    ll num,sign=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')sign=-1;
    for(num=0;c>='0'&&c<='9';)
    {
        c-='0';
        num = num*10+c;
        c=getchar();
    }
    return num*sign;
}

inline ll power(ll a, ll b)
{
	ll multiply=1;
	FOR(i,0,b)
	{
		multiply*=a;
	}
	return multiply;
}

/****** END OF HEADER ******/

namespace mcmf{
    const int MAX = 1000010;
    const int INF = 1 << 25;

    int cap[MAX], flow[MAX], cost[MAX], dis[MAX];
    int n, m, s, t, Q[10000010], adj[MAX], link[MAX], last[MAX], from[MAX], visited[MAX];

    void init(int nodes, int source, int sink){
        m = 0, n = nodes, s = source, t = sink;
        for (int i = 0; i <= n; i++) last[i] = -1;
    }

    void addEdge(int u, int v, int c, int w){
        adj[m] = v, cap[m] = c, flow[m] = 0, cost[m] = +w, link[m] = last[u], last[u] = m++;
        adj[m] = u, cap[m] = 0, flow[m] = 0, cost[m] = -w, link[m] = last[v], last[v] = m++;
    }

    bool spfa(){
        int i, j, x, f = 0, l = 0;
        for (i = 0; i <= n; i++) visited[i] = 0, dis[i] = INF;

        dis[s] = 0, Q[l++] = s;
        while (f < l){
            i = Q[f++];
            for (j = last[i]; j != -1; j = link[j]){
                if (flow[j] < cap[j]){
                    x = adj[j];
                    if (dis[x] > dis[i] + cost[j]){
                        dis[x] = dis[i] + cost[j], from[x] = j;
                        if (!visited[x]){
                            visited[x] = 1;
                            if (f && rand() & 7) Q[--f] = x;
                            else Q[l++] = x;
                        }
                    }
                }
            }
            visited[i] = 0;
        }
        return (dis[t] != INF);
    }

    pair <int, int> solve(){
        int i, j;
        int mincost = 0, maxflow = 0;

        while (spfa()){
            int aug = INF;
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                aug = min(aug, cap[j] - flow[j]);
            }
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                flow[j] += aug, flow[j ^ 1] -= aug;
            }
            maxflow += aug, mincost += aug * dis[t];
        }
        return make_pair(mincost, maxflow);
    }
}

int n, a[3005];
int cnt[100005];

int main()
{
    // ios_base::sync_with_stdio(0);
    // cin.tie(NULL); cout.tie(NULL);
    // freopen("in.txt","r",stdin);

    int test, cases=1;

    scanf("%d", &n);

    FOR(i,1,n+1) scanf("%d", &a[i]);

    int src=0, mid=2*n+2, sink=2*n+4;
    mcmf::init(2*n+5,src,sink);

    mcmf::addEdge(src,mid,4,0);

    FOR(i,1,n+1) mcmf::addEdge(i,i+n,1,-1);
    FOR(i,1,n+1) mcmf::addEdge(mid,i,1,0);
    FOR(i,1,n+1) mcmf::addEdge(i+n,sink,1,0);

    FOR(i,1,n+1)
    {
    	FOR(j,1,n+1) cnt[a[j]]=0;

    	FOR(j,i+1,n+1)
    	{
    		cnt[a[j]]++;
    		if(abs(a[i]-a[j])==1 && cnt[a[j]]<=5)
    			mcmf::addEdge(i+n,j,1,0);
    	}
    }

    FOR(i,1,n+1) a[i]%=7;

    FOR(i,1,n+1)
    {
    	FOR(j,1,n+1) cnt[a[j]]=0;

    	FOR(j,i+1,n+1)
    	{
    		cnt[a[j]]++;
    		if(a[i]==a[j] && cnt[a[j]]<=5)
    			mcmf::addEdge(i+n,j,1,0);
    	}
    }

    pii out=mcmf::solve();

    // PrintPair(out);

    prnt(-out.first);

    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int INF=0x3f3f3f3f;
inline int read(){
	int x=0;char ch=getchar();
	while (!isdigit(ch)) ch=getchar();
	while (isdigit(ch)) x=x*10+ch-'0',ch=getchar();
	return x;
}
int n,a[5005],cnt=2,head[30005],ans=0,dis[30005],rev[30005],p[7],tot,rt[100005];
bool inq[20005];
queue<int> que;
struct edge{
	int to,next,cap,c;
}e[100000];
inline void add_edge(int from,int to,int cap,int cost){
	e[cnt].to=to;e[cnt].cap=cap;e[cnt].c=cost;e[cnt].next=head[from];head[from]=cnt++;
	e[cnt].to=from;e[cnt].cap=0;e[cnt].c=-cost;e[cnt].next=head[to];head[to]=cnt++;
}
int main(){
	n=read();
	for (int i=1;i<=n;++i){
		a[i]=read();
		add_edge(i<<1,i<<1|1,1,-1);
		add_edge(0,i<<1,1,0);
		add_edge(i<<1|1,1,1,0);
	}
	tot=n<<1|1;
	for (int i=0;i<7;++i) p[i]=++tot;
	for (int i=1;i<=n;++i){
		add_edge(p[a[i]%7],i<<1,1,0);
		add_edge(p[a[i]%7],++tot,INF,0);
		p[a[i]%7]=tot;
		add_edge(i<<1|1,p[a[i]%7],1,0);
		if (rt[a[i]-1]) add_edge(rt[a[i]-1],i<<1,1,0);
		if (rt[a[i]+1]) add_edge(rt[a[i]+1],i<<1,1,0);
		if (!rt[a[i]]){
			rt[a[i]]=++tot;
			add_edge(i<<1|1,tot,1,0);
		}
		else{
			add_edge(i<<1|1,++tot,1,0);
			add_edge(rt[a[i]],tot,INF,0);
			rt[a[i]]=tot;
		}
	}
	for (int tim=0;tim<4;++tim){
		memset(dis,63,sizeof(dis));
		memset(inq,false,sizeof(inq));
		while (!que.empty()) que.pop();
		que.push(0);dis[0]=0;
		while (!que.empty()){
			int x=que.front();que.pop();inq[x]=false;
			for (int i=head[x];i;i=e[i].next){
				if (!e[i].cap) continue;
				int y=e[i].to;
				if (dis[y]>dis[x]+e[i].c){
					dis[y]=dis[x]+e[i].c;rev[y]=i;
					if (!inq[y]){
						inq[y]=true;
						que.push(y);
					}
				}
			}
		}
		ans-=dis[1];int x=1;
		while (x){
			--e[rev[x]].cap;
			++e[rev[x]^1].cap;
			x=e[rev[x]^1].to;
		}
	}
	printf ("%d\n",ans);
	return 0;
}


#include<cstdlib>
#include<cstdio>
#define inf 100000000
#include<queue>
using namespace std;
const int N0=5010,N=20010,A=100010;
queue<int>q;
int n,cnt,head1[10],head2[A],S1,S,T,ans,flow[N],dis[N],inq[N],k;
struct node{int v,w,c;node *next,*rev;}pool[20*N0],*h[N],*from[N];
void add(int u,int v,int c,int w,int flag=0)
{
	if(v==0) return;
//	if(flag)
//	printf("%d %d    %d %d\n",u,v,c,w);
	node *p=&pool[++cnt],*q=&pool[++cnt];
	p->v=v;p->next=h[u];h[u]=p; p->c=c;p->w=w; p->rev=q;
	q->v=u;q->next=h[v];h[v]=q; q->c=0;q->w=-w;q->rev=p;
}
bool SPFA()
{
	for(int i=1;i<=S1;i++) dis[i]=-inf;
	flow[S]=inf;inq[S]=1;q.push(S);dis[S]=0;
	while(!q.empty())
	{
		int u=q.front();q.pop();
	//	printf("%d\n",u);
		for(node *t=h[u];t;t=t->next)
			if(t->c&&dis[t->v]<dis[u]+t->w)
			{
				dis[t->v]=dis[u]+t->w;
				from[t->v]=t;
				flow[t->v]=min(t->c,flow[u]);
				if(inq[t->v]==0) inq[u]=1,q.push(t->v);
			}
		inq[u]=0;
	}
//	printf("-----\n");
	return dis[T]!=-inf;
}

int mxc()
{
	int fl=flow[T];
	for(node *t=from[T];t;t=from[t->rev->v])
		t->c-=fl,t->rev->c+=fl;
	return dis[T]*fl;
}
void pt()
{
	for(int i=0;i<7;i++) printf("%d ",head1[i]);printf("\n");
}
int main()
{
	scanf("%d",&n);k=4;
	S=4*n+1,T=S+1,S1=T+1;
	for(int i=0;i<8;i++) head1[i]=-n;
	for(int i=0;i<A;i++) head2[i]=-2*n;
	for(int i=1,x;i<=n;i++)
	{
		scanf("%d",&x);
		add(3*n+i,i,1,1);
		add(2*n+i,i+3*n,1,0);
		add(2*n+i,2*n+head2[x],k,0,1); head2[x]=i;
		add(i,2*n+head2[x-1],1,0,1);
		add(i,2*n+head2[x+1],1,0,1);

		add(n+i,3*n+i,1,0);
		add(n+i,n+head1[x%7],k,0,1);
		add(i,n+head1[x%7],1,0,1);
		head1[x%7]=i;
	}
	add(S,S1,k,0);
	for(int i=1;i<=n;i++)  add(S1,3*n+i,1,0),add(i,T,1,0);
	while(SPFA()) ans+=mxc();
	printf("%d\n",ans);
} //


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 5;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt2 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 5;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 12345;
const int inf = 0x3f3f3f3f;
const int MXE = 1e6;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, -1);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, 0);
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 || a[i] % 7 == a[j] % 7) F.add(i + n, j, 1, -1);
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 3;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt2 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 10;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 5;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 123456;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    int magic = 4;
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, 0);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, -1);
        F.add(i, i + n, INF, 0);
        int cnt1 = 0, cnt2 = 0;
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 && cnt1 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt1++;
            }
            if (a[i] % 7 == a[j] % 7 && cnt2 <= magic) {
                F.add(i + n, j, 1, 0);
                cnt2++;
            }
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#ifdef LOCAL
#define debug(x) cout<<#x<<" = "<<(x)<<endl;
#else
#define debug(x) 1;
#endif

#define chmax(x,y) x=max(x,y)
#define chmin(x,y) x=min(x,y)
#define lson id<<1,l,mid
#define rson id<<1|1,mid+1,r
#define lowbit(x) x&-x
#define mp make_pair
#define pb push_back
#define fir first
#define sec second
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;

const int MOD = 1e9 + 7;
const double PI = acos (-1.);
const double eps = 1e-10;
const int INF = 0x3f3f3f3f;
const ll INFll = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e6 + 5;

const int MX = 12345;
const int inf = 0x3f3f3f3f;
const int MXE = 1e7;
struct MinCost_MaxFlow {
    struct Edge {
        int v, w, nxt;
        int cost;
    } E[MXE];
    int head[MX], tot, level[MX], pre[MX], d[MX];
    bool vis[MX];
    void init() {
        memset(head, -1, sizeof(head));
        tot = 0;
    }
    void add(int u, int v, int w, int cost) {
        E[tot].v = v;
        E[tot].w = w;
        E[tot].cost = cost;
        E[tot].nxt = head[u];
        head[u] = tot++;
        E[tot].v = u;
        E[tot].w = 0;
        E[tot].cost = -cost;
        E[tot].nxt = head[v];
        head[v] = tot++;
    }
    bool spfa(int s, int t) {
        memset(vis, 0, sizeof(vis));
        memset(d, 0x3f, sizeof(d));
        memset(pre, -1, sizeof(pre));
        queue<int>q;
        q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while (!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for (int i = head[u]; ~i; i = E[i].nxt) {
                int w = E[i].w, v = E[i].v, cost = E[i].cost;
                if (w > 0 && d[v] > d[u] + cost) {
                    d[v] = d[u] + cost;
                    pre[v] = i;
                    if (!vis[v]) {
                        q.push(v);
                        vis[v] = 1;
                    }
                }
            }
        }
        //如果是最小费用可行流则要这一句(要求费用最小,不要求流量最大)
        //if (d[t] > 0) return false;
        return pre[t] != -1;
    }
    int solve(int s, int t, int &cost) {
        int flow = 0;
        cost = 0;
        while (spfa(s, t)) {
            int minFlow = inf;
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v])
                minFlow = min(minFlow, E[i].w);
            for (int i = pre[t]; ~i; i = pre[E[i ^ 1].v]) {
                cost += minFlow * E[i].cost;
                E[i].w -= minFlow;
                E[i ^ 1].w += minFlow;
            }
            flow += minFlow;
        }
        return flow;
    }
} F;

int a[MAXN];

int main() {
#ifdef LOCAL
    freopen ("input.txt", "r", stdin);
#endif
    int n;
    scanf ("%d", &n);
    F.init();
    for (int i = 1; i <= n; i++)
        scanf ("%d", &a[i]);
    int st = 0, en = 2 * n + 5;
    int add = en - 1;
    F.add(st, add, 4, 0);
    for (int i = 1; i <= n; i++) {
        F.add(add, i, 1, -1);
        F.add(i + n, en, 1, 0);
        F.add(i, i + n, 1, 0);
        for (int j = i + 1; j <= n; j++) {
            if (abs(a[i] - a[j]) == 1 || a[i] % 7 == a[j] % 7) F.add(i + n, j, 1, -1);
        }
    }
    int flow, cost;
    flow = F.solve(st, en, cost);
    printf ("%d\n", -cost);
    return 0;
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
using namespace std;
namespace mcmf{
    const int MAX = 12507;
    const long long INF = 1LL << 60;

    long long cap[MAX], flow[MAX], cost[MAX], dis[MAX];
    int n, m, s, t, Q[1000007], adj[MAX], link[MAX], last[MAX], from[MAX], visited[MAX];

    void init(int nodes, int source, int sink){
        m = 0, n = nodes, s = source, t = sink;
        for (int i = 0; i <= n; i++) last[i] = -1;
    }

    void addEdge(int u, int v, long long c, long long w){
        adj[m] = v, cap[m] = c, flow[m] = 0, cost[m] = +w, link[m] = last[u], last[u] = m++;
        adj[m] = u, cap[m] = 0, flow[m] = 0, cost[m] = -w, link[m] = last[v], last[v] = m++;
    }

    bool spfa(){
        int i, j, x, f = 0, l = 0;
        for (i = 0; i <= n; i++) visited[i] = 0, dis[i] = INF;

        dis[s] = 0, Q[l++] = s;
        while (f < l){
            i = Q[f++];
            for (j = last[i]; j != -1; j = link[j]){
                if (flow[j] < cap[j]){
                    x = adj[j];
                    if (dis[x] > dis[i] + cost[j]){
                        dis[x] = dis[i] + cost[j], from[x] = j;
                        if (!visited[x]){
                            visited[x] = 1;
                            if (f && rand() & 7) Q[--f] = x;
                            else Q[l++] = x;
                        }
                    }
                }
            }
            visited[i] = 0;
        }
        return (dis[t] != INF);
    }

    pair <long long, long long> solve(){
        int i, j;
        long long mincost = 0, maxflow = 0;

        while (maxflow<4 and spfa()){
            long long aug = INF;
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                aug = min(aug, cap[j] - flow[j]);
            }
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                flow[j] += aug, flow[j ^ 1] -= aug;
            }
            maxflow += aug, mincost += aug * dis[t];
        }
        return make_pair(mincost, maxflow);
    }
}

using namespace mcmf;

int arr[5007];
int next_same[100007], next_same_mod[10];

int main()
{
	int n;
	scanf("%d", &n);

 	int src= 4*n+2, sink= 4*n+3;
	init(4*n+7, src, sink);

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=100000;i++ )
		next_same[i]= sink;
	for( int i=0;i<7;i++ )
		next_same_mod[i]= sink;

	for( int i=1;i<=n;i++ )
	{
		int to= next_same_mod[arr[i]%7];
		addEdge( i+2*n, to, INF, 0 ); // skip the current node and go to a similar one
		addEdge( i+2*n, i, 1, 0 ); // take the current node
		addEdge( i+n, to, 1, 0 ); 	// can take the next node with same mod
		next_same_mod[arr[i]%7]= i+2*n;

		to= next_same[ arr[i] ];
		addEdge( i+3*n, to, INF, 0 ); // // skip the current node and go to a similar one
		addEdge( i+3*n, i, 1, 0 ); // take the current node
		addEdge( i+n, next_same[ arr[i]+1 ], 1, 0 ); // can take the next node with +1
		addEdge( i+n, next_same[ arr[i]-1 ], 1, 0 ); // can take the next node with -1
		next_same[arr[i]]= i+3*n;
	}

	for( int i=1;i<=n;i++ )
		addEdge( src, i, 1, 0 ),
		addEdge( i, i+n, 1, -1 ),
		addEdge( i+n, sink, 1, 0 );

	ll ans= solve().ff;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
using namespace std;
namespace mcmf{
    const int MAX = 20507;
    const long long INF = 1LL << 60;

    long long cap[MAX], flow[MAX], cost[MAX], dis[MAX];
    int n, m, s, t, Q[1000007], adj[MAX], link[MAX], last[MAX], from[MAX], visited[MAX];

    void init(int nodes, int source, int sink){
        m = 0, n = nodes, s = source, t = sink;
        for (int i = 0; i <= n; i++) last[i] = -1;
    }

    void addEdge(int u, int v, long long c, long long w){
        adj[m] = v, cap[m] = c, flow[m] = 0, cost[m] = +w, link[m] = last[u], last[u] = m++;
        adj[m] = u, cap[m] = 0, flow[m] = 0, cost[m] = -w, link[m] = last[v], last[v] = m++;
    }

    bool spfa(){
        int i, j, x, f = 0, l = 0;
        for (i = 0; i <= n; i++) visited[i] = 0, dis[i] = INF;

        dis[s] = 0, Q[l++] = s;
        while (f < l){
            i = Q[f++];
            for (j = last[i]; j != -1; j = link[j]){
                if (flow[j] < cap[j]){
                    x = adj[j];
                    if (dis[x] > dis[i] + cost[j]){
                        dis[x] = dis[i] + cost[j], from[x] = j;
                        if (!visited[x]){
                            visited[x] = 1;
                            if (f && rand() & 7) Q[--f] = x;
                            else Q[l++] = x;
                        }
                    }
                }
            }
            visited[i] = 0;
        }
        return (dis[t] != INF);
    }

    pair <long long, long long> solve(){
        int i, j;
        long long mincost = 0, maxflow = 0;

        while (maxflow<4 and spfa()){
            long long aug = INF;
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                aug = min(aug, cap[j] - flow[j]);
            }
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                flow[j] += aug, flow[j ^ 1] -= aug;
            }
            maxflow += aug, mincost += aug * dis[t];
        }
        return make_pair(mincost, maxflow);
    }
}

using namespace mcmf;

int arr[5007];
int next_same[100007], next_same_mod[10];

int main()
{
	int n;
	scanf("%d", &n);

 	int src= 4*n+2, sink= 4*n+3;
	init(4*n+7, src, sink);

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=100000;i++ )
		next_same[i]= sink;
	for( int i=0;i<7;i++ )
		next_same_mod[i]= sink;

	for( int i=1;i<=n;i++ )
	{
		int to= next_same_mod[arr[i]%7];
		addEdge( i+2*n, to, INF, 0 ); // skip the current node and go to a similar one
		addEdge( i+2*n, i, 1, 0 ); // take the current node
		addEdge( i+n, to, 1, 0 ); 	// can take the next node with same mod
		next_same_mod[arr[i]%7]= i+2*n;

		to= next_same[ arr[i] ];
		addEdge( i+3*n, to, INF, 0 ); // // skip the current node and go to a similar one
		addEdge( i+3*n, i, 1, 0 ); // take the current node
		addEdge( i+n, next_same[ arr[i]+1 ], 1, 0 ); // can take the next node with +1
		addEdge( i+n, next_same[ arr[i]-1 ], 1, 0 ); // can take the next node with -1
		next_same[arr[i]]= i+3*n;
	}

	for( int i=1;i<=n;i++ )
		addEdge( src, i, 1, 0 ),
		addEdge( i, i+n, 1, -1 ),
		addEdge( i+n, sink, 1, 0 );

	ll ans= solve().ff;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
#define MAX 3009
bool done[MAX];
int used[MAX];
typedef long long Tc;
typedef long long Tf;
using namespace std;

struct Edge {
	int from, to, next;
	Tf cap, flow;
	Tc cost;
	Edge(int from, int to, int next, Tf cap, Tc cost) {
		this->from = from;
		this->to = to;
		this->next = next;
		this->cap = cap;
		this->cost = cost;
		this->flow = 0;
	}
};

struct MCMF {
	typedef pair <Tc, int> Pti;
	Tf infF=(numeric_limits<Tf>::max() / 4);
	Tc infC=(numeric_limits<Tc>::max() / 4);
	int n;
	int S, T, ne[MAX];
	Tc d[MAX], pi[MAX];
	vector < Edge > E;

	void init(int _n) {
		n=_n;
		memset(ne, -1, n * sizeof(int));
		fill(pi, pi+n, 0);
		E.clear();
	}
	void addEdge(int u, int v, Tf cap = 1, Tc cost = 0) {
		E.push_back(Edge(u, v, ne[u], cap, cost));
		ne[u] = (int)E.size()-1;
		E.push_back(Edge(v, u, ne[v], 0, -cost));
		ne[v] = (int)E.size()-1;
	}

	// dijkstra
	bool dijkstra() {
		memset(used, -1, n*sizeof(int));
		memset(done, 0, n*sizeof(bool));
		fill(d, d+n, infC);
		priority_queue < Pti, vector <Pti>, greater <Pti> > q;
		q.push(make_pair(0, S));
		d[S] = 0;

		while(!q.empty()) {
			int u = q.top().second, v;
			q.pop();
			if(done[u]) continue;
			done[u] = true;

			for(int i = ne[u]; i != -1; i = E[i].next) {
				v = E[i].to;
				Tc pot = d[u] + pi[u] - pi[v];
				if(E[i].cap > E[i].flow && pot + E[i].cost < d[v]) {
					d[v] = pot + E[i].cost;
					used[v] = i;
					q.push(make_pair(d[v], v));
				}
			}
		}
		for(int i = 0; i < n; i++) pi[i] = min(pi[i] + d[i], infC);

		return d[T] != infC;
	}

	// bellmanford
	bool bellmanford() {
		memset(used, -1, n*sizeof(int));
		memset(done, 0, n*sizeof(bool));
		fill(d, d+n, infC);
		queue<int> q;
		q.push(S);
		d[S] = 0;

		while(!q.empty()) {
			int u = q.front(), v;
			q.pop();
			done[u] = 0;

			for(int i = ne[u]; i != -1; i = E[i].next) {
				v = E[i].to;
				Tc pot = d[u] + pi[u] - pi[v];
				if(E[i].cap > E[i].flow && pot + E[i].cost < d[v]) {
					d[v] = pot + E[i].cost;
					used[v] = i;
					if(done[v]==0) {
						q.push(v);
						done[v]=1;
					}
				}
			}
		}
		for(int i = 0; i < n; i++) pi[i] = min(pi[i] + d[i], infC);

		return d[T] != infC;
	}

	pair <Tf, Tc> maxFlow(int src, int snk, ll goal= 1e17) {
		S = src, T = snk;
		Tf flow = 0;
		Tc cost = 0;

		while( flow<goal and bellmanford()) {
			// get blocking flow
			snk = T;
			Tf bflow = infF;
			while(snk != S) {
				bflow = min(bflow, E[ used[snk] ].cap - E[ used[snk] ].flow);
				snk = E[ used[snk] ].from;
			}
			// augment path
			snk = T;
			while(snk != S) {
				E[ used[snk] ].flow += bflow;
				E[ used[snk] ^ 1 ].flow -= bflow;
				cost += E[ used[snk] ].cost * bflow;
				snk = E[ used[snk] ].from;
			}
			flow += bflow;
		}
		return make_pair(flow, cost);
	}
};
int arr[5007];

int main()
{
	int n;
	scanf("%d", &n);

	MCMF flow;
	flow.init(2*n+7);
	int src= 2*n+2, sink= 2*n+3;

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=n;i++ )
		for( int j=i+1;j<=n;j++ )
			if( arr[j]-arr[i]==1 )
			{
				flow.addEdge( i+n, j, 1, 0 );
				break;
			}

	for( int i=1;i<=n;i++ )
		for( int j=i+1;j<=n;j++ )
			if( arr[i]-arr[j]==1 )
			{
				flow.addEdge( i+n, j, 1, 0 );
				break;
			}

	for( int i=1;i<=n;i++ )
		for( int j=i+1;j<=n;j++ )
			if( arr[j]%7==arr[i]%7 )
			{
				flow.addEdge( i+n, j, 1, 0 );
				break;
			}

	for( int i=1;i<=n;i++ )
		flow.addEdge( src, i, 1, 0 ),
		flow.addEdge( i, i+n, 1, -1 ),
		flow.addEdge( i+n, sink, 1, 0 );

	ll ans= flow.maxFlow(src,sink,4).ss;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
using namespace std;
namespace mcmf{
    const int MAX = 70507;
    const long long INF = 1LL << 60;

    long long cap[MAX], flow[MAX], cost[MAX], dis[MAX];
    int n, m, s, t, Q[1000007], adj[MAX], link[MAX], last[MAX], from[MAX], visited[MAX];

    void init(int nodes, int source, int sink){
        m = 0, n = nodes, s = source, t = sink;
        for (int i = 0; i <= n; i++) last[i] = -1;
    }

    void addEdge(int u, int v, long long c, long long w){
        adj[m] = v, cap[m] = c, flow[m] = 0, cost[m] = +w, link[m] = last[u], last[u] = m++;
        adj[m] = u, cap[m] = 0, flow[m] = 0, cost[m] = -w, link[m] = last[v], last[v] = m++;
    }

    bool spfa(){
        int i, j, x, f = 0, l = 0;
        for (i = 0; i <= n; i++) visited[i] = 0, dis[i] = INF;

        dis[s] = 0, Q[l++] = s;
        while (f < l){
            i = Q[f++];
            for (j = last[i]; j != -1; j = link[j]){
                if (flow[j] < cap[j]){
                    x = adj[j];
                    if (dis[x] > dis[i] + cost[j]){
                        dis[x] = dis[i] + cost[j], from[x] = j;
                        if (!visited[x]){
                            visited[x] = 1;
                            if (f && rand() & 7) Q[--f] = x;
                            else Q[l++] = x;
                        }
                    }
                }
            }
            visited[i] = 0;
        }
        return (dis[t] != INF);
    }

    pair <long long, long long> solve(){
        int i, j;
        long long mincost = 0, maxflow = 0;

        while (maxflow<4 and spfa()){
            long long aug = INF;
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                aug = min(aug, cap[j] - flow[j]);
            }
            for (i = t, j = from[i]; i != s; i = adj[j ^ 1], j = from[i]){
                flow[j] += aug, flow[j ^ 1] -= aug;
            }
            maxflow += aug, mincost += aug * dis[t];
        }
        return make_pair(mincost, maxflow);
    }
}

using namespace mcmf;

int arr[5007];
int next_same[100007], next_same_mod[10];

int main()
{
	int n;
	scanf("%d", &n);

 	int src= 4*n+2, sink= 4*n+3;
	init(4*n+7, src, sink);

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=100000;i++ )
		next_same[i]= sink;
	for( int i=0;i<7;i++ )
		next_same_mod[i]= sink;

	for( int i=1;i<=n;i++ )
	{
		int to= next_same_mod[arr[i]%7];
		addEdge( i+2*n, to, INF, 0 ); // skip the current node and go to a similar one
		addEdge( i+2*n, i, 1, 0 ); // take the current node
		addEdge( i+n, to, 1, 0 ); 	// can take the next node with same mod
		next_same_mod[arr[i]%7]= i+2*n;

		to= next_same[ arr[i] ];
		addEdge( i+3*n, to, INF, 0 ); // // skip the current node and go to a similar one
		addEdge( i+3*n, i, 1, 0 ); // take the current node
		addEdge( i+n, next_same[ arr[i]+1 ], 1, 0 ); // can take the next node with +1
		addEdge( i+n, next_same[ arr[i]-1 ], 1, 0 ); // can take the next node with -1
		next_same[arr[i]]= i+3*n;
	}

	for( int i=1;i<=n;i++ )
		addEdge( src, i, 1, 0 ),
		addEdge( i, i+n, 1, -1 ),
		addEdge( i+n, sink, 1, 0 );

	ll ans= solve().ff;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
#define N 12007
using namespace std;

struct MCMF {
    using T = ll; static const T inf = 1e9 + 7;
    int n, m, s, t; bool vis[N];
    ll par[N], pos[N]; T pot[N], dis[N], left[N];
    priority_queue <pair <T, int>> q;
    struct edge {
        int to, rev; T cap, cost, flow; int id;
    };
    vector<edge>ed[N];
    MCMF() {}
    MCMF(int _n) {
        n = _n + 2;
        for (int i = 1; i <= n; i++) ed[i].clear();
    }
    void add_edge(int u, int v, T cap, T cost, int id = -1) {
        edge a = {v, (int)ed[v].size(), cap, cost, 0, id};
        edge b = {u, (int)ed[u].size(), 0, -cost, 0, -1};
        ed[u].push_back(a); ed[v].push_back(b);
    }
    T BellmanFord(int u) {
        if (vis[u]) return pot[u];
        if (u == s) {
            pot[s] = 0;
            return 0;
        }
        vis[u] = true; pot[u] = inf;
        for (edge e : ed[u]) {
            edge r = ed[e.to][e.rev];
            if (r.flow < r.cap) pot[u] = min(pot[u], BellmanFord(e.to) + r.cost);
        }
        return pot[u];
    }
    bool dijkstra() {
        memset(vis, 0, sizeof vis);
        for (int i = 1; i <= n; i++) dis[i] = left[i] = inf;
        dis[s] = 0; q.push({0, s}); int u, v;
        while (!q.empty()) {
            u = q.top().second; q.pop();
            if (vis[u]) continue;
            vis[u] = true; int ptr = 0;
            for(edge e : ed[u]) {
                v = e.to; T cost = e.cost + pot[u] - pot[v];
                if (e.flow < e.cap && dis[u] + cost < dis[v]) {
                    dis[v] = dis[u] + cost;
                    par[v] = u; pos[v] = ptr;
                    left[v] = min(left[u], e.cap - e.flow);
                    q.push(make_pair(-dis[v], v));
                }
                ++ptr;
            }
        }
        for (int i = 1; i <= n; i++) dis[i] += (pot[i] - pot[s]);
        return vis[t];
    }
    pair<T, T> solve(int _s, int _t, T goal = inf) {
        s = _s; t = _t;
        memset(pot, 0, sizeof pot);
        memset(vis, 0, sizeof vis);
        BellmanFord(t);
        int u, v; T ans = 0, cost = 0, f;
        while (ans < goal && dijkstra()) {
            u = t; f = left[t];
            while (u != s) {
                v = par[u];
                ed[v][pos[u]].flow += left[t];
                ed[u][ed[v][pos[u]].rev].flow -= left[t];
                u = v;
            }
            T need = goal - ans; f = min(f, need);
            ans += f; cost += f * dis[t];
            memcpy(pot, dis, sizeof dis);
        }
        return make_pair(ans, cost);
    }
};

int arr[5007];
int next_same[100007], next_same_mod[10];

int main()
{
	int n;
	scanf("%d", &n);

	MCMF flow(4*n+7);
	int src= 4*n+2, sink= 4*n+3;

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=100000;i++ )
		next_same[i]= sink;
	for( int i=0;i<7;i++ )
		next_same_mod[i]= sink;

	for( int i=1;i<=n;i++ )
	{
		int to= next_same_mod[arr[i]%7];
		flow.add_edge( i+2*n, to, flow.inf, 0 ); // skip the current node and go to a similar one
		flow.add_edge( i+2*n, i, 1, 0 ); // take the current node
		flow.add_edge( i+n, to, 1, 0 ); 	// can take the next node with same mod
		next_same_mod[arr[i]%7]= i+2*n;

		to= next_same[ arr[i] ];
		flow.add_edge( i+3*n, to, flow.inf, 0 ); // // skip the current node and go to a similar one
		flow.add_edge( i+3*n, i, 1, 0 ); // take the current node
		flow.add_edge( i+n, next_same[ arr[i]+1 ], 1, 0 ); // can take the next node with +1
		flow.add_edge( i+n, next_same[ arr[i]-1 ], 1, 0 ); // can take the next node with -1
		next_same[arr[i]]= i+3*n;
	}

	for( int i=1;i<=n;i++ )
		flow.add_edge( src, i, 1, 0 ),
		flow.add_edge( i, i+n, 1, -1 ),
		flow.add_edge( i+n, sink, 1, 0 );

	ll ans= flow.solve(src,sink,4).ss;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
#define N 6507
using namespace std;

struct MCMF {
    using T = ll; static const T inf = 1e9 + 7;
    int n, m, s, t; bool vis[N];
    ll par[N], pos[N]; T pot[N], dis[N], left[N];
    priority_queue <pair <T, int>> q;
    struct edge {
        int to, rev; T cap, cost, flow; int id;
    };
    vector<edge>ed[N];
    MCMF() {}
    MCMF(int _n) {
        n = _n + 2;
        for (int i = 1; i <= n; i++) ed[i].clear();
    }
    void add_edge(int u, int v, T cap, T cost, int id = -1) {
        edge a = {v, (int)ed[v].size(), cap, cost, 0, id};
        edge b = {u, (int)ed[u].size(), 0, -cost, 0, -1};
        ed[u].push_back(a); ed[v].push_back(b);
    }
    T BellmanFord(int u) {
        if (vis[u]) return pot[u];
        if (u == s) {
            pot[s] = 0;
            return 0;
        }
        vis[u] = true; pot[u] = inf;
        for (edge e : ed[u]) {
            edge r = ed[e.to][e.rev];
            if (r.flow < r.cap) pot[u] = min(pot[u], BellmanFord(e.to) + r.cost);
        }
        return pot[u];
    }
    bool dijkstra() {
        memset(vis, 0, sizeof vis);
        for (int i = 1; i <= n; i++) dis[i] = left[i] = inf;
        dis[s] = 0; q.push({0, s}); int u, v;
        while (!q.empty()) {
            u = q.top().second; q.pop();
            if (vis[u]) continue;
            vis[u] = true; int ptr = 0;
            for(edge e : ed[u]) {
                v = e.to; T cost = e.cost + pot[u] - pot[v];
                if (e.flow < e.cap && dis[u] + cost < dis[v]) {
                    dis[v] = dis[u] + cost;
                    par[v] = u; pos[v] = ptr;
                    left[v] = min(left[u], e.cap - e.flow);
                    q.push(make_pair(-dis[v], v));
                }
                ++ptr;
            }
        }
        for (int i = 1; i <= n; i++) dis[i] += (pot[i] - pot[s]);
        return vis[t];
    }
    pair<T, T> solve(int _s, int _t, T goal = inf) {
        s = _s; t = _t;
        memset(pot, 0, sizeof pot);
        memset(vis, 0, sizeof vis);
        BellmanFord(t);
        int u, v; T ans = 0, cost = 0, f;
        while (ans < goal && dijkstra()) {
            u = t; f = left[t];
            while (u != s) {
                v = par[u];
                ed[v][pos[u]].flow += left[t];
                ed[u][ed[v][pos[u]].rev].flow -= left[t];
                u = v;
            }
            T need = goal - ans; f = min(f, need);
            ans += f; cost += f * dis[t];
            memcpy(pot, dis, sizeof dis);
        }
        return make_pair(ans, cost);
    }
};

int arr[5007];

int main()
{
	int n;
	scanf("%d", &n);

	MCMF flow(2*n+7);
	int src= 2*n+2, sink= 2*n+3;

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=n;i++ )
		for( int j=i+1;j<=n;j++ )
			if( abs(arr[j]-arr[i])==1 or arr[i]%7==arr[j]%7 )
				flow.add_edge( i+n, j, 1, 0 );

	for( int i=1;i<=n;i++ )
		flow.add_edge( src, i, 1, 0 ),
		flow.add_edge( i, i+n, 1, -1 ),
		flow.add_edge( i+n, sink, 1, 0 );

	ll ans= flow.solve(src,sink,4).ss;

	printf("%lld\n", abs(ans));
}


#include <bits/stdc++.h>
#define ll long long
#define pll pair<ll,ll>
#define pii pair<int,int>
#define ff first
#define ss second
#define N 12507
using namespace std;

struct MCMF {
    using T = ll; static const T inf = 1e9 + 7;
    int n, m, s, t; bool vis[N];
    ll par[N], pos[N]; T pot[N], dis[N], left[N];
    priority_queue <pair <T, int>> q;
    struct edge {
        int to, rev; T cap, cost, flow; int id;
    };
    vector<edge>ed[N];
    MCMF() {}
    MCMF(int _n) {
        n = _n + 2;
        for (int i = 1; i <= n; i++) ed[i].clear();
    }
    void add_edge(int u, int v, T cap, T cost, int id = -1) {
        edge a = {v, (int)ed[v].size(), cap, cost, 0, id};
        edge b = {u, (int)ed[u].size(), 0, -cost, 0, -1};
        ed[u].push_back(a); ed[v].push_back(b);
    }
    T BellmanFord(int u) {
        if (vis[u]) return pot[u];
        if (u == s) {
            pot[s] = 0;
            return 0;
        }
        vis[u] = true; pot[u] = inf;
        for (edge e : ed[u]) {
            edge r = ed[e.to][e.rev];
            if (r.flow < r.cap) pot[u] = min(pot[u], BellmanFord(e.to) + r.cost);
        }
        return pot[u];
    }
    bool dijkstra() {
        memset(vis, 0, sizeof vis);
        for (int i = 1; i <= n; i++) dis[i] = left[i] = inf;
        dis[s] = 0; q.push({0, s}); int u, v;
        while (!q.empty()) {
            u = q.top().second; q.pop();
            if (vis[u]) continue;
            vis[u] = true; int ptr = 0;
            for(edge e : ed[u]) {
                v = e.to; T cost = e.cost + pot[u] - pot[v];
                if (e.flow < e.cap && dis[u] + cost < dis[v]) {
                    dis[v] = dis[u] + cost;
                    par[v] = u; pos[v] = ptr;
                    left[v] = min(left[u], e.cap - e.flow);
                    q.push(make_pair(-dis[v], v));
                }
                ++ptr;
            }
        }
        for (int i = 1; i <= n; i++) dis[i] += (pot[i] - pot[s]);
        return vis[t];
    }
    pair<T, T> solve(int _s, int _t, T goal = inf) {
        s = _s; t = _t;
        memset(pot, 0, sizeof pot);
        memset(vis, 0, sizeof vis);
        BellmanFord(t);
        int u, v; T ans = 0, cost = 0, f;
        while (ans < goal && dijkstra()) {
            u = t; f = left[t];
            while (u != s) {
                v = par[u];
                ed[v][pos[u]].flow += left[t];
                ed[u][ed[v][pos[u]].rev].flow -= left[t];
                u = v;
            }
            T need = goal - ans; f = min(f, need);
            ans += f; cost += f * dis[t];
            memcpy(pot, dis, sizeof dis);
        }
        return make_pair(ans, cost);
    }
};

int arr[5007];
int next_same[100007], next_same_mod[10];

int main()
{
	int n;
	scanf("%d", &n);

	MCMF flow(4*n+7);
	int src= 4*n+2, sink= 4*n+3;

	for( int i=1;i<=n;i++ )
		scanf("%d", &arr[i]);

	for( int i=1;i<=100000;i++ )
		next_same[i]= sink;
	for( int i=0;i<7;i++ )
		next_same_mod[i]= sink;

	for( int i=1;i<=n;i++ )
	{
		int to= next_same_mod[arr[i]%7];
		flow.add_edge( i+2*n, to, flow.inf, 0 ); // skip the current node and go to a similar one
		flow.add_edge( i+2*n, i, 1, 0 ); // take the current node
		flow.add_edge( i+n, to, 1, 0 ); 	// can take the next node with same mod
		next_same_mod[arr[i]%7]= i+2*n;

		to= next_same[ arr[i] ];
		flow.add_edge( i+3*n, to, flow.inf, 0 ); // // skip the current node and go to a similar one
		flow.add_edge( i+3*n, i, 1, 0 ); // take the current node
		flow.add_edge( i+n, next_same[ arr[i]+1 ], 1, 0 ); // can take the next node with +1
		flow.add_edge( i+n, next_same[ arr[i]-1 ], 1, 0 ); // can take the next node with -1
		next_same[arr[i]]= i+3*n;
	}

	for( int i=1;i<=n;i++ )
		flow.add_edge( src, i, 1, 0 ),
		flow.add_edge( i, i+n, 1, -1 ),
		flow.add_edge( i+n, sink, 1, 0 );

	ll ans= flow.solve(src,sink,4).ss;

	printf("%lld\n", abs(ans));
}