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

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

int arr[5007];

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

using namespace mcmf;

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

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

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

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

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

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

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

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

	ll ans= solve().ff;

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


// http://www.geeksforgeeks.org/ford-fulkerson-algorithm-for-maximum-flow-problem/

#include <bits/stdc++.h>

using namespace std;
//using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define FOR(i, a, b) for (int i=a; i<b; i++)
#define F0R(i, a) for (int i=0; i<a; i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
double PI = 4*atan(1);

struct Edge {
    int v, flow, C, rev, cost;
};

template<int SZ> struct mcf {
    pii pre[SZ];
    int cost[SZ], num[SZ], SC, SNC;
    ll flo, ans, ccost;
    vector<Edge> adj[SZ];

    void addEdge(int u, int v, int C, int cost) {
        Edge a{v, 0, C, (int)adj[v].size(), cost};
        Edge b{u, 0, 0, (int)adj[u].size(), -cost};
        adj[u].pb(a), adj[v].pb(b);
    }

    void reweight() {
    	F0R(i,SZ) {
    	    for (auto& p: adj[i]) p.cost += cost[i]-cost[p.v];
    	}
    }

    bool spfa() {
        F0R(i,SZ) cost[i] = MOD, num[i] = 0;
        cost[SC] = 0, num[SC] = MOD;
        priority_queue<pii,vector<pii>,greater<pii>> todo; todo.push({0,SC});

        while (todo.size()) {
            pii x = todo.top(); todo.pop();
            if (x.f > cost[x.s]) continue;
            for (auto a: adj[x.s]) if (x.f+a.cost < cost[a.v] && a.flow < a.C) {
                pre[a.v] = {x.s,a.rev};
                cost[a.v] = x.f+a.cost;
                num[a.v] = min(a.C-a.flow,num[x.s]);
                todo.push({cost[a.v],a.v});
            }
        }

        ccost += cost[SNC];
        return num[SNC] > 0;
    }

    void backtrack() {
        flo += num[SNC], ans += (ll)num[SNC]*ccost;
        for (int x = SNC; x != SC; x = pre[x].f) {
            adj[x][pre[x].s].flow -= num[SNC];
            int t = adj[x][pre[x].s].rev;
            adj[pre[x].f][t].flow += num[SNC];
        }
    }

    pii mincostflow(int sc, int snc) {
        SC = sc, SNC = snc;
        flo = ans = ccost = 0;

        spfa();
        F0R(i,4) {
            reweight();
            if (!spfa()) return {flo,ans};
            backtrack();
        }
        return {flo,ans};
    }
};

mcf<6002> m;
int n, a[3001];

int main() {
    cin >> n;
    FOR(i,1,n+1) {
        cin >> a[i];
        m.addEdge(0,i,1,0);
        m.addEdge(i+n,2*n+1,1,0);
    }
    FOR(i,1,n+1) m.addEdge(i,i+n,1,-1);
    FOR(i,1,n+1) FOR(j,i+1,n+1) if ((a[i]-a[j]) % 7 == 0 || abs(a[i]-a[j]) <= 1) {
        m.addEdge(i+n,j,1,0);
    }
    pii x = m.mincostflow(0,2*n+1);
    cout << -x.s;
}


// http://www.geeksforgeeks.org/ford-fulkerson-algorithm-for-maximum-flow-problem/

#include <bits/stdc++.h>

using namespace std;
//using namespace __gnu_pbds;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
//typedef tree<int,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update> ordered_set;

#define FOR(i, a, b) for (int i=a; i<b; i++)
#define F0R(i, a) for (int i=0; i<a; i++)
#define FORd(i,a,b) for (int i = (b)-1; i >= a; i--)
#define F0Rd(i,a) for (int i = (a)-1; i >= 0; i--)

#define mp make_pair
#define pb push_back
#define f first
#define s second
#define lb lower_bound
#define ub upper_bound

const int MOD = 1000000007;
double PI = 4*atan(1);

struct Edge {
    int v, flow, C, rev, cost;
};

template<int SZ> struct mcf {
    pii pre[SZ];
    int cost[SZ], num[SZ], SC, SNC;
    vector<Edge> adj[SZ];

    void addEdge(int u, int v, int C, int cost) {
        Edge a{v, 0, C, (int)adj[v].size(), cost};
        Edge b{u, 0, 0, (int)adj[u].size(), -cost};
        adj[u].pb(a);
        adj[v].pb(b);
    }

    bool bfs() {
        F0R(i,SZ) cost[i] = MOD, num[i] = 0;
        cost[SC] = 0, num[SC] = MOD;
        priority_queue<pii,vector<pii>,greater<pii>> todo; todo.push({0,SC});
        // doesn't handle negative edges very well
        // no negative cycles

        while (todo.size()) {
            pii x = todo.top(); todo.pop();
            for (auto a: adj[x.s]) if (x.f+a.cost < cost[a.v] && a.flow < a.C) {
                pre[a.v] = {x.s,a.rev};
                cost[a.v] = x.f+a.cost;
                num[a.v] = min(a.C-a.flow,num[x.s]);
                todo.push({cost[a.v],a.v});
            }
        }

        return num[SNC] > 0;
    }

    pii mincostflow(int sc, int snc) {
        SC = sc, SNC = snc;

        int flo = 0, ans = 0;
        F0R(i,4) {
            bfs();
            flo += num[SNC], ans += (ll)num[SNC]*cost[SNC];
            for (int x = SNC; x != SC; x = pre[x].f) {
                adj[x][pre[x].s].flow -= num[SNC];
                int t = adj[x][pre[x].s].rev;
                adj[pre[x].f][t].flow += num[SNC];
            }
        }

        return {flo,ans};
    }
};

mcf<6002> m;
int n, a[3001];

int main() {
    cin >> n;
    FOR(i,1,n+1) {
        cin >> a[i];
        m.addEdge(0,i,1,0);
        m.addEdge(i+n,2*n+1,1,0);
    }
    FOR(i,1,n+1) m.addEdge(i,i+n,1,-1);
    FOR(i,1,n+1) FOR(j,i+1,n+1) if ((a[i]-a[j]) % 7 == 0 || abs(a[i]-a[j]) <= 1) {
        m.addEdge(i+n,j,1,0);
    }
    pii x = m.mincostflow(0,2*n+1);
    cout << -x.s;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
const int inf = 1e9;
inline int read()
{
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
  return p*f;
}

struct node{int x,y,d,c,next;}edge[N<<4]; int len,first[N];
void ins(int x,int y,int c,int d)
{
  len++; edge[len].x=x; edge[len].y=y; edge[len].c=c; edge[len].d=d; edge[len].next=first[x]; first[x]=len;
  len++; edge[len].x=y; edge[len].y=x; edge[len].c=0; edge[len].d=-d; edge[len].next=first[y]; first[y]=len;
}

bool v[N]; int d[N]; queue<int>q; int pre[N],pos[N]; int s,t;
bool bfs()
{
  while(!q.empty()) q.pop(); q.push(s);
  memset(d,-63,sizeof(d)); d[s]=0;
  memset(v,0,sizeof(v)); v[s]=1;
  while(!q.empty())
  {
    int x=q.front();
    for(int k=first[x];k!=-1;k=edge[k].next)
    {
      int y=edge[k].y;
      if(d[y] < d[x] + edge[k].d && edge[k].c)
      {
        d[y] = d[x] + edge[k].d; pos[y] = x; pre[y]=k;
        if(!v[y]){v[y]=1; q.push(y);}
      }
    }
    q.pop(); v[x] = 0;
  }
  return d[t] >= 0;
}

int n,a[N];

int main()
{

  len=1; memset(first,-1,sizeof(first));
  n = read(); for(int i=1;i<=n;i++) a[i] = read();
  int ss=2*n+1; s = ss+1; t = s+1; ins(s,ss,4,0);
  for(int i=1;i<=n;i++)
  {
    ins(ss,i,1,1);
    ins(i+n,i,1,1);
    ins(i,t,1,0);
  }

  for(int i=1;i<=n;i++)
  {
    int cnt = 0;
    #define MAGIC 55
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == 1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == -1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i]%7==0 && a[j]%7==0) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
  }

  int ans = 0;
  while(bfs())
  {
    for(int i=t;i!=s;i=pos[i]) ans+=edge[pre[i]].d,edge[pre[i]].c--,edge[pre[i]^1].c++;
  }

  return printf("%d\n",ans),0;
}


#include <bits/stdc++.h>
using namespace std;
const int N = 50010;
const int inf = 1e9;
inline int read()
{
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
  return p*f;
}

struct node{int x,y,d,c,next;}edge[N<<4]; int len,first[N];
void ins(int x,int y,int c,int d)
{
  len++; edge[len].x=x; edge[len].y=y; edge[len].c=c; edge[len].d=d; edge[len].next=first[x]; first[x]=len;
  len++; edge[len].x=y; edge[len].y=x; edge[len].c=0; edge[len].d=-d; edge[len].next=first[y]; first[y]=len;
}

bool v[N]; int d[N]; queue<int>q; int pre[N],pos[N]; int s,t;
bool bfs()
{
  while(!q.empty()) q.pop(); q.push(s);
  memset(d,-63,sizeof(d)); d[s]=0;
  memset(v,0,sizeof(v)); v[s]=1;
  while(!q.empty())
  {
    int x=q.front();
    for(int k=first[x];k!=-1;k=edge[k].next)
    {
      int y=edge[k].y;
      if(d[y] < d[x] + edge[k].d && edge[k].c)
      {
        d[y] = d[x] + edge[k].d; pos[y] = x; pre[y]=k;
        if(!v[y]){v[y]=1; q.push(y);}
      }
    }
    q.pop(); v[x] = 0;
  }
  return d[t] >= 0;
}

int n,a[N];

int main()
{

  len=1; memset(first,-1,sizeof(first));
  n = read(); for(int i=1;i<=n;i++) a[i] = read();
  int ss=2*n+1; s = ss+1; t = s+1; ins(s,ss,4,0);
  for(int i=1;i<=n;i++)
  {
    ins(ss,i+n,1,0);
    ins(i+n,i,1,1);
    ins(i,t,1,0);
  }

  for(int i=1;i<=n;i++)
  {
    int cnt = 0;
    #define MAGIC 55
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == 1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == -1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i]%7 == a[j]%7) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
  }

  int ans = 0;
  while(bfs())
  {
    for(int i=t;i!=s;i=pos[i]) ans+=edge[pre[i]].d,edge[pre[i]].c--,edge[pre[i]^1].c++;
  }

  return printf("%d\n",ans),0;
}


#include <bits/stdc++.h>
#define MP make_pair
using namespace std;
const int N = 50010;
const int inf = 1e9;
typedef pair<int,int> pii;
inline int read()
{
  int p=0; int f=1; char ch=getchar();
  while(ch<'0' || ch>'9'){if(ch=='-') f=-1; ch=getchar();}
  while(ch>='0' && ch<='9'){p=p*10+ch-'0'; ch=getchar();}
  return p*f;
}

struct node{int x,y,d,c,next;}edge[N<<4]; int len,first[N];
void ins(int x,int y,int c,int d)
{
  len++; edge[len].x=x; edge[len].y=y; edge[len].c=c; edge[len].d=d; edge[len].next=first[x]; first[x]=len;
  len++; edge[len].x=y; edge[len].y=x; edge[len].c=0; edge[len].d=-d; edge[len].next=first[y]; first[y]=len;
}

bool v[N]; int d[N]; queue<int>q; int pre[N],pos[N]; int s,t;
bool bfs()
{
  while(!q.empty()) q.pop(); q.push(s);
  memset(d,-63,sizeof(d)); d[s]=0;
  memset(v,0,sizeof(v)); v[s]=1;
  while(!q.empty())
  {
    int x=q.front();
    for(int k=first[x];k!=-1;k=edge[k].next)
    {
      int y=edge[k].y;
      if(d[y] < d[x] + edge[k].d && edge[k].c)
      {
        d[y] = d[x] + edge[k].d; pos[y] = x; pre[y]=k;
        if(!v[y]){v[y]=1; q.push(y);}
      }
    }
    q.pop(); v[x] = 0;
  }
  return d[t] >= 0;
}

int n,a[N];

int main()
{

  len=1; memset(first,-1,sizeof(first));
  n = read(); for(int i=1;i<=n;i++) a[i] = read();
  int ss=2*n+1; s = ss+1; t = s+1; ins(s,ss,4,0);
  for(int i=1;i<=n;i++)
  {
    ins(ss,i+n,1,0);
    ins(i+n,i,1,1);
    ins(i,t,1,0);
  }

  for(int i=1;i<=n;i++)
  {
    int cnt = 0;
    #define MAGIC 1
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == 1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i] - a[j] == -1) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    cnt=0;
    for(int j=i+1;j<=n;j++)
      if((a[i]%7 == a[j]%7) && cnt < MAGIC){ins(i,j+n,inf,0); cnt++;}
    ins(i+n,i,inf,0);
  }

  int ans = 0;
  while(bfs())
  {
    for(int i=t;i!=s;i=pos[i]) ans+=edge[pre[i]].d,edge[pre[i]].c--,edge[pre[i]^1].c++;
  }

  return printf("%d\n",ans),0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
template<class FW=ll,class CO=ll>
struct MCMF{
    struct eg{int t;FW C;CO W;int x;};
    const FW IF=1e9;
    const CO IC=1e17;
    int n,t,S,T;
    FW s;
    CO P;
    vector<int> l,v;
    vector<CO> H;
    vector<eg> G;
    MCMF(int n):n(n),l(n,-1),v(n,0),H(n,0){t=s=P=0,G.clear();}
    int ade(int F,int T,FW C,CO W){
        return G.PB({T,C,W,l[F]}),l[F]=t++,G.PB({F,0,-W,l[T]}),l[T]=t++,t-2;
    }
    pair<FW,CO> mf(int a,int b){
        S=a,T=b,SPFA();
        do do F(n)v[i]=0;while(FLW(S,IF));while(ML());
        return {s,P};
    }
    void SPFA(){
        F(n)H[i]=IC;
        priority_queue<pair<CO,ll>>Q;
        Q.push({H[S]=0,S});
        while (!Q.empty()) {
            ll x=Q.top().bb;
            CO d=-Q.top().aa;
            Q.pop();
            if(H[x]!=d)continue;
            for(int i=l[x];~i;i=G[i].x)
                if(G[i].C>0&&H[G[i].t]>d+G[i].W)
                    Q.push({-(H[G[i].t]=d+G[i].W),G[i].t});
        }
        F(n)H[i]=H[T]-H[i];
    }
    FW FLW(ll x,FW f){
        if(x==T)return P+=H[S]*f,s+=f,f;
        FW t=f;
        v[x]=1;
        for(int i=l[x];~i;i=G[i].x)
            if(G[i].C&&!v[G[i].t]&&H[G[i].t]+G[i].W==H[x]){
                FW a=FLW(G[i].t,min(t,G[i].C));
                G[i].C-=a,G[i^1].C+=a,t-=a;
                if(!t)break;
            }
        return f-t;
    }
    bool ML(){
        CO d=IC;
        F(n)if(v[i])for(int j=l[i];~j;j=G[j].x)
            if(G[j].C&&!v[G[j].t])d=min(d,H[G[j].t]+G[j].W-H[i]);

        if(d==IC)return 0;
        F(n)if(v[i])H[i]+=d;
        return 1;
    }
};
#define MX (6006)
int N,A[MX];
int main(void){
    scanf("%d",&N),ga(N,A);
    MCMF<ll,ll> G(2*N+3);
    G.ade(2*N,2*N+2,4,0);
    F(N)G.ade(2*N+2,i,1,-1),G.ade(i,N+i,1,0),G.ade(N+i,2*N+1,1,0);
    F(N){
        FT(i+1,N)if(A[i]+1==A[k])G.ade(N+i,k,1,-1),k=INF;
        FT(i+1,N)if(A[i]%7==A[k]%7)G.ade(N+i,k,1,-1),k=INF;
    }
    printf("%lld\n",-G.mf(2*N,2*N+1).bb);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
template<class FW=ll,class CO=ll>
struct MCMF{
    struct eg{int t;FW C;CO W;int x;};
    const FW IF=1e9;
    const CO IC=1e17;
    int n,t,S,T;
    FW s;
    CO P;
    vector<int> l,v;
    vector<CO> H;
    vector<eg> G;
    MCMF(int n):n(n),l(n,-1),v(n,0),H(n,0){t=s=P=0,G.clear();}
    int ade(int F,int T,FW C,CO W){
        return G.PB({T,C,W,l[F]}),l[F]=t++,G.PB({F,0,-W,l[T]}),l[T]=t++,t-2;
    }
    pair<FW,CO> mf(int a,int b){
        S=a,T=b,SPFA();
        do do F(n)v[i]=0;while(FLW(S,IF));while(ML());
        return {s,P};
    }
    void SPFA(){
        F(n)H[i]=IC;
        priority_queue<pair<CO,ll>>Q;
        Q.push({H[S]=0,S});
        while (!Q.empty()) {
            ll x=Q.top().bb;
            CO d=-Q.top().aa;
            Q.pop();
            if(H[x]!=d)continue;
            for(int i=l[x];~i;i=G[i].x)
                if(G[i].C>0&&H[G[i].t]>d+G[i].W)
                    Q.push({-(H[G[i].t]=d+G[i].W),G[i].t});
        }
        F(n)H[i]=H[T]-H[i];
    }
    FW FLW(ll x,FW f){
        if(x==T)return P+=H[S]*f,s+=f,f;
        FW t=f;
        v[x]=1;
        for(int i=l[x];~i;i=G[i].x)
            if(G[i].C&&!v[G[i].t]&&H[G[i].t]+G[i].W==H[x]){
                FW a=FLW(G[i].t,min(t,G[i].C));
                G[i].C-=a,G[i^1].C+=a,t-=a;
                if(!t)break;
            }
        return f-t;
    }
    bool ML(){
        CO d=IC;
        F(n)if(v[i])for(int j=l[i];~j;j=G[j].x)
            if(G[j].C&&!v[G[j].t])d=min(d,H[G[j].t]+G[j].W-H[i]);

        if(d==IC)return 0;
        F(n)if(v[i])H[i]+=d;
        return 1;
    }
};
#define MX (3006)
int N,A[MX];
int main(void){
    scanf("%d",&N),ga(N,A);
    MCMF<ll,ll> G(2*N+3);
    G.ade(2*N,2*N+2,4,0);
    F(N)G.ade(2*N+2,i,1,-1),G.ade(i,N+i,1,0),G.ade(N+i,2*N+1,1,0);
    F(N){
        FT(i+1,N)if(A[i]+1==A[k])G.ade(N+i,k,1,-1),k=INF;
        FT(i+1,N)if(A[i]-1==A[k])G.ade(N+i,k,1,-1),k=INF;
        FT(i+1,N)if(A[i]%7==A[k]%7)G.ade(N+i,k,1,-1),k=INF;
    }
    printf("%lld\n",-G.mf(2*N,2*N+1).bb);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
#define MX (6005)
#define EG (MX*10)
struct MCMF{
    MCMF(){m=0;}
    void CLR(int N,int S,int T){
        m=0,n=N,s=S+1,t=T+1;
        F(n)g[i+1].clear();
    }
    void RST(){F(m)E[i].F=0;}
    void ade(int f,int t,int F,int C) {
        E[m++]=eg(++f,++t,0,F,C);
        E[m++]=eg(t,f,0,0,-C);
        g[f].PB(m-2);
        g[t].PB(m-1);
    }
    struct eg{
        int f,t,F,C,W;
        eg(int a=0,int b=0,int c=0,int d=0,int e=0){f=a,t=b,C=d,W=e,F=c;}
        inline int OT(int u){return f^t^u;}
    };
    bool C[MX];
    int n,m,s,t,p[MX],D[MX],P[MX];
    vi g[MX];
    eg E[2*EG];
    priority_queue<ii> Q;
    int BF(int u){
        if(C[u])return p[u];
        if(u==s)return p[s]=0;
        C[u]=1,p[u]=INF;
        for(auto h:g[u])if(E[h^1].F<E[h^1].C)
            p[u]=min(p[u],BF(E[h^1].OT(u))+E[h^1].W);
        return p[u];
    }
    bool DJ(){
        int u,OT,W;
        memset(C,0,n+1),fill(D+1,D+n+1,INF),D[s]=0;
        Q.push({0,s});
        while(!Q.empty()){
            u=Q.top().bb,Q.pop();
            if(C[u]++)continue;
            for(auto h:g[u]){
                OT=E[h].OT(u),W=E[h].W+p[u]-p[OT];
                if(E[h].F<E[h].C&&D[u]+W<D[OT])
                    D[OT]=D[u]+W,P[OT]=h,Q.push({-D[OT],OT});
            }
        }
        F(n)D[i+1]+=p[i+1]-p[s];
        return C[t];
    }
    ii mf(){
        memset(p,0,(n+1)<<2),BF(t);
        int F=0,W=0,u,X,S;
        while(DJ()){
            u=t,X=INF,S=0;
            while(u^s)
                X=min(X,E[P[u]].C-E[P[u]].F),
                S+=E[P[u]].W,u=E[P[u]].OT(u);
            u=t;
            while(u^s)
                E[P[u]].F+=X,E[P[u]^1].F-=X,
                u=E[P[u]].OT(u);
            F+=X,W+=X*S;
            memcpy(p,D,(n+1)<<2);
        }
        return {F,W};
    }
}G;
int N,A[MX],H;
int main(void){
    scanf("%d",&N),ga(N,A),G.CLR(N*2+3,2*N,2*N+1),G.RST();
    G.ade(2*N,2*N+2,4,0);
    F(N)G.ade(2*N+2,i,1,0),G.ade(i,N+i,1,-1),G.ade(N+i,2*N+1,1,0);
    F(N){
        H=4;FT(i+1,N&&H)if(A[i]+1==A[k])G.ade(N+i,k,1,0),--H;
        H=4;FT(i+1,N&&H)if(A[i]-1==A[k])G.ade(N+i,k,1,0),--H;
        H=4;FT(i+1,N&&H)if(A[i]%7==A[k]%7)G.ade(N+i,k,1,0),--H;
    }
    printf("%d\n",-G.mf().bb);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
template<class FW=ll,class CO=ll>
struct MCMF{
    struct eg{int t;FW C;CO W;int x;};
    const FW IF=1e9;
    const CO IC=1e17;
    int n,t,S,T;
    FW s;
    CO P;
    vector<int> l,v;
    vector<CO> H;
    vector<eg> G;
    MCMF(int n):n(n),l(n,-1),v(n,0),H(n,0){t=s=P=0,G.clear();}
    int ade(int F,int T,FW C,CO W){
        return G.PB({T,C,W,l[F]}),l[F]=t++,G.PB({F,0,-W,l[T]}),l[T]=t++,t-2;
    }
    pair<FW,CO> mf(int a,int b){
        S=a,T=b,SPFA();
        do do F(n)v[i]=0;while(FLW(S,IF));while(ML());
        return {s,P};
    }
    void SPFA(){
        F(n)H[i]=IC;
        priority_queue<pair<CO,ll>>Q;
        Q.push({H[S]=0,S});
        while (!Q.empty()) {
            ll x=Q.top().bb;
            CO d=-Q.top().aa;
            Q.pop();
            if(H[x]!=d)continue;
            for(int i=l[x];~i;i=G[i].x)
                if(G[i].C>0&&H[G[i].t]>d+G[i].W)
                    Q.push({-(H[G[i].t]=d+G[i].W),G[i].t});
        }
        F(n)H[i]=H[T]-H[i];
    }
    FW FLW(ll x,FW f){
        if(x==T)return P+=H[S]*f,s+=f,f;
        FW t=f;
        v[x]=1;
        for(int i=l[x];~i;i=G[i].x)
            if(G[i].C&&!v[G[i].t]&&H[G[i].t]+G[i].W==H[x]){
                FW a=FLW(G[i].t,min(t,G[i].C));
                G[i].C-=a,G[i^1].C+=a,t-=a;
                if(!t)break;
            }
        return f-t;
    }
    bool ML(){
        CO d=IC;
        F(n)if(v[i])for(int j=l[i];~j;j=G[j].x)
            if(G[j].C&&!v[G[j].t])d=min(d,H[G[j].t]+G[j].W-H[i]);

        if(d==IC)return 0;
        F(n)if(v[i])H[i]+=d;
        return 1;
    }
};
#define MX (3006)
int N,A[MX],H;
int main(void){
    scanf("%d",&N),ga(N,A);
    MCMF<ll,ll> G(2*N+3);
    G.ade(2*N,2*N+2,4,0);
    F(N)G.ade(2*N+2,i,1,0),G.ade(i,N+i,1,-1),G.ade(N+i,2*N+1,1,0);
    F(N){
        H=4;FT(i+1,N&&H)if(A[i]+1==A[k])G.ade(N+i,k,1,0),--H;
        H=4;FT(i+1,N&&H)if(A[i]-1==A[k])G.ade(N+i,k,1,0),--H;
        H=4;FT(i+1,N&&H)if(A[i]%7==A[k]%7)G.ade(N+i,k,1,0),--H;
    }
    printf("%lld\n",-G.mf(2*N,2*N+1).bb);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define PB push_back
#define ZERO (1e-10)
#define INF int(1e9+1)
#define CL(A,I) (memset(A,I,sizeof(A)))
#define DEB printf("DEB!\n");
#define D(X) cout<<"  "<<#X": "<<X<<endl;
#define EQ(A,B) (A+ZERO>B&&A-ZERO<B)
typedef long long ll;
typedef pair<ll,ll> pll;
typedef vector<int> vi;
typedef pair<int,int> ii;
typedef vector<ii> vii;
#define IN(n) int n;scanf("%d",&n);
#define FOR(i, m, n) for (int i(m); i < n; i++)
#define F(n) FOR(i,0,n)
#define FF(n) FOR(j,0,n)
#define FT(m, n) FOR(k, m, n)
#define aa first
#define bb second
void ga(int N,int *A){F(N)scanf("%d",A+i);}
template<class FW=ll,class CO=ll>
struct MCMF{
    struct eg{int t;FW C;CO W;int x;};
    const FW IF=1e9;
    const CO IC=1e17;
    int n,t,S,T;
    FW s;
    CO P;
    vector<int> l,v;
    vector<CO> H;
    vector<eg> G;
    MCMF(int n):n(n),l(n,-1),v(n,0),H(n,0){t=s=P=0,G.clear();}
    int ade(int F,int T,FW C,CO W){
        return G.PB({T,C,W,l[F]}),l[F]=t++,G.PB({F,0,-W,l[T]}),l[T]=t++,t-2;
    }
    pair<FW,CO> mf(int a,int b){
        S=a,T=b,SPFA();
        do do F(n)v[i]=0;while(FLW(S,IF));while(ML());
        return {s,P};
    }
    void SPFA(){
        F(n)H[i]=IC;
        priority_queue<pair<CO,ll>>Q;
        Q.push({H[S]=0,S});
        while (!Q.empty()) {
            ll x=Q.top().bb;
            CO d=-Q.top().aa;
            Q.pop();
            if(H[x]!=d)continue;
            for(int i=l[x];~i;i=G[i].x)
                if(G[i].C>0&&H[G[i].t]>d+G[i].W)
                    Q.push({-(H[G[i].t]=d+G[i].W),G[i].t});
        }
        F(n)H[i]=H[T]-H[i];
    }
    FW FLW(ll x,FW f){
        if(x==T)return P+=H[S]*f,s+=f,f;
        FW t=f;
        v[x]=1;
        for(int i=l[x];~i;i=G[i].x)
            if(G[i].C&&!v[G[i].t]&&H[G[i].t]+G[i].W==H[x]){
                FW a=FLW(G[i].t,min(t,G[i].C));
                G[i].C-=a,G[i^1].C+=a,t-=a;
                if(!t)break;
            }
        return f-t;
    }
    bool ML(){
        CO d=IC;
        F(n)if(v[i])for(int j=l[i];~j;j=G[j].x)
            if(G[j].C&&!v[G[j].t])d=min(d,H[G[j].t]+G[j].W-H[i]);

        if(d==IC)return 0;
        F(n)if(v[i])H[i]+=d;
        return 1;
    }
};
#define MX (6006)
int N,A[MX];
int main(void){
    scanf("%d",&N),ga(N,A);
    MCMF<ll,ll> G(2*N+3);
    G.ade(2*N,2*N+2,4,0);
    F(N)G.ade(2*N+2,i,1,-1),G.ade(i,N+i,1,0),G.ade(N+i,2*N+1,1,0);
    F(N)FT(i+1,N)if(A[i]+1==A[k]||A[i]%7==A[k]%7)G.ade(N+i,k,1,-1);
    printf("%lld\n",-G.mf(2*N,2*N+1).bb);
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(abs(arr[i]-arr[j])==1 || arr[i]%7==arr[j]%7){
                mcmf.add(1+n+i, 1+j, 1, 0);
            }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 5, false).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]], n+2, 0);

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, 0).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, true).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]] != -1)
            mcmf.add(1+i, 1+last1[arr[i]], n+2, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+i, 1+last2[arr[i]%7], n+2, 0);

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, 0).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
            if(abs(arr[i]-arr[j])==1 || arr[i]%7==arr[j]%7){
                mcmf.add(1+n+i, 1+j, 1, 0);
            }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, true).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]] != -1)
            mcmf.add(1+i, 1+last1[arr[i]], n+2, 0);

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, 0).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, 0).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
bool done[100002];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    for(int i=1;i<=n;i++){

        for(int j=i+1;j<=n;j++)
            done[arr[j]] = false;

        for(int j=i+1;j<=n;j++){
            if(done[arr[j]])    continue;
            done[arr[j]] = true;
            if(abs(arr[i]-arr[j])==1 || arr[i]%7==arr[j]%7){
                mcmf.add(1+n+i, 1+j, 1, 0);
            }
        }
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, 0).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
bool done[100002];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    for(int i=1;i<=n;i++){

        for(int j=i+1;j<=n;j++)
            done[arr[j]] = false;

        for(int j=i+1;j<=n;j++){
            if(done[arr[j]])    continue;
            done[arr[j]] = true;
            if(abs(arr[i]-arr[j])==1 || arr[i]%7==arr[j]%7){
                mcmf.add(1+n+i, 1+j, 1, 0);
            }
        }
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 5, true).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
int last1[100005], last2[10];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    memset(last1, -1, sizeof(last1));
    memset(last2, -1, sizeof(last2));
    for(int i=n;i>=1;i--){

        if(last1[arr[i]] != -1)
            mcmf.add(1+i, 1+last1[arr[i]], n+2, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+i, 1+last2[arr[i]%7], n+2, 0);

        if(last1[arr[i]-1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]-1], 1, 0);
        if(last1[arr[i]+1] != -1)
            mcmf.add(1+n+i, 1+last1[arr[i]+1], 1, 0);
        if(last2[arr[i]%7] != -1)
            mcmf.add(1+n+i, 1+last2[arr[i]%7], 1, 0);

        last1[arr[i]] = i;
        last2[arr[i]%7] = i;
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 4, true).ff;
    return 0;
}


//satyaki3794
#include <bits/stdc++.h>
#define ff first
#define ss second
#define pb push_back
#define LEFT(n) (2*(n))
#define RIGHT(n) (2*(n)+1)

using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
typedef pair<int, ii> iii;

ll pwr(ll base, ll p, ll mod){
ll ans = 1;while(p){if(p&1)ans=(ans*base)%mod;base=(base*base)%mod;p/=2;}return ans;
}

ll gcd(ll a, ll b){
    if(b == 0)  return a;
    return gcd(b, a%b);
}

const int InfCost=3002;
struct MinimumCostMaximumFlow {
    typedef int Index; typedef int Flow; typedef int Cost;
    static const Flow InfCapacity = 10;
    struct Edge {
        Index to; Index rev;
        Flow capacity; Cost cost;
    };
    vector<vector<Edge> > g;
    void init(Index n) { g.assign(n, vector<Edge>()); }
    void add(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
// cout<<"added edge "<<i<<" "<<j<<" "<<capacity<<" "<<cost<<"\n";
        Edge e, f; e.to = j, f.to = i; e.capacity = capacity, f.capacity = 0; e.cost = cost, f.cost = -cost;
        g[i].push_back(e); g[j].push_back(f);
        g[i].back().rev = (Index)g[j].size() - 1; g[j].back().rev = (Index)g[i].size() - 1;
    }
    void addB(Index i, Index j, Flow capacity = InfCapacity, Cost cost = Cost()) {
        add(i, j, capacity, cost);
        add(j, i, capacity, cost);
    }
    pair<Cost,Flow> minimumCostMaximumFlow(Index s, Index t, Flow f = InfCapacity, bool bellmanFord = false) {
        int n = g.size();
        vector<Cost> dist(n); vector<Index> prev(n); vector<Index> prevEdge(n);
        pair<Cost,Flow> total = make_pair(0, 0);
        vector<Cost> potential(n);
        while(f > 0) {
            fill(dist.begin(), dist.end(), InfCost);
            if(bellmanFord || total.second == 0) {
                dist[s] = 0;
                for(int k=0;k<n;k++){
                    bool update = false;
                    for(int i=0;i<n;i++)
                        if(dist[i] != InfCost)
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost;
                        if(dist[j] > d ) {  //èª¤å·®â�¦
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            update = true;
                        }
                    }
                    if(!update) break;
                }
            }else {
                vector<bool> vis(n);
                priority_queue<pair<Cost,Index> > q;
                q.push(make_pair(-0, s)); dist[s] = 0;
                while(!q.empty()) {
                    Index i = q.top().second; q.pop();
                    if(vis[i]) continue;
                    vis[i] = true;
                    for(Index ei = 0; ei < (Index)g[i].size(); ei ++) {
                        const Edge &e = g[i][ei];
                        if(e.capacity <= 0) continue;
                        Index j = e.to; Cost d = dist[i] + e.cost + potential[i] - potential[j];
                        if(d < dist[i])  d = dist[i];    //èª¤å·®â�¦
                        if(dist[j] > d) {
                            dist[j] = d; prev[j] = i; prevEdge[j] = ei;
                            q.push(make_pair(-d, j));
                        }
                    }
                }
            }
            if(dist[t] == InfCost) break;
            if(!bellmanFord) for(Index i = 0; i < n; i ++) potential[i] += dist[i];
            Flow d = f; Cost distt = 0;
            for(Index v = t; v != s; ) {
                Index u = prev[v]; const Edge &e = g[u][prevEdge[v]];
                d = min(d, e.capacity); distt += e.cost; v = u;
            }
            f -= d; total.first += d * distt; total.second += d;
            for(Index v = t; v != s; v = prev[v]) {
                Edge &e = g[prev[v]][prevEdge[v]];
                e.capacity -= d; g[e.to][e.rev].capacity += d;
            }
        }
        return total;
    }
};

int n, arr[3002];
bool done[100002];

int main(){

    // ios_base::sync_with_stdio(0);
    // cin.tie(0);

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

    MinimumCostMaximumFlow mcmf;
    mcmf.init(1+1+2*n+1);
    int src = 0, sink = 1+1+2*n;

    mcmf.add(src, 1, 4, 0);
    for(int i=1;i<=n;i++){
        mcmf.add(1+i, 1+n+i, 1, -1);
        mcmf.add(1, 1+i, 1, 0);
        mcmf.add(1+n+i, sink, 1, 0);
    }

    for(int i=1;i<=n;i++){

        for(int j=i+1;j<=n;j++)
            done[arr[j]] = false;

        for(int j=i+1;j<=n;j++){
            if(done[arr[j]])    continue;
            done[arr[j]] = true;
            if(abs(arr[i]-arr[j])==1 || arr[i]%7==arr[j]%7){
                mcmf.add(1+n+i, 1+j, 1, 0);
            }
        }
    }

    cout<<-mcmf.minimumCostMaximumFlow(src, sink, 5, 0).ff;
    return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=int(b); i++)
#define loop(k,a) for (int k=(a); ~k; k=link[k])
#define Next(x) ((x++)%maxn)
using namespace std;

const int maxn = 10009, maxm = 1000009, INF = 1e9;
struct edge { int u, v, w, f, c; };
struct flows {
	int n, s, t, limit, a[maxn], d[maxn], inq[maxn], q[maxn];
	int m, head[maxn], link[maxm], p[maxn];
	edge e[maxm];
	void init(int _n, int _limit = 0) {
		n = _n; m = 0; limit = _limit;
		memset(head, -1, sizeof head);
	}
	void addEdge(int u, int v, int c, int w) {
		e[m].u = u; e[m].v = v; e[m].f = 0; e[m].c = c; e[m].w = w;
		link[m] = head[u]; head[u] = m++;
		e[m].u = v; e[m].v = u; e[m].f = 0; e[m].c = 0; e[m].w = -w;
		link[m] = head[v]; head[v] = m++;
	}
	bool SPFA(int s, int t, int &flow, int &cost) {
		int l = 0, r = 0, u;
		memset(d, 0x3f, sizeof d);
		memset(inq, 0, sizeof inq);
		d[s] = 0; q[Next(r)] = s; a[s] = INF;
		while (l < r) {
			u = q[Next(l)]; inq[u] = 0;
			loop (k, head[u])
				if (e[k].f < e[k].c && d[u] + e[k].w < d[e[k].v]) {
					d[e[k].v] = d[u] + e[k].w;
					a[e[k].v] = min(a[u], e[k].c - e[k].f);
					p[e[k].v] = k;
					if (!inq[e[k].v]) {
						q[Next(r)] = e[k].v; inq[e[k].v] = 1;
					}
				}
		}
		if (d[t] >= INF) return false;
		flow += a[t]; cost += a[t] * d[t]; u = t;
		while (u != s) {
			e[p[u]].f += a[t]; e[p[u]^1].f -= a[t];
			u = e[p[u]].u;
		}
		return true;
	}
	int MinCost(int s, int t) {
		int flow = 0, cost = 0;
		while (SPFA(s, t, flow, cost));
		if (flow < limit) return -1;
		return cost;
	}
} G;
int n, S0, S, T, a[maxn];

int main() {
	scanf("%d", &n);
	rep (i, 1, n) scanf("%d", &a[i]);
	S0 = 2 * n + 1; S = S0 + 1;
	T = S + 1; G.init(T);
	G.addEdge(S0, S, 4, 0);
	rep (i, 1, n) {
		G.addEdge(S, i, 1, 0);
		G.addEdge(n+i, T, 1, 0);
		G.addEdge(i, i+n, 1, -1);
	}
	rep (i, 2, n) {
		for (int j=i-1; j; j--)
			if (a[i] % 7 == a[j] % 7) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
		for (int j=i-1; j; j--)
			if (a[j] == a[i] + 1) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
		for (int j=i-1; j; j--)
			if (a[j] == a[i] - 1) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
	}
	printf("%d\n", -G.MinCost(S0, T));
	return 0;
}


#include<bits/stdc++.h>
#define rep(i,a,b) for (int i=(a); i<=int(b); i++)
#define loop(k,a) for (int k=(a); ~k; k=link[k])
#define Next(x) ((x++)%maxn)
using namespace std;

const int maxn = 10009, maxm = 1000009, INF = 1e9;
struct edge { int u, v, w, f, c; };
struct flows {
	int n, s, t, limit, a[maxn], d[maxn], inq[maxn], q[maxn];
	int m, head[maxn], link[maxm], p[maxn];
	edge e[maxm];
	void init(int _n, int _limit = 0) {
		n = _n; m = 0; limit = _limit;
		memset(head, -1, sizeof head);
	}
	void addEdge(int u, int v, int c, int w) {
		e[m].u = u; e[m].v = v; e[m].f = 0; e[m].c = c; e[m].w = w;
		link[m] = head[u]; head[u] = m++;
		e[m].u = v; e[m].v = u; e[m].f = 0; e[m].c = 0; e[m].w = -w;
		link[m] = head[v]; head[v] = m++;
	}
	bool SPFA(int s, int t, int &flow, int &cost) {
		int l = 0, r = 0, u;
		memset(d, 0x3f, sizeof d);
		memset(inq, 0, sizeof inq);
		d[s] = 0; q[Next(r)] = s; a[s] = INF;
		while (l < r) {
			u = q[Next(l)]; inq[u] = 0;
			loop (k, head[u])
				if (e[k].f < e[k].c && d[u] + e[k].w < d[e[k].v]) {
					d[e[k].v] = d[u] + e[k].w;
					a[e[k].v] = min(a[u], e[k].c - e[k].f);
					p[e[k].v] = k;
					if (!inq[e[k].v]) {
						q[Next(r)] = e[k].v; inq[e[k].v] = 1;
					}
				}
		}
		if (d[t] >= INF) return false;
		flow += a[t]; cost += a[t] * d[t]; u = t;
		while (u != s) {
			e[p[u]].f += a[t]; e[p[u]^1].f -= a[t];
			u = e[p[u]].u;
		}
		return true;
	}
	int MinCost(int s, int t) {
		int flow = 0, cost = 0;
		while (SPFA(s, t, flow, cost));
		if (flow < limit) return -1;
		return cost;
	}
} G;
int n, S0, S, T, a[maxn];

int main() {
	scanf("%d", &n);
	rep (i, 1, n) scanf("%d", &a[i]);
	S0 = 2 * n + 1; S = S0 + 1;
	T = S + 1; G.init(T);
	G.addEdge(S0, S, 4, 0);
	rep (i, 1, n) {
		G.addEdge(S, i, 1, 0); G.addEdge(n+i, T, 1, 0);
		G.addEdge(i, i+n, 1, -1); G.addEdge(i, n+i, INF, 0);
	}
	rep (i, 2, n) {
		for (int j=i-1; j; j--)
			if (a[i] % 7 == a[j] % 7) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
		for (int j=i-1; j; j--)
			if (a[j] == a[i] + 1) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
		for (int j=i-1; j; j--)
			if (a[j] == a[i] - 1) {
				G.addEdge(n+j, i, 1, 0);
				break;
			}
	}
	printf("%d\n", -G.MinCost(S0, T));
	return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
using namespace std;
typedef long long LL;
inline int read()
{
	int x=0;bool f=0;char c=getchar();
	for (;c<'0'||c>'9';c=getchar()) f=c=='-'?1:0;
	for (;c>='0'&&c<='9';c=getchar()) x=x*10+c-'0';
	return f?-x:x;
}
const int N=6005,M=2000005,oo=0x3f3f3f3f;
int n,A[N],S,S2,T,ll=1,to[M],nxt[M],fl[M],co[M],hd[N],ds[N],pr[N],qu[N],ans,pos[100005],pm[7];
bool inq[N];
inline void adde(int u,int v,int w,int c){
	to[++ll]=v,nxt[ll]=hd[u],hd[u]=ll,fl[ll]=w,co[ll]=c;
	to[++ll]=u,nxt[ll]=hd[v],hd[v]=ll,fl[ll]=0,co[ll]=-c;
}

inline bool spfa(){
	memset(ds+1,-1,sizeof(int)*T);
	memset(inq+1,0,sizeof(bool)*T);
	int l=0,r=1;
	ds[S]=0,qu[0]=S,inq[S]=1;
	while (l!=r){
		int u=qu[l++];if (l==N) l=0;
		inq[u]=0;
		for (int i=hd[u],v;i;i=nxt[i])
			if (fl[i]&&ds[v=to[i]]<ds[u]+co[i]){
				ds[v]=ds[u]+co[i],pr[v]=i;
				if (!inq[v]){
					qu[r++]=v,inq[v]=1;
					if (r==N) r=0;
				}
			}
	}
	return ~ds[T];
}

int main()
{
	n=read(),S=2*n+1,S2=S+1,T=S+2;
	for (int i=1;i<=n;i++) A[i]=read();
	adde(S,S2,4,0);
	for (int i=1;i<=n;i++) adde(S2,i,1,0),adde(n+i,T,1,0),adde(i,n+i,1,1),adde(i,i+n,4,0);
	for (int i=1,a,r;i<=n;i++){
		if (a=pos[A[i]-1]) adde(a+n,i,4,0);
		if (a=pos[A[i]+1]) adde(a+n,i,4,0);
		if (a=pm[r=A[i]%7]) adde(a+n,i,4,0);
		pos[A[i]]=i,pm[r]=i;
	}
	while (spfa()){
		int f=oo;
		for (int i=pr[T];i;i=pr[to[i^1]]) f=min(f,fl[i]);
		for (int i=pr[T];i;i=pr[to[i^1]]) fl[i]-=f,fl[i^1]+=f,ans+=f*co[i];
	}
	printf("%d\n",ans);
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MX=3005,MV=6005,ME=4507550;

int N,a[MX],S,T,u[ME],v[ME],f[ME],c[ME],tot,deg[MV];

struct MinCostMaxFlow
{
    struct edge
    {
        int to,c,f;
        edge *rev;
        edge(){}
        edge(int t,int c,int f,edge *r):to(t),c(c),f(f),rev(r){}
    }*E[MV],Pool[ME<<1],*pre[MV];
    int S,T,dis[MV],p[MV];
    char vis[MV];

    void build()
    {
        E[1]=Pool;
        for(int i=1;i<=T;i++)E[i+1]=E[i]+deg[i];
        for(int i=1;i<=tot;i++)
        {
            --deg[u[i]],--deg[v[i]];
            E[u[i]][deg[u[i]]]=edge(v[i],c[i],f[i],E[v[i]]+deg[v[i]]);
            E[v[i]][deg[v[i]]]=edge(u[i],-c[i],0,E[u[i]]+deg[u[i]]);
        }
    }
    void SPFA()
    {
        deque<int> q;
        memset(p+1,0x3f,sizeof(int)*T);
        p[S]=0,q.push_back(S);
        while(!q.empty())
        {
            int now=q.front();
            q.pop_front(),vis[now]=0;
            for(edge *i=E[now];i!=E[now+1];i++)
                if(i->f&&p[i->to]>p[now]+i->c)
                {
                    p[i->to]=p[now]+i->c;
                    if(!vis[i->to])
                    {
                        vis[i->to]=1;
                        if(!q.size()||p[q.front()]<p[i->to])q.push_back(i->to);
                        else q.push_front(i->to);
                    }
                }
        }
    }
    inline bool Dijkstra();
    int solve();
}Edmond_Karp;
inline bool MinCostMaxFlow::Dijkstra()
{
    using pii=pair<int,int>;
    priority_queue<pii,vector<pii>,greater<pii> > q;
    memset(dis+1,0x3f,sizeof(int)*T);
    memset(vis+1,0,sizeof(char)*T);
    q.push(make_pair(dis[S]=0,S));
    while(!q.empty())
    {
        int now=q.top().second,tmp;
        q.pop();
        if(vis[now])continue;
        vis[now]=1;
        for(edge *i=E[now];i!=E[now+1];i++)
        {
            if(i->f&&dis[i->to]>(tmp=dis[now]+i->c+p[now]-p[i->to]))
                q.push(make_pair(dis[i->to]=tmp,i->to)),pre[i->to]=i;
        }
    }
    return dis[T]<0x3f3f3f3f;
}
inline int MinCostMaxFlow::solve()
{
    int ans=0;
    SPFA();
    for(int i=0;i<4;i++)
    {
        Dijkstra();
        ans+=dis[T]+p[T];
        for(int i=T;i!=S;i=pre[i]->rev->to)
            pre[i]->f--,pre[i]->rev->f++;
        for(int i=1;i<=T;i++)p[i]+=dis[i];
    }
    return ans;
}

void add(int _u,int _v,int _f,int _c)
{
    ++tot,deg[_u]++,deg[_v]++;
    u[tot]=_u,v[tot]=_v,f[tot]=_f,c[tot]=_c;
}

int main()
{
    ios::sync_with_stdio(0);
    cin>>N;
    for(int i=1;i<=N;i++)cin>>a[i];
    S=N*2+1,T=S+1;
    Edmond_Karp.S=S,Edmond_Karp.T=T;
    for(int i=1;i<=N;i++)add(i,i+N,1,-1);
    for(int i=1;i<=N;i++)add(S,i,1,0);
    for(int i=1;i<=N;i++)add(i+N,T,1,0);
    for(int i=2;i<=N;i++)for(int j=1;j<i;j++)
        if(abs(a[i]-a[j])==1||(a[i]-a[j])%7==0)
            add(j+N,i,1,0);
    Edmond_Karp.build();
    cout<<-Edmond_Karp.solve()<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int MX=3005,MV=6005,ME=4507550;

int N,a[MX],S,T,S0,u[ME],v[ME],f[ME],c[ME],tot,deg[MV];

struct MinCostMaxFlow
{
    struct edge
    {
        int to,c,f;
        edge *rev;
        edge(){}
        edge(int t,int c,int f,edge *r):to(t),c(c),f(f),rev(r){}
    }*E[MV],Pool[ME<<1],*pre[MV];
    int S,T,dis[MV],p[MV];
    char vis[MV];

    void build()
    {
        E[1]=Pool;
        for(int i=1;i<=T;i++)E[i+1]=E[i]+deg[i];
        for(int i=1;i<=tot;i++)
        {
            --deg[u[i]],--deg[v[i]];
            E[u[i]][deg[u[i]]]=edge(v[i],c[i],f[i],E[v[i]]+deg[v[i]]);
            E[v[i]][deg[v[i]]]=edge(u[i],-c[i],0,E[u[i]]+deg[u[i]]);
        }
    }
    void SPFA()
    {
        queue<int> q;
        memset(vis+1,0,sizeof(char)*T);
        dis[S]=0,q.push(S);
        while(!q.empty())
        {
            int now=q.front();
            q.pop(),vis[now]=0;
            for(edge *i=E[now];i!=E[now+1];i++)
                if(i->f&&p[i->to]>p[now]+i->c)
                {
                    p[i->to]=p[now]+i->c;
                    if(!vis[i->to])q.push(i->to),vis[i->to]=1;
                }
        }
    }
    inline bool Dijkstra();
    int solve();
}Edmond_Karp;
inline bool MinCostMaxFlow::Dijkstra()
{
    using pii=pair<int,int>;
    priority_queue<pii,vector<pii>,greater<pii> > q;
    memset(dis+1,0x3f,sizeof(int)*T);
    memset(vis+1,0,sizeof(char)*T);
    q.push(make_pair(dis[S]=0,S));
    while(!q.empty())
    {
        int now=q.top().second,tmp;
        q.pop();
        if(vis[now])continue;
        vis[now]=1;
        for(edge *i=E[now];i!=E[now+1];i++)
            if(i->f&&dis[i->to]>(tmp=dis[now]+i->c+p[now]-p[i->to]))
                q.push(make_pair(dis[i->to]=tmp,i->to)),pre[i->to]=i;
    }
    return dis[T]<0x3f3f3f3f;
}
inline int MinCostMaxFlow::solve()
{
    int ans=0;
    SPFA();
    while(Dijkstra())
    {
        ans+=dis[T]+p[T];
        for(int i=T;i!=S;i=pre[i]->rev->to)pre[i]->f--,pre[i]->rev->f++;
        for(int i=1;i<=T;i++)p[i]+=dis[i];
    }
    return ans;
}

void add(int _u,int _v,int _f,int _c)
{
    ++tot,deg[_u]++,deg[_v]++;
    u[tot]=_u,v[tot]=_v,f[tot]=_f,c[tot]=_c;
}

int main()
{
    ios::sync_with_stdio(0);
    cin>>N;
    for(int i=1;i<=N;i++)cin>>a[i];
    S0=N*2+1,S=S0+1,T=S+1;
    Edmond_Karp.S=S,Edmond_Karp.T=T;
    add(S,S0,4,0);
    for(int i=1;i<=N;i++)add(i,i+N,1,-1);
    for(int i=1;i<=N;i++)add(S0,i,1,0);
    for(int i=1;i<=N;i++)add(i+N,T,1,0);
    for(int i=2;i<=N;i++)for(int j=1;j<i;j++)
        if(abs(a[i]-a[j])==1||(a[i]-a[j])%7==0)
            add(j+N,i,1,0);
    Edmond_Karp.build();
    cout<<-Edmond_Karp.solve()<<endl;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int main() {
	int x, y;
	long a;
	cin >> x >>a;
	vector<long> vecx;
	vector<long> vecy;
	long long xymin;
	for (int i = 0; i < x; i++) {
		cin >> a;
		vecx.push_back(a);
	}
	cin >> y >> a;
	for (int i = 0; i < y; i++) {
		cin >> a;
		vecy.push_back(a);
	}
	xymin = min(vecx[0], vecy[0]);
	for (int i = 0; i < x; i++) {
		vecx[i] -= xymin;
	}
	for (int i = 0; i < y; i++) {
		vecy[i] -= xymin;
	}
	long long xx = 1;
	map<long long, long long> m1;
	map<long long, long long> m2;
	long long max1 = 0, max2 = 0;
	for (long long xx = 1; xx < 1000000000; xx *= 2) {
		for (long i : vecx) {
			if (i % (2 * xx) == 0) {
				m1[xx]++;
				max1 = max(max1, m1[xx]);
			}
			if ((i + xx) % (2 * xx) == 0){
				m2[xx]++;
				max2 = max(max2, m2[xx]);
			}
		}
		for (long i : vecy) {
			if (i % (2 * xx) == 0) {
				m2[xx]++;
				max2 = max(max2, m2[xx]);
			}
			if ((i + xx) % (2 * xx) == 0){
				m1[xx]++;
				max1 = max(max1, m1[xx]);
			}
		}
	}
	long long ot = max(max1,max2);
	cout << ot;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

int main() {
	int x, y;
	long a;
	cin >> x >>a;
	vector<long> vecx;
	vector<long> vecy;
	long long xymin;
	for (int i = 0; i < x; i++) {
		cin >> a;
		vecx.push_back(a);
	}
	cin >> y >> a;
	for (int i = 0; i < y; i++) {
		cin >> a;
		vecy.push_back(a);
	}
	xymin = min(vecx[0], vecy[0]);
	for (int i = 0; i < x; i++) {
		vecx[i] -= xymin;
	}
	for (int i = 0; i < y; i++) {
		vecy[i] -= xymin;
	}
	long long xx = 1;
	map<long long, long long> m2;
	long long max1 = 0, max2 = 0;
	for (long long xx = 1; xx < 10000000000; xx *= 2) {
		map<long long, long long> m1;
		long long m = xx / 2;
		for (long i : vecx) {
			m1[i & (2 * m-1)]++;
			//m2[(i + xx) & (2 * m - 1)]++;
		}
		for (long i : vecy) {
			//m2[i & (2 * m-1)]++;
			m1[(i + m) & (2 * m-1)]++;
		}
		for (auto i : m1) {
			max1 = max(max1, i.second);
		}

	}

	//long long ot = max(max1,max2);
	cout << max1;
}