#include<bits/stdc++.h>
#define inf 100000
using namespace std;
struct edge
{
    int to,cap,flow,cost,index;
    edge(int to,int cap,int flow,int cost,int index):
    to(to),cap(cap),flow(flow),cost(cost),index(index)
    {

    }
};
struct minimumcostflow
{
    int n;
    vector<vector<edge>>g;
    vector<int>potential,prio,curflow,prevnode,prevedge;
    vector<bool>inqueue;
    minimumcostflow(int n):
    n(n),g(n),potential(n),prio(n),curflow(n),prevnode(n),prevedge(n),inqueue(n,false)
    {

    }
    void addedge(int from,int to,int cap,int cost)
    {
        g[from].push_back(edge(to,cap,0,cost,g[to].size()));
        g[to].push_back(edge(from,0,0,-cost,g[from].size()-1));
    }
    void bellmanford(int src,vector<int> &dist)
    {
        fill(dist.begin(),dist.end(),inf);
        dist[src]=0;
        inqueue[src]=true;
        queue<int>q;
        q.push(src);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inqueue[u]=false;
            for(int i=0;i<g[u].size();i++)
            {
                edge &e=g[u][i];
                if(e.flow==e.cap)
                continue;
                int v=e.to;
                int newdist=dist[u]+e.cost;
                if(newdist<dist[v])
                {
                    dist[v]=newdist;
                    if(!inqueue[v])
                    {
                        inqueue[v]=true;
                        q.push(v);
                    }
                }
            }
        }
    }
    pair<int,int> mincostmaxflow(int src,int snk)
    {
        bellmanford(src,potential);
        int flow=0,flowcost=0;
        while(true)
        {
            priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
            fill(prio.begin(),prio.end(),inf);
            prio[src]=0;
            q.push({
                0,src
            });
            curflow[src]=inf;
            while(!q.empty())
            {
                int d=q.top().first;
                int u=q.top().second;
                q.pop();
                if(d!=prio[u])
                continue;
                for(int i=0;i<g[u].size();i++)
                {
                    edge &e=g[u][i];
                    if(e.cap==e.flow)
                    continue;
                    int v=e.to;
                    int newdist=prio[u]+potential[u]-potential[v]+e.cost;
                    if(prio[v]>newdist)
                    {
                        prio[v]=newdist;
                        q.push({
                            newdist,v
                        });
                        prevnode[v]=u;
                        prevedge[v]=i;
                        curflow[v]=min(curflow[u],e.cap-e.flow);
                    }
                }
            }
            if(prio[snk]==inf)
            break;
            int temp=curflow[snk];
            flow += temp;
            for(int i=0;i<n;i++)
            potential[i] += prio[i];
            for(int i=snk;i!=src;i=prevnode[i])
            {
                edge &e=g[prevnode[i]][prevedge[i]];
                e.flow += temp;
                g[e.to][e.index].flow -= temp;
                flowcost += temp*e.cost;
            }
        }
        return {
            flow,flowcost
        };
    }
};
int n,a[3003];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<+n;i++)
    scanf("%d",&a[i]);
    minimumcostflow mcmf(2*n + 3);
    mcmf.addedge(0,2*n + 1,4,0);
    for(int i=1;i<=n;i++)
    {
        mcmf.addedge(i,i+n,1,-1);
        mcmf.addedge(i+n,2*n + 2,1,0);
        mcmf.addedge(2*n + 1,i,1,0);
        for(int j=i+1;j<=n;j++)
        {
            if((a[i]%7 == a[j]%7) || abs(a[i]-a[j])==1)
            mcmf.addedge(i+n,j,1,0);
        }
    }
    printf("%d\n",-mcmf.mincostmaxflow(0,2*n + 2).second);
    return 0;
}


/* Cf: Akigeor */

#include <bits/stdc++.h>
using namespace std;
const int INF= 1e9;
const int N = 6e3 + 100;
struct edge { int f, c, to, r;};
vector<edge> G[N];
int S, T, cur[N], vst[N];
int d[N];
bool fst = false;
bool SPFA(int S) {
	if (fst) {
		d[S] = 0;
		for (int i = 1; i <= T; ++ i) {
			d[i] = INF;
			for (edge e : G[i]) {
				if (!e.f) {
					if (d[e.to] - e.c < d[i]) {
						d[i] = d[e.to] - e.c;
					}
				}
			}
			//printf("d[%d]=%d---\n", i, d[i]);
		}
		fst = 0;
		return d[T] != INF;
	} else {
		fill(d, d + 1 + T, INF);
		queue<int> pq;
		d[S] = 0;
        for(int i=0; i<= T; ++i){
            pq.push(i);
        }
		while (1) {
			if (pq.empty()) break;
			int v = pq.front(); pq.pop();
			for (edge e : G[v]) {
				if (e.f && d[e.to] > d[v] + e.c) {
					d[e.to] = d[v] + e.c;
					pq.push(e.to);
				}
			}
		}
		return d[T] != INF;
	}
}
int aug(int v, int flow) {
	if (v == T) return flow;
	vst[v] = 1; int flow1 = flow;
	for (int &i = cur[v]; i < (int) G[v].size(); ++ i) {
		edge &e = G[v][i];
		if (e.f && d[v] + e.c == d[e.to] && !vst[e.to]) {
			int flow1 = aug(e.to, min(flow, e.f));
			flow -= flow1; e.f -= flow1;
			G[e.to][e.r].f += flow1;
		}
		if (flow == 0) {
			vst[v] = 0; return flow1 - flow;
		}
	}
	return flow1 - flow;
}
int mcmf() {
	int ans = 0, sT = 0;
	while (SPFA(S)) {
		sT += d[T];
		for (int i = 0; i <= T; ++ i) cur[i] = 0, vst[i] = 0;
		ans += sT * aug(S, INF);
		/*int f = INF;
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			printf("%d\n", v);
			f = min(f, G[u][j].f);
		}
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			G[u][j].f -= f;
			G[v][G[u][j].r].f += f;
		}
		sT += d[T];
		printf("f=%d  d[T]=%d\n", f, d[T]);
		ans += f * sT;*/
		for (int i = 0; i <= T; ++ i) {
			for (auto &e : G[i]) {
				e.c += d[i] - d[e.to];
			}
		}
	}
	return ans;
}
void ae(int u, int v, int f, int c) {
	G[u].push_back((edge) {f, c, v, (int) G[v].size()});
	G[v].push_back((edge) {0, -c, u, (int) G[u].size() - 1});
}
int a[N];
int main() {
    //freopen("input.txt", "r", stdin);
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
	S = 0, T = 2 * n + 2;
	int SS = 1;
	ae(S, SS, 4, 0);
	for (int i = 1; i <= n; ++ i) ae(2 * i, 2 * i + 1, 1, -1);
	for (int i = 1; i <= n; ++ i) {
		ae(SS, 2 * i, 1, 0);
		ae(2 * i + 1, T, 1, 0);
		int cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] % 7 == a[i] % 7) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] + 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] - 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
	}
	int ans = mcmf();
	printf("%d\n", -ans);
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define MAX 200010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))

using namespace std;

namespace mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    struct compare{
        inline bool operator()(int a, int b){
            if (dis[a] == dis[b]) return (a < b);
            return (dis[a] < dis[b]);
        }
    };
    set<int, compare> S;

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

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

    pair<int, int> solve(){
        int i, j, e, u, v;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            queue<int> Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push(s);
            while (!Q.empty()){
                u = Q.front();
                Q.pop();

                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push(v);
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
}

int n, ar[5010];
char counter[100010];

inline int get_in(int x){
    return 2 * x;
}

inline int get_out(int x){
    return 2 * x + 1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    int i, j, k, l, x, w, s, t;

    while (scanf("%d", &n) != EOF){
        for (i = 0; i < n; i++) scanf("%d", &ar[i]);
        //n = 3000;
        //for (i = 0; i < n; i++) ar[i] = rand() % 7 + 1;

        s = n * 2, t = s + 1, w = t + 1;
        mcmf::init(n * 2 + 3, s, t);

        mcmf::addEdge(s, w, 4, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_in(i), get_out(i), 1, -1);
        for (i = 0; i < n; i++) mcmf::addEdge(w, get_in(i), 1, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_out(i), t, 1, 0);

        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (abs(ar[j] - ar[i]) == 1){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        for (i = 0; i < n; i++) ar[i] %= 7;
        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (ar[i] == ar[j]){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        pair <int, int> res = mcmf::solve();
        printf("%d\n", -res.first);
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define MAX 200010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))

using namespace std;

namespace mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    struct compare{
        inline bool operator()(int a, int b){
            if (dis[a] == dis[b]) return (a < b);
            return (dis[a] < dis[b]);
        }
    };
    set<int, compare> S;

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

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

    pair<int, int> solve(){
        int i, j, e, u, v, c;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            typedef pair<int, int> pii;
            priority_queue<pii, vector<pii>, greater<pii> > Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push({dis[s], s});
            while (!Q.empty()){
                c=Q.top().first, u = Q.top().second;
                Q.pop();
                if(c>dis[u]) continue;
                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push({dis[v], v});
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
}

int n, ar[5010];
char counter[100010];

inline int get_in(int x){
    return 2 * x;
}

inline int get_out(int x){
    return 2 * x + 1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    int i, j, k, l, x, w, s, t;

    while (scanf("%d", &n) != EOF){
        for (i = 0; i < n; i++) scanf("%d", &ar[i]);
        //n = 3000;
        //for (i = 0; i < n; i++) ar[i] = rand() % 7 + 1;

        s = n * 2, t = s + 1, w = t + 1;
        mcmf::init(n * 2 + 3, s, t);

        mcmf::addEdge(s, w, 4, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_in(i), get_out(i), 1, -1);
        for (i = 0; i < n; i++) mcmf::addEdge(w, get_in(i), 1, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_out(i), t, 1, 0);

        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (abs(ar[j] - ar[i]) == 1){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        for (i = 0; i < n; i++) ar[i] %= 7;
        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (ar[i] == ar[j]){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        pair <int, int> res = mcmf::solve();
        printf("%d\n", -res.first);
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define MAX 200010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))

using namespace std;

namespace mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    struct compare{
        inline bool operator()(int a, int b){
            if (dis[a] == dis[b]) return (a < b);
            return (dis[a] < dis[b]);
        }
    };
    set<int, compare> S;

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

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

    pair<int, int> solve(){
        int i, j, e, u, v;
        int w, aug = 0, mincost = 0, maxflow = 0;

//        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;
//
//        for (u = 0; u < n; u++){
//            for (e = last[u]; e != -1; e = next[e]){
//                v = adj[e];
//                if (cap[e] == 0){
//                    potential[v] = min(potential[v], potential[u] + cost[e]);
//                }
//            }
//        }

        while (1){
            queue<int> Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push(s);
            while (!Q.empty()){
                u = Q.front();
                if (u == t) break;
                Q.pop();

                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push(v);
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            //for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
}

int n, ar[5010];
char counter[100010];

inline int get_in(int x){
    return 2 * x;
}

inline int get_out(int x){
    return 2 * x + 1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    int i, j, k, l, x, w, s, t;

    while (scanf("%d", &n) != EOF){
        for (i = 0; i < n; i++) scanf("%d", &ar[i]);
        //n = 3000;
        //for (i = 0; i < n; i++) ar[i] = rand() % 7 + 1;

        s = n * 2, t = s + 1, w = t + 1;
        mcmf::init(n * 2 + 3, s, t);

        mcmf::addEdge(s, w, 4, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_in(i), get_out(i), 1, -1);
        for (i = 0; i < n; i++) mcmf::addEdge(w, get_in(i), 1, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_out(i), t, 1, 0);

        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (abs(ar[j] - ar[i]) == 1){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        for (i = 0; i < n; i++) ar[i] %= 7;
        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (ar[i] == ar[j]){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        pair <int, int> res = mcmf::solve();
        printf("%d\n", -res.first);
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define MOD 1000000007
#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

struct _mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

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

    void add_edge(int u, int v, int w, int c){
        from[m] = u, adj[m] = v, cap[m] = c, cost[m] = w, next[m] = last[u], last[u] = m++;
        from[m] = v, adj[m] = u, cap[m] = 0, cost[m] = -w, next[m] = last[v], last[v] = m++;
    }

    pair<int, int> solve(){
        int i, j, e, u, v, c;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            typedef pair<int, int> pii;
            priority_queue<pii, vector<pii>, greater<pii> > Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push({dis[s], s});
            while (!Q.empty()){
                c=Q.top().first, u = Q.top().second;
                Q.pop();
                if(c>dis[u]) continue;
                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push({dis[v], v});
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        int INF=1000000000;
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.init(4*n+4, 2*src+1, 2*sink+2);
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.solve();

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


/* Cf: Akigeor */

#include <bits/stdc++.h>
using namespace std;
const int INF= 1e9;
const int N = 6e3 + 100;
struct edge { int f, c, to, r;};
vector<edge> G[N];
int S, T, cur[N], vst[N];
int d[N];
bool fst = false;
bool SPFA(int S) {
	if (fst) {
		d[S] = 0;
		for (int i = 1; i <= T; ++ i) {
			d[i] = INF;
			for (edge e : G[i]) {
				if (!e.f) {
					if (d[e.to] - e.c < d[i]) {
						d[i] = d[e.to] - e.c;
					}
				}
			}
			//printf("d[%d]=%d---\n", i, d[i]);
		}
		fst = 0;
		return d[T] != INF;
	} else {
		fill(d, d + 1 + T, INF);
		queue<int> pq;
		pq.push(S);
		d[S] = 0;
		while (1) {
			if (pq.empty()) break;
			int v = pq.front(); pq.pop();
			for (edge e : G[v]) {
				if (e.f && d[e.to] > d[v] + e.c) {
					d[e.to] = d[v] + e.c;
					pq.push(e.to);
				}
			}
		}
		return d[T] != INF;
	}
}
int aug(int v, int flow) {
	if (v == T) return flow;
	vst[v] = 1; int flow1 = flow;
	for (int &i = cur[v]; i < (int) G[v].size(); ++ i) {
		edge &e = G[v][i];
		if (e.f && d[v] + e.c == d[e.to] && !vst[e.to]) {
			int flow1 = aug(e.to, min(flow, e.f));
			flow -= flow1; e.f -= flow1;
			G[e.to][e.r].f += flow1;
		}
		if (flow == 0) {
			vst[v] = 0; return flow1 - flow;
		}
	}
	return flow1 - flow;
}
int mcmf() {
	int ans = 0, sT = 0;
	while (SPFA(S)) {
		sT += d[T];
		for (int i = 0; i <= T; ++ i) cur[i] = 0, vst[i] = 0;
		ans += sT * aug(S, INF);
		/*int f = INF;
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			printf("%d\n", v);
			f = min(f, G[u][j].f);
		}
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			G[u][j].f -= f;
			G[v][G[u][j].r].f += f;
		}
		sT += d[T];
		printf("f=%d  d[T]=%d\n", f, d[T]);
		ans += f * sT;*/
		for (int i = 0; i <= T; ++ i) {
			for (auto &e : G[i]) {
				e.c += d[i] - d[e.to];
			}
		}
	}
	return ans;
}
void ae(int u, int v, int f, int c) {
	G[u].push_back((edge) {f, c, v, (int) G[v].size()});
	G[v].push_back((edge) {0, -c, u, (int) G[u].size() - 1});
}
int a[N];
int main() {
    //freopen("input.txt", "r", stdin);
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
	S = 0, T = 2 * n + 2;
	int SS = 1;
	ae(S, SS, 4, 0);
	for (int i = 1; i <= n; ++ i) ae(2 * i, 2 * i + 1, 1, -1);
	for (int i = 1; i <= n; ++ i) {
		ae(SS, 2 * i, 1, 0);
		ae(2 * i + 1, T, 1, 0);
		int cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] % 7 == a[i] % 7) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] + 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] - 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
	}
	int ans = mcmf();
	printf("%d\n", -ans);
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define MAX 200010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))

using namespace std;

namespace mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    struct compare{
        inline bool operator()(int a, int b){
            if (dis[a] == dis[b]) return (a < b);
            return (dis[a] < dis[b]);
        }
    };
    set<int, compare> S;

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

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

    pair<int, int> solve(){
        int i, j, e, u, v;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                if (cap[e] != 0){
                    potential[v] = min(potential[v], potential[u] + cost[e]);
                }
            }
        }

        while (1){
            S.clear();
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0, S.insert(s);
            while (!S.empty()){
                u = *(S.begin());
                if (u == t) break;
                S.erase(S.begin());

                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            S.erase(v);
                            dis[v] = w, to[v] = e;
                            S.insert(v);
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
}

int n, ar[5010];
char counter[100010];

inline int get_in(int x){
    return 2 * x;
}

inline int get_out(int x){
    return 2 * x + 1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    int i, j, k, l, x, w, s, t;

    while (scanf("%d", &n) != EOF){
        for (i = 0; i < n; i++) scanf("%d", &ar[i]);

        s = n * 2, t = s + 1, w = t + 1;
        mcmf::init(n * 2 + 3, s, t);

        mcmf::addEdge(s, w, 4, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_in(i), get_out(i), 1, -1);
        for (i = 0; i < n; i++) mcmf::addEdge(w, get_in(i), 1, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_out(i), t, 1, 0);

        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (abs(ar[j] - ar[i]) == 1){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        for (i = 0; i < n; i++) ar[i] %= 7;
        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (ar[i] == ar[j]){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        pair <int, int> res = mcmf::solve();
        printf("%d\n", -res.first);
    }
    return 0;
}


#include <stdio.h>
#include <bits/stdtr1c++.h>

#define MAX 200010
#define clr(ar) memset(ar, 0, sizeof(ar))
#define read() freopen("lol.txt", "r", stdin)
#define dbg(x) cout << #x << " = " << x << endl
#define ran(a, b) ((((rand() << 15) ^ rand()) % ((b) - (a) + 1)) + (a))

using namespace std;

namespace mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

    struct compare{
        inline bool operator()(int a, int b){
            if (dis[a] == dis[b]) return (a < b);
            return (dis[a] < dis[b]);
        }
    };
    set<int, compare> S;

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

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

    pair<int, int> solve(){
        int i, j, e, u, v, c;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            typedef pair<int, int> pii;
            priority_queue<pii, vector<pii>, greater<pii> > Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push({dis[s], s});
            while (!Q.empty()){
                c=Q.top().first, u = Q.top().second;
                Q.pop();
                if(c>dis[u]) continue;
                if(u==t) break;
                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push({dis[v], v});
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
}

int n, ar[5010];
char counter[100010];

inline int get_in(int x){
    return 2 * x;
}

inline int get_out(int x){
    return 2 * x + 1;
}

int main(){
    //freopen("input.txt", "r", stdin);
    int i, j, k, l, x, w, s, t;

    while (scanf("%d", &n) != EOF){
        for (i = 0; i < n; i++) scanf("%d", &ar[i]);
        //n = 3000;
        //for (i = 0; i < n; i++) ar[i] = rand() % 7 + 1;

        s = n * 2, t = s + 1, w = t + 1;
        mcmf::init(n * 2 + 3, s, t);

        mcmf::addEdge(s, w, 4, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_in(i), get_out(i), 1, -1);
        for (i = 0; i < n; i++) mcmf::addEdge(w, get_in(i), 1, 0);
        for (i = 0; i < n; i++) mcmf::addEdge(get_out(i), t, 1, 0);

        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (abs(ar[j] - ar[i]) == 1){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        for (i = 0; i < n; i++) ar[i] %= 7;
        for (i = 0; i < n; i++){
            clr(counter);
            for (j = i + 1; j < n; j++){
                if (ar[i] == ar[j]){
                    if (counter[ar[j]] <= 7){
                        counter[ar[j]]++;
                        mcmf::addEdge(get_out(i), get_in(j), 1, 0);
                    }
                }
            }
        }

        pair <int, int> res = mcmf::solve();
        printf("%d\n", -res.first);
    }
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int INF= 1e9;
const int N = 6e3 + 100;
struct edge { int f, c, to, r;};
vector<edge> G[N];
int S, T, prv[N], prp[N], cur[N], vst[N];
int d[N];
bool fst = false;
bool SPFA(int S) {
	if (fst) {
		d[S] = 0;
		for (int i = 1; i <= T; ++ i) {
			d[i] = INF;
			int cnt = 0;
			for (edge e : G[i]) {
				if (!e.f) {
					if (d[e.to] - e.c < d[i]) {
						d[i] = d[e.to] - e.c;
						prv[i] = e.to;
						prp[i] = cnt;
					}
				}
				cnt ++;
			}
			//printf("d[%d]=%d---\n", i, d[i]);
		}
		fst = 0;
		return d[T] != INF;
	} else {
		fill(d, d + 1 + T, INF);
		priority_queue<pair<int, int>> pq;
		pq.push({0, S});
		d[S] = 0;
		while (1) {
			while (!pq.empty() && -pq.top().first != d[pq.top().second]) pq.pop();
			if (pq.empty()) break;
			int v = pq.top().second; pq.pop();
			int cnt = 0;
			for (edge e : G[v]) {
				if (e.f && d[e.to] > d[v] + e.c) {
					d[e.to] = d[v] + e.c; prv[e.to] = v;
					prp[e.to] = cnt; pq.push({-d[e.to], e.to});
				}
				cnt ++;
			}
		}
		return d[T] != INF;
	}
}
int aug(int v, int flow) {
	if (v == T) return flow;
	vst[v] = 1; int flow1 = flow;
	for (int &i = cur[v]; i < (int) G[v].size(); ++ i) {
		edge &e = G[v][i];
		if (e.f && d[v] + e.c == d[e.to] && !vst[e.to]) {
			int flow1 = aug(e.to, min(flow, e.f));
			flow -= flow1; e.f -= flow1;
			G[e.to][e.r].f += flow1;
		}
		if (flow == 0) {
			vst[v] = 0; return flow1 - flow;
		}
	}
	return flow1 - flow;
}
int mcmf() {
	int ans = 0, sT = 0;
	while (SPFA(S)) {
		sT += d[T];
		for (int i = 0; i <= T; ++ i) cur[i] = 0, vst[i] = 0;
		ans += sT * aug(S, INF);
		/*int f = INF;
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			printf("%d\n", v);
			f = min(f, G[u][j].f);
		}
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			G[u][j].f -= f;
			G[v][G[u][j].r].f += f;
		}
		sT += d[T];
		printf("f=%d  d[T]=%d\n", f, d[T]);
		ans += f * sT;*/
		for (int i = 0; i <= T; ++ i) {
			for (auto &e : G[i]) {
				e.c += d[i] - d[e.to];
			}
		}
	}
	return ans;
}
void ae(int u, int v, int f, int c) {
	G[u].push_back((edge) {f, c, v, (int) G[v].size()});
	G[v].push_back((edge) {0, -c, u, (int) G[u].size() - 1});
}
int a[N];
int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
	S = 0, T = 2 * n + 2;
	int SS = 1;
	ae(S, SS, 4, 0);
	for (int i = 1; i <= n; ++ i) ae(2 * i, 2 * i + 1, 1, -1);
	for (int i = 1; i <= n; ++ i) {
		ae(SS, 2 * i, 1, 0);
		ae(2 * i + 1, T, 1, 0);
		int cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] % 7 == a[i] % 7) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] + 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] - 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
	}
	int ans = mcmf();
	printf("%d\n", -ans);
}


#include<bits/stdc++.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define MOD 1000000007
#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

struct _mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

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

    void add_edge(int u, int v, int w, int c){
        from[m] = u, adj[m] = v, cap[m] = c, cost[m] = w, next[m] = last[u], last[u] = m++;
        from[m] = v, adj[m] = u, cap[m] = 0, cost[m] = -w, next[m] = last[v], last[v] = m++;
    }

    pair<int, int> solve(){
        int i, j, e, u, v, c;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            typedef pair<int, int> pii;
            priority_queue<pii, vector<pii>, greater<pii> > Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push({dis[s], s});
            while (!Q.empty()){
                c=Q.top().first, u = Q.top().second;
                Q.pop();
                if(c>dis[u]) continue;
                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push({dis[v], v});
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        int INF=1000000000;
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.init(6*n+6, 2*src+1, 2*sink+2);
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.solve();

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


/* Cf: akigeor */
#include <bits/stdc++.h>
using namespace std;
const int INF= 1e9;
const int N = 6e3 + 100;
struct edge { int f, c, to, r;};
vector<edge> G[N];
int S, T, prv[N], prp[N], cur[N], vst[N];
int d[N];
bool fst = false;
bool SPFA(int S) {
	if (fst) {
		d[S] = 0;
		for (int i = 1; i <= T; ++ i) {
			d[i] = INF;
			int cnt = 0;
			for (edge e : G[i]) {
				if (!e.f) {
					if (d[e.to] - e.c < d[i]) {
						d[i] = d[e.to] - e.c;
						prv[i] = e.to;
						prp[i] = cnt;
					}
				}
				cnt ++;
			}
			//printf("d[%d]=%d---\n", i, d[i]);
		}
		fst = 0;
		return d[T] != INF;
	} else {
		fill(d, d + 1 + T, INF);
		priority_queue<pair<int, int>> pq;
		d[S] = 0;
		for(int i=0; i<=T; i++){
            pq.push({d[i], i});
		}
		while (1) {
			while (!pq.empty() && -pq.top().first != d[pq.top().second]) pq.pop();
			if (pq.empty()) break;
			int v = pq.top().second; pq.pop();
			int cnt = 0;
			for (edge e : G[v]) {
				if (e.f && d[e.to] > d[v] + e.c) {
					d[e.to] = d[v] + e.c; prv[e.to] = v;
					prp[e.to] = cnt; pq.push({-d[e.to], e.to});
				}
				cnt ++;
			}
		}
		return d[T] != INF;
	}
}
int aug(int v, int flow) {
	if (v == T) return flow;
	vst[v] = 1; int flow1 = flow;
	for (int &i = cur[v]; i < (int) G[v].size(); ++ i) {
		edge &e = G[v][i];
		if (e.f && d[v] + e.c == d[e.to] && !vst[e.to]) {
			int flow1 = aug(e.to, min(flow, e.f));
			flow -= flow1; e.f -= flow1;
			G[e.to][e.r].f += flow1;
		}
		if (flow == 0) {
			vst[v] = 0; return flow1 - flow;
		}
	}
	return flow1 - flow;
}
int mcmf() {
	int ans = 0, sT = 0;
	while (SPFA(S)) {
		sT += d[T];
		for (int i = 0; i <= T; ++ i) cur[i] = 0, vst[i] = 0;
		ans += sT * aug(S, INF);
		/*int f = INF;
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			printf("%d\n", v);
			f = min(f, G[u][j].f);
		}
		for (int v = T; v != S; v = prv[v]) {
			int u = prv[v];
			int j = prp[v];
			G[u][j].f -= f;
			G[v][G[u][j].r].f += f;
		}
		sT += d[T];
		printf("f=%d  d[T]=%d\n", f, d[T]);
		ans += f * sT;*/
		for (int i = 0; i <= T; ++ i) {
			for (auto &e : G[i]) {
				e.c += d[i] - d[e.to];
			}
		}
	}
	return ans;
}
void ae(int u, int v, int f, int c) {
	G[u].push_back((edge) {f, c, v, (int) G[v].size()});
	G[v].push_back((edge) {0, -c, u, (int) G[u].size() - 1});
}
int a[N];
int main() {
	int n;
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
	S = 0, T = 2 * n + 2;
	int SS = 1;
	ae(S, SS, 4, 0);
	for (int i = 1; i <= n; ++ i) ae(2 * i, 2 * i + 1, 1, -1);
	for (int i = 1; i <= n; ++ i) {
		ae(SS, 2 * i, 1, 0);
		ae(2 * i + 1, T, 1, 0);
		int cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] % 7 == a[i] % 7) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] + 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
		cnt = 0;
		for (int j = i + 1; j <= n; ++ j) if (a[j] - 1 == a[i]) {
			ae(2 * i + 1, 2 * j, 1, 0);
			if (cnt ++ == 4) break;
		}
	}
	int ans = mcmf();
	printf("%d\n", -ans);
}


#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define INF 10000000
#define MOD 1000000007
#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

#include <bits/stdc++.h>

using namespace std;

struct _mcmf{

    struct edge_t{
        int u, v, w, cap, prev;
    };

    static const int NMAX=30000;
    static const int NINF=1000000;
    vector<edge_t> edges;
    int last[NMAX];
    int D[NMAX]; // Distance from source
    int E[NMAX]; // Edge used to get to u

    void reset(){
        edges.clear();
        memset(last, -1, sizeof(last));
    }

    void add_edge(int u, int v, int w, int cap){
        edges.push_back({u, v,  w, cap, last[u]});
        last[u] = edges.size() - 1;
        edges.push_back({v, u, -w, 0, last[v]});
        last[v] = edges.size() - 1;
    }

    bool spfa(int src, int sink){
        for(int u=0; u<NMAX; u++) D[u]=NINF, E[u]=-1;
        queue<int> que;
        for(int u=0; u<NMAX; u++) que.push(u);
        D[src] = 0;
        E[src] = -2;
        que.push(src);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i = last[u]; i != -1; i = edges[i].prev){
                int v = edges[i].v, w = edges[i].w;
                if(edges[i].cap && (E[v]==-1||D[u]+w < D[v])){
                    D[v]=D[u]+w;
                    E[v]=i;
                    que.push(v);
                }
            }
        }
        //dbg(E[sink]);
        return (E[sink] != -1);
    }

    pair<int, int> max_flow(int src, int sink){
        int mflow = 0;
        int mcost = 0;
        while(spfa(src, sink)){
            int flow = NINF;
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                flow = min(flow, edges[i].cap);
            }
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                edges[i].cap -= flow;
                edges[i^1].cap += flow;
                mcost += edges[i].w*flow;
            }
            mflow += flow;
        }
        return {mcost, mflow};
    }

} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        mcmf.reset();
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }

            //
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.max_flow(2*src+1, 2*sink+2);

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define INF 10000000
#define MOD 1000000007

#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

#include <bits/stdc++.h>

using namespace std;

struct _mcmf{

    struct edge_t{
        int u, v, w, cap, prev;
    };

    static const int NMAX=30000;
    static const int NINF=1000000;
    vector<edge_t> edges;
    int last[NMAX];
    int D[NMAX]; // Distance from source
    int E[NMAX]; // Edge used to get to u

    void reset(){
        edges.clear();
        memset(last, -1, sizeof(last));
    }

    void add_edge(int u, int v, int w, int cap){
        edges.push_back({u, v,  w, cap, last[u]});
        last[u] = edges.size() - 1;
        edges.push_back({v, u, -w, 0, last[v]});
        last[v] = edges.size() - 1;
    }

    bool spfa(int src, int sink){
        for(int u=0; u<NMAX; u++) D[u]=NINF, E[u]=-1;
        queue<int> que;
        for(int u=0; u<NMAX; u++) que.push(u);
        D[src] = 0;
        E[src] = -2;
        que.push(src);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i = last[u]; i != -1; i = edges[i].prev){
                int v = edges[i].v, w = edges[i].w;
                if(edges[i].cap && (E[v]==-1||D[u]+w < D[v])){
                    D[v]=D[u]+w;
                    E[v]=i;
                    que.push(v);
                }
            }
        }
        //dbg(E[sink]);
        return (E[sink] != -1);
    }

    pair<int, int> max_flow(int src, int sink){
        int mflow = 0;
        int mcost = 0;
        while(spfa(src, sink)){
            int flow = NINF;
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                flow = min(flow, edges[i].cap);
            }
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                edges[i].cap -= flow;
                edges[i^1].cap += flow;
                mcost += edges[i].w*flow;
            }
            mflow += flow;
        }
        return {mcost, mflow};
    }

} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        mcmf.reset();
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }

            //
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.max_flow(2*src+1, 2*sink+2);

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


#include<bits/stdc++.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define MOD 1000000007
#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

struct _mcmf{
    const int INF = 1 << 28;

    int potential[MAX], dis[MAX], cap[MAX], cost[MAX];
    int n, m, s, t, to[MAX], from[MAX], last[MAX], next[MAX], adj[MAX];

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

    void add_edge(int u, int v, int w, int c){
        from[m] = u, adj[m] = v, cap[m] = c, cost[m] = w, next[m] = last[u], last[u] = m++;
        from[m] = v, adj[m] = u, cap[m] = 0, cost[m] = -w, next[m] = last[v], last[v] = m++;
    }

    pair<int, int> solve(){
        int i, j, e, u, v, c;
        int w, aug = 0, mincost = 0, maxflow = 0;

        for (i = 0; i < n; i++) potential[i] = INF, potential[s] = 0;

        for (u = 0; u < n; u++){
            for (e = last[u]; e != -1; e = next[e]){
                v = adj[e];
                potential[v] = min(potential[v], potential[u] + cost[e]);
            }
        }

        while (1){
            typedef pair<int, int> pii;
            priority_queue<pii, vector<pii>, greater<pii> > Q;
            for (i = 0; i < n; i++) dis[i] = INF;

            dis[s] = 0;
            Q.push({dis[s], s});
            while (!Q.empty()){
                c=Q.top().first, u = Q.top().second;
                Q.pop();
                if(c>dis[u]) continue;
                for (e = last[u]; e != -1; e = next[e]){
                    if (cap[e] != 0){
                        v = adj[e];
                        w = dis[u] + potential[u] + cost[e] - potential[v];

                        if (dis[v] > w){
                            //S.erase(v);
                            dis[v] = w, to[v] = e;
                            Q.push({dis[v], v});
                        }
                    }
                }
            }
            if (dis[t] >= (INF >> 1)) break;

            aug = cap[to[t]];
            for (i = t; i != s; i = from[to[i]]) aug = min(aug, cap[to[i]]);
            for (i = t; i != s; i = from[to[i]]){
                cap[to[i]] -= aug;
                cap[to[i] ^ 1] += aug;
                mincost += (cost[to[i]] * aug);
            }
            for (i = 0; i <= n; i++) potential[i] = min(potential[i] + dis[i], INF);
            maxflow += aug;
        }
        return make_pair(mincost, maxflow);
    }
} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        int INF=1000000000;
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.init(30000, 2*src+1, 2*sink+2);
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.solve();

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


#include <stdio.h>
#include <iostream>
#include <vector>
#include <string.h>

using namespace std;

/* Template Begins */

#define For(i,N) Forr(i, 0, N)
#define Forr(i,a,b) FOTR(i, a, b, 1)
#define FOTR(i,a,b,c) for(int i=(a);i<(b);i+=(c))
#define FOREACH(it, x) for(__typeof__((x).begin()) it=(x).begin();it!=(x).end();it++)
#define MEM(a,x) memset(a,x,sizeof(a))
#define BCHK(a,x) (((a)>>(x))&1)
#define BSET(a,x) ((a)|(1<<(x)))
#define BCLR(a,x) ((a)&(~(1<<(x))))
#define BTGL(a,x) ((a)^(1<<(x)))
#define FMT(...) (sprintf(CRTBUFF, __VA_ARGS__)?CRTBUFF:0)
#define read() freopen("input.txt","r",stdin)
#define write() freopen("output.txt","w",stdout)
#define cpp_io() {ios_base::sync_with_stdio(false);cin.tie(NULL);}
#define BUFFSIZE 30000
#define INF 10000000
#define MOD 1000000007
#define MAX 200000

typedef long long ll;

char CRTBUFF[BUFFSIZE];

#define dbg(args...) {string s(#args);s+=',';cout<<"-->";debugger::call(s.begin(), s.end(), args);cout<<"\n";}
#define dbg_A(A, N) {cout<<#A<<"=(";FOR(i,N)cout<<A[i]<<" ";cout<<"\b)\n";}
struct debugger{
    typedef string::iterator si;
    static void call(si it, si ed){}
    template<typename T, typename ... aT>
    static void call(si it, si ed, T a, aT... rest){
        string b;
        for(;*it!=',';++it) if(*it!=' ')b+=*it;
        cout << b << "=" << a << " ";
        call(++it, ed, rest...);
    }
};

/* Template Ends */

#include <bits/stdc++.h>

using namespace std;

struct _mcmf{

    struct edge_t{
        int u, v, w, cap, prev;
    };

    static const int NMAX=30000;
    static const int NINF=1000000;
    vector<edge_t> edges;
    int last[NMAX];
    int D[NMAX]; // Distance from source
    int E[NMAX]; // Edge used to get to u

    void reset(){
        edges.clear();
        memset(last, -1, sizeof(last));
    }

    void add_edge(int u, int v, int w, int cap){
        edges.push_back({u, v,  w, cap, last[u]});
        last[u] = edges.size() - 1;
        edges.push_back({v, u, -w, 0, last[v]});
        last[v] = edges.size() - 1;
    }

    bool spfa(int src, int sink){
        for(int u=0; u<NMAX; u++) D[u]=NINF, E[u]=-1;
        queue<int> que;
        D[src] = 0;
        E[src] = -2;
        que.push(src);
        while(!que.empty()){
            int u=que.front();
            que.pop();
            for(int i = last[u]; i != -1; i = edges[i].prev){
                int v = edges[i].v, w = edges[i].w;
                if(edges[i].cap && (E[v]==-1||D[u]+w < D[v])){
                    D[v]=D[u]+w;
                    E[v]=i;
                    que.push(v);
                }
            }
        }
        //dbg(E[sink]);
        return (E[sink] != -1);
    }

    pair<int, int> max_flow(int src, int sink){
        int mflow = 0;
        int mcost = 0;
        while(spfa(src, sink)){
            int flow = NINF;
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                flow = min(flow, edges[i].cap);
            }
            for(int i = E[sink]; i>=0 ; i = E[edges[i].u]){
                edges[i].cap -= flow;
                edges[i^1].cap += flow;
                mcost += edges[i].w*flow;
            }
            mflow += flow;
        }
        return {mcost, mflow};
    }

} mcmf;

int A[MAX + 100];
int Pos[MAX+10], PMod[MAX+10];

int main()
{
    //read();
    cpp_io();
    //begin
    int n;
    while(cin >> n){
        mcmf.reset();
        MEM(PMod, -1);
        MEM(Pos, -1);
        For(i, n) cin >> A[i];
        int lst=n;
        int src=lst++; int sink=lst++;
        mcmf.add_edge(2*src+1, 2*src+2, 0, 4);
        mcmf.add_edge(2*sink+1, 2*sink+2, 0, 4);
        for(int i=n-1; i>=0; i--){
            int e[3]={Pos[A[i]-1], Pos[A[i]+1], PMod[A[i]%7]};
            For(j, 3){
                if(e[j]==-1) continue;
                mcmf.add_edge(2*i+2, 2*e[j]+1, 0, INF);
            }
            int x=lst++, y=lst++;
            if(Pos[A[i]]!=-1) mcmf.add_edge(2*x+1, 2*Pos[A[i]]+1, 0, INF);
            if(PMod[A[i]%7]!=-1) mcmf.add_edge(2*y+1, 2*PMod[A[i]%7]+1, 0, INF);
            mcmf.add_edge(2*x+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*y+1, 2*i+1, 0, INF);
            mcmf.add_edge(2*src+2, 2*i+1, 0, INF);
            mcmf.add_edge(2*i+2, 2*sink+1, 0, INF);
            mcmf.add_edge(2*i+1, 2*i+2, -1, 1);
            Pos[A[i]]=x, PMod[A[i]%7]=y;
        }
        int cost, flow;
        tie(cost, flow)=mcmf.max_flow(2*src+1, 2*sink+2);

        int ans=-cost;
        cout << ans << "\n";
    }
    return 0;
}


#include <stdio.h>
#include <set>
#include <vector>
#include <queue>
using namespace std;
#define mp make_pair
#define pb push_back
const int N=3050;
const int M=N*N;
const int inf=1e9;
struct Edge
{
	int u,v,w,c;
	Edge(int a=0, int b=0, int d=0, int e=0){ u=a,v=b,w=d,c=e;}
};
vector<Edge> edges;
vector<int> E[N];
void AddEdge(int u, int v, int w, int c)
{
	E[u].pb(edges.size());
	edges.pb(Edge(u,v,w,c));
	E[v].pb(edges.size());
	edges.pb(Edge(v,u,-w,0));
}
int max(int a, int b){ return a>b?a:b;}
int min(int a, int b){ return a>b?b:a;}
int s,t,pot[N],in[N];
void SetPotentials()
{
	queue<int> q;
	int i,j;
	for(i=s;i<=t;i++) in[i]=0,pot[i]=inf;
	for(i=s;i<=t;i++) for(j=0;j<E[i].size();j++) if(edges[E[i][j]].c) in[edges[E[i][j]].v]++;
	q.push(s);
	pot[s]=0;
	while(q.size())
	{
		int u=q.front();
		q.pop();
		for(i=0;i<E[u].size();i++)
		{
			int v=edges[E[u][i]].v;
			int w=edges[E[u][i]].w;
			int c=edges[E[u][i]].c;
			if(c)
			{
				pot[v]=min(pot[v],pot[u]+w);
				in[v]--;
				if(!in[v]) q.push(v);
			}
		}
	}
}
set<pair<int,int> > pq;
bool was[N];
int dist[N],go[N];
bool Dijkstra()
{
	int i,j;
	for(i=s;i<=t;i++) was[i]=0,in[i]=0,dist[i]=inf;
	pq.insert(mp(0,s));
	in[s]=1;dist[s]=0;
	while(pq.size())
	{
		int u=pq.begin()->second;
		pq.erase(pq.begin());
		//printf("work:%i dist:%i\n",u,dist[u]);
		was[u]=1;in[u]=0;
		for(i=0;i<E[u].size();i++)
		{
			int v=edges[E[u][i]].v;
			int w=edges[E[u][i]].w+pot[u]-pot[v];
			int c=edges[E[u][i]].c;
			if(c && w<0) printf("%i %i %i %i %i %i???\n",u,v,w,pot[v],pot[u],c);
			if(c && dist[v]>dist[u]+w)
			{
				if(in[v]) pq.erase(mp(dist[v],v));
				dist[v]=dist[u]+w;
				go[v]=E[u][i];
				pq.insert(mp(dist[v],v));
				in[v]=1;
			}
		}
	}
	return was[t];
}
int MinCostKFlow(int k)
{
	SetPotentials();
	int ans=0,i;
	//printf("Potentials:\n");
	//for(i=s;i<=t;i++) printf("%i ",pot[i]);
	//printf("\n");
	while(k--)
	{
		if(!Dijkstra()) break;
		ans+=dist[t]-pot[s]+pot[t];
		for(i=t;i!=s;i=edges[go[i]].u)
		{
			edges[go[i]].c--;
			edges[go[i]^1].c++;
		}
		for(i=s;i<=t;i++) pot[i]+=dist[i];
		//printf("%i\n",ans);
	}
	return ans;
}
int a[N];
int main()
{
	int n,i,j;
	scanf("%i",&n);
	for(i=1;i<=n;i++) scanf("%i",&a[i]);
	s=0;t=n*2+1;
	for(i=1;i<=n;i++)
	{
		AddEdge(s,i,0,1);
		AddEdge(i,i+n,-1,1);
		AddEdge(i+n,t,0,1);
	}
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)
		{
			if(a[i]==a[j]-1 || a[i]==a[j]+1 || a[i]%7==a[j]%7)
			{
				AddEdge(i+n,j,0,1);
			}
		}
	}
	printf("%i\n",-MinCostKFlow(4));
	return 0;
}


#include <stdio.h>
#include <set>
#include <vector>
#include <queue>
using namespace std;
#define mp make_pair
#define pb push_back
const int N=6050;
const int M=N*N;
const int inf=1e9;
struct Edge
{
	int u,v,w,c;
	Edge(int a=0, int b=0, int d=0, int e=0){ u=a,v=b,w=d,c=e;}
};
vector<Edge> edges;
vector<int> E[N];
void AddEdge(int u, int v, int w, int c)
{
	E[u].pb(edges.size());
	edges.pb(Edge(u,v,w,c));
	E[v].pb(edges.size());
	edges.pb(Edge(v,u,-w,0));
}
int max(int a, int b){ return a>b?a:b;}
int min(int a, int b){ return a>b?b:a;}
int s,t,pot[N],in[N];
void SetPotentials()
{
	queue<int> q;
	int i,j;
	for(i=s;i<=t;i++) in[i]=0,pot[i]=inf;
	for(i=s;i<=t;i++) for(j=0;j<E[i].size();j++) if(edges[E[i][j]].c) in[edges[E[i][j]].v]++;
	q.push(s);
	pot[s]=0;
	while(q.size())
	{
		int u=q.front();
		q.pop();
		for(i=0;i<E[u].size();i++)
		{
			int v=edges[E[u][i]].v;
			int w=edges[E[u][i]].w;
			int c=edges[E[u][i]].c;
			if(c)
			{
				pot[v]=min(pot[v],pot[u]+w);
				in[v]--;
				if(!in[v]) q.push(v);
			}
		}
	}
}
set<pair<int,int> > pq;
bool was[N];
int dist[N],go[N];
bool Dijkstra()
{
	int i,j;
	for(i=s;i<=t;i++) was[i]=0,in[i]=0,dist[i]=inf;
	pq.insert(mp(0,s));
	in[s]=1;dist[s]=0;
	while(pq.size())
	{
		int u=pq.begin()->second;
		pq.erase(pq.begin());
		//printf("work:%i dist:%i\n",u,dist[u]);
		was[u]=1;in[u]=0;
		for(i=0;i<E[u].size();i++)
		{
			int v=edges[E[u][i]].v;
			int w=edges[E[u][i]].w+pot[u]-pot[v];
			int c=edges[E[u][i]].c;
			if(c && w<0) printf("%i %i %i %i %i %i???\n",u,v,w,pot[v],pot[u],c);
			if(c && dist[v]>dist[u]+w)
			{
				if(in[v]) pq.erase(mp(dist[v],v));
				dist[v]=dist[u]+w;
				go[v]=E[u][i];
				pq.insert(mp(dist[v],v));
				in[v]=1;
			}
		}
	}
	return was[t];
}
int MinCostKFlow(int k)
{
	SetPotentials();
	int ans=0,i;
	//printf("Potentials:\n");
	//for(i=s;i<=t;i++) printf("%i ",pot[i]);
	//printf("\n");
	while(k--)
	{
		if(!Dijkstra()) break;
		ans+=dist[t]-pot[s]+pot[t];
		for(i=t;i!=s;i=edges[go[i]].u)
		{
			edges[go[i]].c--;
			edges[go[i]^1].c++;
		}
		for(i=s;i<=t;i++) pot[i]+=dist[i];
		//printf("%i\n",ans);
	}
	return ans;
}
int a[N];
int main()
{
	int n,i,j;
	scanf("%i",&n);
	for(i=1;i<=n;i++) scanf("%i",&a[i]);
	s=0;t=n*2+1;
	for(i=1;i<=n;i++)
	{
		AddEdge(s,i,0,1);
		AddEdge(i,i+n,-1,1);
		AddEdge(i+n,t,0,1);
	}
	for(i=1;i<=n;i++)
	{
		for(j=i+1;j<=n;j++)
		{
			if(a[i]==a[j]-1 || a[i]==a[j]+1 || a[i]%7==a[j]%7)
			{
				AddEdge(i+n,j,0,1);
			}
		}
	}
	printf("%i\n",-MinCostKFlow(4));
	return 0;
}


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

struct node{
	int to,cap,cost,rev;
	node(int t=0,int c=0,int n=0,int r=0):to(t),cap(c),cost(n),rev(r){};
};
vector<node> edge[maxn];
void addedge(int from,int to,int cap,int cost){
//	printf("%d->%d %d %d\n",from,to,cap,cost);
	edge[from].push_back(node(to,cap,cost,edge[to].size()));
	edge[to].push_back(node(from,0,-cost,edge[from].size()-1));
}
int dis[maxn];
bool mark[maxn];
int pre_v[maxn],pre_e[maxn];
deque<int> Q;
int mincostflow(int s,int t,int f){
	int ret=0,d;
	int i,v;
	while (f){
		memset(dis,0x3f,sizeof(dis));
		memset(mark,0,sizeof(mark));
		while (Q.size()) Q.pop_front();
		dis[s]=0;Q.push_back(s);
		while (Q.size()){
			v=Q.front();mark[v]=0;Q.pop_front();
			REP(i,edge[v].size()){
				node &e=edge[v][i];
				if (e.cap>0&&dis[e.to]>dis[v]+e.cost){
					dis[e.to]=dis[v]+e.cost;
					pre_v[e.to]=v;
					pre_e[e.to]=i;
					if (!mark[e.to]){
						if (Q.empty()||dis[Q.front()]<dis[e.to]) Q.push_back(e.to);
						else Q.push_front(e.to);
						mark[e.to]=1;
					}
				}
			}
		}
		if (dis[t]==INF) break;
		d=f;
		for (v=t;v!=s;v=pre_v[v])
			d=min(d,edge[pre_v[v]][pre_e[v]].cap);
		f-=d;
		ret+=d*dis[t];
		for(v=t;v!=s;v=pre_v[v]){
			node &e=edge[pre_v[v]][pre_e[v]];
			e.cap-=d;
			edge[v][e.rev].cap+=d;
		}
		if (d==0) break;
	}
	return ret;
}
int n,s,t;
int i,k;
int tot,now,choose;
int val[maxn],mod[8];
int main(){
	scanf("%d",&n);
	tot=0;
	s=++tot;t=++tot;
	REP(i,n){
		scanf("%d",&k);
		now=++tot;choose=++tot;//now=could->choose
		if (val[k-1]) addedge(val[k-1],now,INF,0);
		if (val[k+1]) addedge(val[k+1],now,INF,0);
		val[k]=choose;
		tot++;
		if (mod[k%7]) addedge(mod[k%7],tot,INF,0);
		if (mod[k%7]) addedge(mod[k%7],now,INF,0);
		addedge(choose,tot,INF,0);
		mod[k%7]=tot;
		addedge(now,choose,1,-1);
		addedge(s,now,INF,0);
		addedge(choose,t,INF,0);
	}
	printf("%d",-mincostflow(s,t,4));
}
/*
*/


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

struct node{
	int to,cap,cost,rev;
	node(int t=0,int c=0,int n=0,int r=0):to(t),cap(c),cost(n),rev(r){};
};
vector<node> edge[maxn];
void addedge(int from,int to,int cap,int cost){
//	printf("%d->%d %d %d\n",from,to,cap,cost);
	edge[from].push_back(node(to,cap,cost,edge[to].size()));
	edge[to].push_back(node(from,0,-cost,edge[from].size()-1));
}
int dis[maxn];
bool mark[maxn];
int pre_v[maxn],pre_e[maxn];
deque<int> Q;
int mincostflow(int s,int t,int f){
	int ret=0,d;
	int i,v;
	while (f){
		memset(dis,0x3f,sizeof(dis));
		memset(mark,0,sizeof(mark));
		while (Q.size()) Q.pop_front();
		dis[s]=0;Q.push_back(s);
		while (Q.size()){
			v=Q.front();mark[v]=0;Q.pop_front();
			REP(i,edge[v].size()){
				node &e=edge[v][i];
				if (e.cap>0&&dis[e.to]>dis[v]+e.cost){
					dis[e.to]=dis[v]+e.cost;
					pre_v[e.to]=v;
					pre_e[e.to]=i;
					if (!mark[e.to]){
						if (Q.empty()||dis[Q.front()]<dis[e.to]) Q.push_back(e.to);
						else Q.push_front(e.to);
						mark[e.to]=1;
					}
				}
			}
		}
		if (dis[t]==INF) break;
		d=f;
		for (v=t;v!=s;v=pre_v[v])
			d=min(d,edge[pre_v[v]][pre_e[v]].cap);
		f-=d;
		ret+=d*dis[t];
		for(v=t;v!=s;v=pre_v[v]){
			node &e=edge[pre_v[v]][pre_e[v]];
			e.cap-=d;
			edge[v][e.rev].cap+=d;
		}
		if (d==0) break;
	}
	return ret;
}
int n,s,t;
int i,k;
int tot,now,choose;
int val[maxn],mod[8];
int main(){
	scanf("%d",&n);
	tot=0;
	s=++tot;t=++tot;
	REP(i,n){
		scanf("%d",&k);
		now=++tot;choose=++tot;//now=could->choose
		if (val[k-1]) addedge(val[k-1],now,INF,0);
		if (val[k+1]) addedge(val[k+1],now,INF,0);
		if (val[k]) addedge(val[k],choose,INF,0);
		val[k]=choose;
		tot++;
		if (mod[k%7]) addedge(mod[k%7],tot,INF,0);
		if (mod[k%7]) addedge(mod[k%7],now,INF,0);
		addedge(choose,tot,INF,0);
		mod[k%7]=tot;
		addedge(now,choose,1,-1);
		addedge(s,now,INF,0);
		addedge(choose,t,INF,0);
	}
	printf("%d",-mincostflow(s,t,2));
}
/*
*/


#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <utility>
using namespace std;
#define REP(I,N) for (I=0;I<N;I++)
#define rREP(I,N) for (I=N-1;I>=0;I--)
#define rep(I,S,N) for (I=S;I<N;I++)
#define rrep(I,S,N) for (I=N-1;I>=S;I--)
#define FOR(I,S,N) for (I=S;I<=N;I++)
#define rFOR(I,S,N) for (I=N;I>=S;I--)
typedef unsigned long long ULL;
typedef long long LL;
const int INF=0x3f3f3f3f;
const LL INFF=0x3f3f3f3f3f3f3f3fll;
const LL M=1e9+7;
const LL maxn=1e6+7;
const double eps=0.00000001;
LL gcd(LL a,LL b){return b?gcd(b,a%b):a;}
template<typename T>inline T abs(T a) {return a>0?a:-a;}
template<typename T>inline T powMM(T a,T b){T ret=1;for (;b;b>>=1ll,a=a*a%M) ret=1ll*ret*a%M;return ret;}

struct node{
	int to,cap,cost,rev;
	node(int t=0,int c=0,int n=0,int r=0):to(t),cap(c),cost(n),rev(r){};
};
vector<node> edge[maxn];
void addedge(int from,int to,int cap,int cost){
//	printf("%d->%d %d %d\n",from,to,cap,cost);
	edge[from].push_back(node(to,cap,cost,edge[to].size()));
	edge[to].push_back(node(from,0,-cost,edge[from].size()-1));
}
int dis[maxn];
bool mark[maxn];
int pre_v[maxn],pre_e[maxn];
deque<int> Q;
int mincostflow(int s,int t,int f){
	int ret=0,d;
	int i,v;
	while (f){
		memset(dis,0x3f,sizeof(dis));
		memset(mark,0,sizeof(mark));
		while (Q.size()) Q.pop_front();
		dis[s]=0;Q.push_back(s);
		while (Q.size()){
			v=Q.front();mark[v]=0;Q.pop_front();
			REP(i,edge[v].size()){
				node &e=edge[v][i];
				if (e.cap>0&&dis[e.to]>dis[v]+e.cost){
					dis[e.to]=dis[v]+e.cost;
					pre_v[e.to]=v;
					pre_e[e.to]=i;
					if (!mark[e.to]){
						if (Q.empty()||dis[Q.front()]<dis[e.to]) Q.push_back(e.to);
						else Q.push_front(e.to);
						mark[e.to]=1;
					}
				}
			}
		}
		if (dis[t]==INF) break;
		d=f;
		for (v=t;v!=s;v=pre_v[v])
			d=min(d,edge[pre_v[v]][pre_e[v]].cap);
		f-=d;
		ret+=d*dis[t];
		for(v=t;v!=s;v=pre_v[v]){
			node &e=edge[pre_v[v]][pre_e[v]];
			e.cap-=d;
			edge[v][e.rev].cap+=d;
		}
		if (d==0) break;
	}
	return ret;
}
int n,s,t;
int i,k;
int tot,now,choose;
int val[maxn],mod[8];
int main(){
	scanf("%d",&n);
	tot=0;
	s=++tot;t=++tot;
	REP(i,n){
		scanf("%d",&k);
		now=++tot;choose=++tot;//now=could->choose
		if (val[k-1]) addedge(val[k-1],now,INF,0);
		if (val[k+1]) addedge(val[k+1],now,INF,0);
		if (val[k]) addedge(val[k],choose,INF,0);
		val[k]=choose;
		tot++;
		if (mod[k%7]) addedge(mod[k%7],tot,INF,0);
		if (mod[k%7]) addedge(mod[k%7],now,INF,0);
		addedge(choose,tot,INF,0);
		mod[k%7]=tot;
		addedge(now,choose,1,-1);
		addedge(s,now,INF,0);
		addedge(choose,t,INF,0);
	}
	printf("%d",-mincostflow(s,t,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])
				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;
	}

	void shuffle()
	{
		for (auto &v : g)
			random_shuffle(v.begin(), v.end());
	}
};

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);

	f.shuffle();
	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 5005
#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;
		queue<int> q;
		inqueue[u] = 1;
		q.push(u);

		while (q.size())
		{
			int x = q.front();
			q.pop();
			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])
						q.push(e[v].to), inqueue[e[v].to] = 1;
				}
		}

		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];

vector<int> dp[N], g[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], dp[w[i] % 7].push_back(i), g[w[i]].push_back(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)
		auto it = upper_bound(g[w[i] + 1].begin(), g[w[i] + 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] + 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(g[w[i] - 1].begin(), g[w[i] - 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] - 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(dp[w[i] % 7].begin(), dp[w[i] % 7].end(), i);
		for (int j = 0; j < 100 && it != dp[w[i] % 7].end(); it++, j++)
			f.add(2 * i, 2 * *it - 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])
				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];

	random_shuffle(w + 1, w + n + 1);

	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];

vector<int> dp[N], g[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], dp[w[i] % 7].push_back(i), g[w[i]].push_back(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)
		auto it = upper_bound(g[w[i] + 1].begin(), g[w[i] + 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] + 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(g[w[i] - 1].begin(), g[w[i] - 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] - 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(dp[w[i] % 7].begin(), dp[w[i] % 7].end(), i);
		for (int j = 0; j < 4 && it != dp[w[i] % 7].end(); it++, j++)
			f.add(2 * i, 2 * *it - 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];

vector<int> dp[N], g[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], dp[w[i] % 7].push_back(i), g[w[i]].push_back(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)
		auto it = upper_bound(g[w[i] + 1].begin(), g[w[i] + 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] + 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(g[w[i] - 1].begin(), g[w[i] - 1].end(), i);
		for (int j = 0; j < 4 && it != g[w[i] - 1].end(); it++, j++)
			f.add(2 * i, 2 * *it - 1, 1, 0);

		it = upper_bound(dp[w[i] % 7].begin(), dp[w[i] % 7].end(), i);
		for (; it != dp[w[i] % 7].end(); it++)
			f.add(2 * i, 2 * *it - 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;
		for (auto &vc : g)
			random_shuffle(vc.begin(), vc.end());

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