/*
  author            :  _jzp,
  date              : 2020-3-3
  problemID         : CF 1305 C
*/

#include "algorithm"
#include "bits/stl_pair.h"
#include "ctype.h"
#include "functional"
#include "iostream"
#include "limits.h"
#include "map"
#include "math.h"
#include "queue"
#include "stdio.h"
#include "set"
#include "vector"
#include "stdlib.h"
#include "string.h"
#include "string"
#include "time.h"
#include "unordered_map"

#define Rep(a, b, c) for (register int a = b; a <= c; ++ a)
#define Rep_s(a, s) for (register int a = 0; s[a]; ++ a)
#define Dep(a, b, c) for (register int a = b; a >= c; -- a)

#define DEBUG
#define CODEFORCES
// #define ONLINE_JUDGE

#ifndef CODEFORCES
    #include "bits/extc++.h"
#endif

namespace IO {
    static char inBuf[32768], *inNow = inBuf, *lenBuf = inBuf;
    inline void gc (char&);
    inline bool gs (char*);
    template <class T > inline bool read (T&);

    static char outBuf[32768], *outNow = outBuf;
    inline void flush ();
    inline void pc (char);
    inline void ps (const char*);
    template < class T > inline void print (T);
    template < class T > inline void println (T);
    template < class T > inline void printsp (int);
};

inline void IO :: gc (char &ch) {
    ch = ((inNow == lenBuf) && (lenBuf = ((inNow = inBuf) + fread (inBuf, 1, sizeof(inBuf), stdin)), inNow == lenBuf)? EOF: *(inNow ++));
}
inline bool IO :: gs (char* s) {
    while (gc (s[0]), isspace (s[0]) && ~s[0])
        ;
    if (!(~s[0]))
        return 0;
    int len = 0;
    while (!isspace (s[len]) && ~s[len])
        gc (s[++ len]);
    s[len] = 0;
    return 1;
}
template < class T >
inline bool IO :: read (T &x) {
    x = 0;
    bool y = 1;
    char ch;
    gc (ch);
    if (!(~ch))
        return 0;
    while (!isdigit (ch))
        y &= !!(ch ^ (char)'-'), gc (ch);
    while (isdigit (ch))
        x = (x << 3) + (x << 1) + (ch & 15), gc (ch);
    x = y? x: -x;
    return 1;
}

inline void IO :: flush () {
    fwrite (outBuf, 1, outNow - outBuf, stdout);
    outNow = outBuf;
    fflush (stdout);
}
inline void IO :: pc (char ch) {
    *(outNow ++) = ch;
    if (outNow - outBuf == sizeof(outBuf))
        flush ();
}
inline void IO :: ps (const char* s) {
    while (*s)
        pc (*(s ++));
}
template < class T >
inline void IO :: print(T x) {
    short num[35], *numNow = num;
    if (x <= 0)
        pc (x? (char)'-': (char)'0'), x = -x;
    while (x)
        *(numNow ++) = x % 10, x /= 10;
    while (numNow != num)
        pc ((char)(48 | *(-- numNow)));
}
template < class T >
inline void IO :: println(T x) {
    print(x), pc(10);
}
template < class T >
inline void IO :: printsp(T x) {
    print(x), pc(32);
}

using IO :: gc;
using IO :: pc;
using IO :: gs;
using IO :: ps;
using IO :: read;
using IO :: print;
using IO :: println;
using IO :: printsp;

namespace Quote {
    template < class T >
    inline T Max (T a, T b) {
        return b < a? a: b;
    }
    template < class T >
    inline T Min (T a, T b) {
        return a < b? a: b;
    }
    template < class T >
    inline T Abs (T x) {
        return x < 0? -x: x;
    }

    struct pair_hash {
        template < class T1, class T2 >
        std :: size_t operator () (const std :: pair < T1, T2 > &x) const {
            return (((std :: hash < T1 > () (x.first) << 10) ^ 0x9e3779b9) ^ (std :: hash < T2 > () (x.second)) ^ 0x4c5968ac);
        }
    };
};

namespace myPrepare {
    void pre() {

    }

};

namespace mySolve {

    // #define SUBTEST

    int n, m;
    int a[100010], num[1010];
    int ans = 1ll;

    inline void main () {
        read(n), read(m);
        if (n >= m) {
            println(0);
            return;
        }
        Rep (i, 1, n)
            read(a[i]), ++ num[a[i] % m];
        // Rep (i, 0, m - 1)
        //     if (num[i] > 1) {
        //         ps("0");
        //         return;
        //     }
        Rep (i, 1, n)
            Rep (j, i + 1, n)
                ans = ans * ((a[i] % m - a[j] % m + m) % m) % m;
        println(ans);
    }
};

namespace myMain {
    inline void solve () {
        int T = 1;
        #ifdef SUBTEST
            read (T);
        #endif
        myPrepare :: pre();
        while (T --) {
            mySolve :: main ();
        }
    }
    inline void main () {
        solve ();
        IO :: flush ();
    }
};

main() {

    #ifndef ONLINE_JUDGE
        freopen ("in.txt", "r", stdin);
        freopen ("out.txt", "w", stdout);
    #endif

    myMain :: main ();
    return 0;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
ll cnt[M], tmp[M], sum[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = (a[i + 1] - a[i]) % m;
	}

	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] = 1;
		for (int j = 0;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
		for (int j = 0;j < m;j++) {
			sum[j] += cnt[j];
		}
		//for (int j = 1;j < m;j++) cout << j << ':' << sum[j] << endl;
	}

	int ans = 1;
	for (int i = 0;i < m;i++) {
		ans *= qpow(i, sum[i], m);
		ans %= m;
	}
	cout << ans << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
int cnt[M], tmp[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = a[i + 1] - a[i];
	}

	memset(cnt, 0, sizeof cnt);
	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] += 1;
		for (int j = 1;j < m;j++) {
			tmp[j] += cnt[j];
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		//cout << i << ' ' << cnt[i] << endl;
		ans *= qpow(i, cnt[i], m);
		ans %= m;
	}
	cout << ans << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
int cnt[M], tmp[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = a[i + 1] - a[i];
	}

	memset(cnt, 0, sizeof cnt);
	for (int i = 1;i < n;i++) {
		memcpy(tmp, cnt, sizeof cnt);
		tmp[a[i] % m] += 1;
		for (int j = 1;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		//cout << i << ' ' << cnt[i] << endl;
		ans *= qpow(i, cnt[i], m);
		ans %= m;
	}
	cout << ans << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
int cnt[M], tmp[M], sum[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = a[i + 1] - a[i];
	}

	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] = 1;
		for (int j = 1;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
		for (int j = 1;j < m;j++) {
			sum[j] += cnt[j];
		}
		//for (int j = 1;j < m;j++) cout << j << ':' << sum[j] << endl;
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		ans *= qpow(i, sum[i] % (m - 1), m);
		ans %= m;
	}
	cout << ans << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
int cnt[M], tmp[M], sum[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = a[i + 1] - a[i];
	}

	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] = 1;
		for (int j = 1;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
		for (int j = 1;j < m;j++) {
			sum[j] += cnt[j];
			sum[j] %= m - 1;
		}
		//for (int j = 1;j < m;j++) cout << j << ':' << sum[j] << endl;
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		ans *= qpow(i, sum[i] % (m - 1), m);
		ans %= m;
	}
	cout << ((m > 1) ? ans : 0) << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
ll cnt[M], tmp[M], sum[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = (a[i + 1] - a[i]) % m;
	}

	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] = 1;
		for (int j = 1;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
		for (int j = 1;j < m;j++) {
			sum[j] += cnt[j];
		}
		//for (int j = 1;j < m;j++) cout << j << ':' << sum[j] << endl;
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		ans *= qpow(i, sum[i], m);
		ans %= m;
	}
	cout << ((m > 1) ? ans : 0) << endl;
}


#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstring>
#include <cmath>
#include <cstdio>
#define all(v) (v).begin(), (v).end()
#define pii pair<int, int>
#define pll pair<ll, ll>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define test cerr << '!' << endl;
using namespace std;

typedef long long ll;
typedef unsigned long long ull;

int main0 ();
int main () {
	#ifndef ONLINE_JUDGE
		freopen("C:\\Users\\98497\\Desktop\\code\\file.in", "r", stdin);
	#endif
	ios::sync_with_stdio(false);
	// clock_t start,end;
	// start = clock();
	main0();
	// end = clock();
	// cout << (end - start) << endl;
	#ifndef ONLINE_JUDGE
		fclose(stdin);
	#endif
	return 0;
}

const int INF = 0x3f3f3f3f;
const int N = 2e5 + 5;
const int M = 1e3 + 5;
const int mod = 1e9 + 7;
const double eps = 1e-5;
const double Pi = acos(-1.0);

int a[N];
int cnt[M], tmp[M], sum[M];

ll qpow (ll n, ll m, ll mod) {
	ll ret = 1;
	while (m) {
		if (m & 1) ret = ret * n % mod;
		n = n * n % mod;
		m >>= 1;
	}
	return ret;
}

int main0 () {
	int n, m;
	cin >> n >> m;
	for (int i = 1;i <= n;i++) {
		cin >> a[i];
	}
	sort(a + 1, a + n + 1);
	for (int i = 1;i < n;i++) {
		a[i] = a[i + 1] - a[i];
	}

	for (int i = 1;i < n;i++) {
		memset(tmp, 0, sizeof tmp);
		tmp[a[i] % m] = 1;
		for (int j = 1;j < m;j++) {
			tmp[(j + a[i]) % m] += cnt[j];
		}
		memcpy(cnt, tmp, sizeof cnt);
		for (int j = 1;j < m;j++) {
			sum[j] += cnt[j];
		}
		//for (int j = 1;j < m;j++) cout << j << ':' << sum[j] << endl;
	}

	int ans = 1;
	for (int i = 1;i < m;i++) {
		ans *= qpow(i, sum[i] % (m - 1), m);
		ans %= m;
	}
	cout << ((m > 1) ? ans : 0) << endl;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 3000000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
//				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
				ll tmp = A[i]%m-A[j]%m;
				tmp = abs(tmp);
				ans = ans*tmp%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300000;
ll m;
int n;
int A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*abs(A[i]%m-A[j]%m))%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m+10)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300000;
int m;
int n;
int A[MAXN];
int main()
{
	scanf("%d%d", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%d", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		int ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*abs(A[i]%m-A[j]%m))%m;
			}
		}
		printf("%d", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 300000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*abs(A[i]%m-A[j]%m))%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 3000000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 3000000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
//				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
				ll tmp = A[i]-A[j];
				tmp = abs(tmp);
				ans = ans*tmp%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int MAXN = 3000000;
ll m;
int n;
ll A[MAXN];
int main()
{
	scanf("%d%lld", &n, &m);
	for (int i = 1; i <= n; i++)
	{
		scanf("%lld", &A[i]);
	}
	if (n > m)
	{
		printf("0");
	}
	else
	{
		ll ans = 1;
		for (int i = 1; i <= n; i++)
		{
			for (int j = i+1; j <= n; j++)
			{
//				ans = ((ans%m)*((A[i]%m-A[j]%m+m)%m))%m;
				tmp = A[i]-A[j];
				tmp = abs(tmp);
				ans = ans*tmp%m;
			}
		}
		printf("%lld", ans);
	}
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

int cnt[1050];
int n,m;
int seq[200050];

int main()
{
	scanf("%d",&n);
	scanf("%d",&m);
	for(int i = 1;i <= n; ++ i)
	{
		scanf("%d",&seq[i]);
		cnt[seq[i] % m] ++;
		if(cnt[seq[i] % m] > 1)
		{
			printf("0\n");
			return 0;
		}
	}
	sort(seq + 1,seq + 1 + n);
	long long as = 1;
	for(int i = 1;i <= n; ++ i)
		for(int j = i + 1;j <= n; ++ j)
			as = as * 1ll * (seq[j] - seq[i]) % m;
	printf("%lld\n",as);
	return 0;
}


//#include<>
#include<bits/stdc++.h>
using namespace std;
int n,m;
int a[500000];
int ABS(int x)
{
	if(x>=0) return x;
	else return -x;
}
int main()
{
//  freopen(" ","r",stdin);
	cin>>n>>m;
	long long int sum=1;
	for(int i=1;i<=n;i++)
	cin>>a[i];
	for(int i=1;i<n;i++)
	for(int j=i+1;j<=n;j++)
	sum*=ABS(a[i]-a[j]);
	cout<<sum%m;
    return 0;
}


#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define INF 1e10+5
#define MAXN 20015
#define MINN -105
typedef long long int LL;
int main()
{
    LL n,m,a[MAXN];
    cin.tie();
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    if(n>m)
    {
        cout<<0<<endl;
        return 0;
    }
    else
    {
        LL ans=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<i;j++)
            {
                ans=(ans*(LL)abs(a[i]-a[j]))%m;
            }
        cout<<ans<<endl;
    }
    return 0;
}


#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
#define INF 1e10+5
#define MAXN 200015
#define MINN -105
typedef long long int LL;
int main()
{
    LL n,m,a[MAXN];
    cin.tie();
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    if(n>m)
    {
        cout<<0<<endl;
        return 0;
    }
    else
    {
        LL ans=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<i;j++)
            {
                ans=(ans*(LL)abs(a[i]-a[j]))%m;
            }
        cout<<ans<<endl;
    }
    return 0;
}


 #include<iostream>
using namespace std;
int n,m,ans=1;
int nn[10000];
int Abs(int a)
{
	if(a>0)
	return a;
	else return -a;
}
void pri()
{

	  for(int i=1;i<=n;i++)
		{
			for(int j=1;j<i;j++)
			{
				int ab=Abs(nn[i]-nn[j])%m;
				ans*=ab;
			}
		}
		ans=ans%m;
		cout<<ans;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		nn[i]=x;
	}
	if(n>=m)
	cout<<0;
	else;
	pri();
 }


#include<iostream>
using namespace std;
int n,m,ans=1;
int nn[10000];
int Abs(int a)
{
	if(a>0)
	return a;
	else return -a;
}
void pri()
{
	  for(int i=1;i<=n;i++)
	  {
	  	nn[i]=nn[i]%m;
	  }
	  for(int i=1;i<=n;i++)
		{
			for(int j=1;j<i;j++)
			{
				int ab=Abs(nn[i]-nn[j]);
				ans*=ab;
			}
		}
		ans=ans%m;
		cout<<ans;
}
int main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		int x;
		cin>>x;
		nn[i]=x;
	}
	if(n>=m)
	cout<<0;
	else;
	pri();
 }


#include<cstdio>
int a[200100],n,m,s=1;
int f(int x)    {return x<0?-x:x;}
inline int r(){
	int o=0;char c=getchar();
	while(c<48||c>57)	c=getchar();
	while(c<58&&c>47)	o=(o<<1)+(o<<3)+(c^48),c=getchar();
	return o;
}
int main(){
    n=r();m=r();
    if(n>m) {putchar(48);return 0;}
    for(int i=0;i<n;++i)    a[i]=r();
    for(int i=1;i<n;++i)
        for(int j=0;j<i;++j)
            s=f(a[i]-a[j])*s%m;
    printf("%d",s);
	return 0;
}


#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;

#define INF 1e10+5
#define MAXN 20005
#define MINN -105
typedef long long int LL;

int main()
{
    int n,m,a[MAXN];
    cin>>n>>m;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    if(n>1000)cout<<0<<endl;
    else
    {
        int ans=1;
        for(int i=2;i<=n;i++)
            for(int j=1;j<i;j++)
            {
                ans=(ans*abs(a[i]-a[j])%m);
            }
        cout<<ans<<endl;
    }

    return 0;
}


#include<bits/stdc++.h>

using namespace std;

inline long long read() {
	long long x = 0, f = 1;
	char c = getchar();
	while (c < '0' || c > '9') {
		if(c == '-') {
			f = -1;
		}
		c = getchar();
	}
	while (c <= '9' && c >= '0') {
		x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
	}
	return x * f;
}

#define Maxn 200002

int n, m;

long long ans = 1, a[Maxn];

int main() {
	n = read(), m = read();
	if(n > m) {
		puts("0");
		return 0;
	}
	for(register int i = 1; i <= n; ++i) {
		a[i] = read();
	}
	for(register int i = 1; i <= n; ++i) {
		for(register int j = i + 1; j <= n; ++j) {
			ans = ans * abs(a[i] - a[j]) % m;
		}
	}
	printf("%lld\n", ans);
	return 0;
}


#include<bits/stdc++.h>
#define For(i,a,b) for(register int i=(a);i<=(b);++i)
#define Rep(i,a,b) for(register int i=(a);i>=(b);--i)
using namespace std;
const int maxn=200050;
int n,m,a[maxn];
unsigned long long ans=1;
int main()
{
    cin>>n>>m;
    For(i,1,n)
		cin>>a[i];
    if(n>m)
    {
        puts("0");
        return 0;
    }
    For(i,1,n-1)
        For(j,i+1,n)
            ans=ans%m*abs(a[i]-a[j])%m;
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef int ll;
int h=1,m;
vector<int>s1;

ll ml(ll t,ll r)
{
   return (1LL*t*r)%m;
}

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

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            ll x=abs(s1[i]-s1[j])%m;

            h=ml(h,x);
        }
    }
    //p(m);

    cout<<h<<"\n";

}


#include<bits/stdc++.h>
using namespace std;
typedef int ll;
int h=1,m;
vector<int>s1;

ll ml(ll t,ll r)
{
   return (1LL*t*r)%m;
}

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

    cin>>n>>m;
    if(n>m)
    {
        cout<<0<<"\n";
        return 0;
    }
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            ll x=abs(s1[i]-s1[j])%m;

            h=ml(h,x);
        }
    }
    //p(m);

    cout<<h<<"\n";

}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
long long h=1;
vector<long long>s1;

void m1(ll t,ll r)
{
    ll g=t%r;
    h=h*g;
    if(h>r)
    {
        h=h%r;
    }

}
void p(ll y)
{
    ll a1=h%y;
    cout<<a1<<"\n";
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    ll n,m;

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j]);
            m1(x,m);
        }
    }
    p(m);

}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
long long h=1,m;
vector<long long>s1;

ll ml(ll t,ll r)
{
   return (1LL*t*r)%m;
}

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

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j])%m;

            h=ml(h,x);
        }
    }
    //p(m);

    cout<<h<<"\n";

}


#include<bits/stdc++.h>
using namespace std;
long long h=1;
vector<long long>s1;

void m1(long long t)
{
    h=h*t;

}
void p(long long y)
{
    long long a1=h%y;
    cout<<a1<<"\n";
}

int main()
{
    long long n,m;

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        long long a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j]);
            m1(x);
        }
    }
    p(m);

}


#include<bits/stdc++.h>
using namespace std;
long long h=1;
vector<long long>s1;

void m1(long long t,long long r)
{
    long long g=t%r;
    h=h*g;

}
void p(long long y)
{
    long long a1=h%y;
    cout<<a1<<"\n";
}

int main()
{
    long long n,m;

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        long long a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j]);
            m1(x,m);
        }
    }
    p(m);

}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
long long h=1;
vector<long long>s1;

void m1(ll t,ll r)
{
    ll g=t%r;
    h=h*g;

}
void p(ll y)
{
    ll a1=h%y;
    cout<<a1<<"\n";
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    ll n,m;

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j]);
            m1(x,m);
        }
    }
    p(m);

}


#include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
long long h=1;
vector<long long>s1;

void m1(ll t,ll r)
{
    ll g=t%r;
    h=(h%r)*g;
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    ll n,m;

    cin>>n>>m;
    for(int i=0;i<n;i++)
    {
        ll a;
        cin>>a;
        s1.push_back(a);
    }
    for(int i=0;i<s1.size();i++)
    {
        for(int j=i+1;j<s1.size();j++)
        {
            long long x=abs(s1[i]-s1[j]);
            m1(x,m);
        }
    }
    //p(m);
    ll px=h%m;
    cout<<px<<"\n";

}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 1e6+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    int flag=0;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            if(m%n==0) {flag==1;break;}
            sum=(sum*(m%n))%n;
        }
        if(flag==1) break;
    }
    if(flag==1) printf("0\n");
    else cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 1e6+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    int t,n,c=0,sum=1;
    int flag=0;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%lld",&a[i]);
    if(t>n) {printf("0\n");return 0;}
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            sum=(sum*(m%n))%n;
        }
    }
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 3e6+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            b[++c]=m%n;
        }
    }
    for(int i=1;i<=c;i++)
        sum=(sum*b[i])%n;
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 2e5+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            b[++c]=m%n;
        }
    }
    for(int i=1;i<=c;i++)
        sum=(sum*b[i])%n;
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 1e6+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    int flag=0;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%lld",&a[i]);
    if(n>m) {printf("0\n");return 0;}
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            sum=(sum*(m%n))%n;
        }
    }
    printf("%lld\n",sum);
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 1e6+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            ll m=fabs(a[i]-a[j]);
            sum=(sum*(m%n))%n;
        }
    }
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
#define sc(t) scanf("%lld",&t)
#define sc(n) scanf("%lld",&n)
#define gt(s) getline(cin,s)
const int maxn = 2e5+10;
const int INF = 0x7777777;
ll a[maxn],b[maxn],c[maxn];
bool book[maxn]={false};
string s;

int main(void)
{
    ll t,n,c=0,sum=1;
    sc(t);
    sc(n);
    for(int i=1;i<=t;i++)
        scanf("%d",&a[i]);
    for(int i=1;i<=t;i++)
    {
        for(int j=i+1;j<=t;j++)
        {
            int m=fabs(a[i]-a[j]);
            b[++c]=m%n;
        }
    }
    for(int i=1;i<=c;i++)
        sum=(sum*b[i])%n;
    cout<<sum<<endl;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
int a[n_max];

inline int mod_abs(int a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  int res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res *= mod_abs(a[i]-a[j], m);

  return res%m;
}

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

  cout << solve() << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
ll a[n_max];

inline ll mod_abs(ll a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  if (n>m)
    return 0;

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  ll res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res = (res * mod_abs(a[i]-a[j],m)) % m;

  return mod_abs(res,m);
}

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

  cout << solve() << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
int a[n_max];

inline int mod_abs(ll a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  if (n>m)
    return 0;

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  ll res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res *= mod_abs(a[i]-a[j],m);

  return mod_abs(res,m);
}

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

  cout << solve() << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
int a[n_max];

inline int mod_abs(ll a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  ll res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res *= (a[i]-a[j]);

  return mod_abs(res,m);
}

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

  cout << solve() << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
int a[n_max];

inline ll mod_abs(ll a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  if (n>m)
    return 0;

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  ll res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res *= mod_abs(a[i]-a[j],m);

  return mod_abs(res,m);
}

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

  cout << solve() << endl;

  return 0;
}


#include <bits/stdc++.h>
using namespace std;
using ll = long long;

constexpr int n_max = 2e5;
constexpr int a_max = 1e9;
ll a[n_max];

inline ll mod_abs(ll a, int m) {
  return a >= 0 ? a%m : (-a)%m;
}

int solve() {

  int n, m;
  cin >> n; cin >> m;
  if (n>m)
    return 0;

  for (int i = 0; i < n; ++i) {
    cin >> a[i];
  }

  ll res = 1;
  for (int i = 0; i < n; ++i)
    for (int j = i+1; j < n; ++j)
      res = (res*mod_abs(a[i]-a[j],m)%m;

  return mod_abs(res,m);
}

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

  cout << solve() << endl;

  return 0;
}


#include<bits/stdc++.h>

using namespace std;

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

long long a[200005],ans=1;

bool cmp(long long a,long long b)
{
	return a>b;
}

int main()
{
	int n,m;
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
		a[i]=a[i]%m;
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			ans*=(a[i]-a[j]);
		}
		ans=ans%m;
	}
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

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

long long a[200005],ans=1;

int main()
{
	int n,m;
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			if(i==j) continue;
			ans*=abs(a[i]-a[j]);
		}
		ans%=m;
	}
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

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

long long a[200005],ans=1;

int main()
{
	int n,m;
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=i+1;j<=n;j++)
		{
			ans*=abs(a[i]-a[j]);
		}
		ans=ans%m;
	}
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
	int n,m;
	long long a[1005],ans=1;

	void work()
	{
		scanf("%d%d",&n,&m);
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
		}
		if(n>m)
		{
			printf("0\n");
			return ;
		}
		else
		{
			for(int i=2;i<=n;i++)
			{
				for(int j=1;j<i;j++)
				{
					ans=(ans*abs(a[i]-a[j])%m)%m;
				}
			}
			printf("%lld",ans);
		}
	}

}

int main()
{
	zzc::work();
	return 0;
 }


#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
    long long n,m;
	long long a[200005],ans=1;

	long long labs(long long x)
	{
		return x<0?-x:x;
	}

	void work()
	{
		scanf("%lld%lld",&n,&m);
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
		}
		if(n>m)
		{
			printf("0\n");
			return ;
		}
		else
		{
			for(int i=2;i<=n;i++)
			{
				for(int j=1;j<i;j++)
				{
					ans=(ans*labs(a[i]-a[j]))%m;
				}
			}
			printf("%lld",ans);
		}
	}

}

int main()
{
	zzc::work();
	return 0;
 }


#include<bits/stdc++.h>

using namespace std;

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

long long a[200005],ans=1;

int main()
{
	int n,m;
	n=read();
	m=read();
	for(int i=1;i<=n;i++)
	{
		a[i]=read();
	}
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=n;j++)
		{
			ans*=abs(a[i]-a[j]);
		}
		ans%=m;
	}
	printf("%lld",ans);
	return 0;
}


#include<bits/stdc++.h>

using namespace std;

namespace zzc
{
    long long n,m;
	long long a[1005],ans=1;

	long long labs(long long x)
	{
		return x<0?-x:x;
	}

	void work()
	{
		scanf("%lld%lld",&n,&m);
		for(int i=1;i<=n;i++)
		{
			scanf("%lld",&a[i]);
		}
		if(n>m)
		{
			printf("0\n");
			return ;
		}
		else
		{
			for(int i=2;i<=n;i++)
			{
				for(int j=1;j<i;j++)
				{
					ans=(ans*labs(a[i]-a[j]))%m;
				}
			}
			printf("%lld",ans);
		}
	}

}

int main()
{
	zzc::work();
	return 0;
 }


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
const int mod=1e9+7;
int t,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    sort(a,a+n);
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%m;
    }
    if(n%2==0)
    printf("%lld\n",s);
    else printf("%lld\n",(m-s)%m);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
//const int mod=1e9+7;
int t=0,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
        scanf("%d",&a[i]);
    if(n>m) {puts("0");return 0;}
    for(int i=0;i<n;i++)
        for(int j=i+1;j<n;j++)
            s=s*(abs(a[j]-a[i]))%m;
    printf("%lld\n",s%m);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
//const int mod=1e9+7;
int t=0,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    int mod=m;
    m*=2;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    sort(a,a+n);
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%mod;
    }
    printf("%lld\n",s);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
const int mod=1e9+7;
int t,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
        printf("%d ",a[i]);puts("");
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%m;
    }
    if(n%2==0)
    printf("%lld\n",s);
    else printf("%lld\n",m-s);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
//const int mod=1e9+7;
int t=0,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    int mod=m;
    m*=2;
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    sort(a,a+n);
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%m;
    }
    printf("%lld\n",s%mod);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
const int mod=1e9+7;
int t,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        a[i]%=m;
    }
    sort(a,a+n);
    for(int i=0;i<n;i++)
        printf("%d ",a[i]);puts("");
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%m;
    }
    if(n%2)
    printf("%lld\n",s);
    else printf("%lld\n",m-s);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define pb push_back
const int maxn=2e5+7;
const int mod=1e9+7;
int t=0,n,m;
ll s=1;
int a[maxn];
int main(){
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++){
        scanf("%d",&a[i]);
        if(a[i]>m) t++;
        a[i]%=m;
    }
    sort(a,a+n);
    int k=unique(a,a+n)-a;
    for(int i=0;i<k;i++){
        for(int j=i+1;j<k;j++)
            s=(s*(a[j]-a[i]))%m;
    }
    if(t%2==0)
    printf("%lld\n",s);
    else printf("%lld\n",(m-s)%m);
    return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        priority_queue<pair<int, int>,vector<pair<int, int> >, greater<pair<int, int> > > pq;
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
        states[source] = {0, -2, INT_MAX};
        pq.push(make_pair(states[source].dist, source));
        while(!pq.empty()){
            int d, v; tie(d, v) = pq.top(); pq.pop();
            if(d != states[v].dist) continue;
            for(int edid : adj[v]){
                edge & ed = edges[edid];
                if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
                    states[ed.u].dist = states[v].dist + ed.cost;
                    states[ed.u].prev = edid;
                    states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
                    pq.push(make_pair(states[ed.u].dist, ed.u));
                }
            }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        if(any_of(edges.begin(), edges.end(), [](const edge & ed){
            return ed.flow > 0 && ed.cost < 0;
        })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};

const int maxn = 3030;
const int magic = ((int)log2(maxn));
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++){
		int qtd_by_1 = 0;
		int qtd_by_7 = 0;
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1 && qtd_by_1 < 2 * magic) {
				solver.add_edge(out[e], in[f], 1, 0);
				qtd_by_1++;
			} else if((arr[e] % 7) == (arr[f] % 7) && qtd_by_7 < magic) {
				solver.add_edge(out[e], in[f], 1, 0);
				qtd_by_7++;
			}
		}
	}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
		vector<int> inqueue(n, 0);
		queue<int> q;
        states[source] = {0, -2, INT_MAX};
        q.push(source);
		inqueue[source] = 1;
        while(!q.empty()){
			int v = q.front(); q.pop();
			inqueue[v] = 0;
			for(int edid : adj[v]){
				edge & ed = edges[edid];
				if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
					states[ed.u].dist = states[v].dist + ed.cost;
					states[ed.u].prev = edid;
					states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
					if(!inqueue[ed.u]){
						q.push(ed.u);
						inqueue[ed.u] = 1;
					}
				}
			}
            // int d, v; tie(d, v) = pq.top(); pq.pop();
            // if(d != states[v].dist) continue;
            // for(int edid : adj[v]){
            //     edge & ed = edges[edid];
            //     if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
            //         states[ed.u].dist = states[v].dist + ed.cost;
            //         states[ed.u].prev = edid;
            //         states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
            //         pq.push(make_pair(states[ed.u].dist, ed.u));
            //     }
            // }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        if(any_of(edges.begin(), edges.end(), [](const edge & ed){
            return ed.flow > 0 && ed.cost < 0;
        })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};
const int maxn = 3030;
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++)
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1) solver.add_edge(out[e], in[f], 1, 0);
			else if((arr[e] % 7) == (arr[f] % 7)) solver.add_edge(out[e], in[f], 1, 0);
		}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        priority_queue<pair<int, int>,vector<pair<int, int> >, greater<pair<int, int> > > pq;
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
        states[source] = {0, -2, INT_MAX};
        pq.push(make_pair(states[source].dist, source));
        while(!pq.empty()){
            int d, v; tie(d, v) = pq.top(); pq.pop();
            if(d != states[v].dist) continue;
            for(int edid : adj[v]){
                edge & ed = edges[edid];
                if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
                    states[ed.u].dist = states[v].dist + ed.cost;
                    states[ed.u].prev = edid;
                    states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
                    pq.push(make_pair(states[ed.u].dist, ed.u));
                }
            }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        if(any_of(edges.begin(), edges.end(), [](const edge & ed){
            return ed.flow > 0 && ed.cost < 0;
        })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};
const int maxn = 3030;
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++)
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1) solver.add_edge(out[e], in[f], 1, 0);
			else if((arr[e] % 7) == (arr[f] % 7)) solver.add_edge(out[e], in[f], 1, 0);
		}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        priority_queue<pair<int, int>,vector<pair<int, int> >, greater<pair<int, int> > > pq;
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
        states[source] = {0, -2, INT_MAX};
        pq.push(make_pair(states[source].dist, source));
        while(!pq.empty()){
            int d, v; tie(d, v) = pq.top(); pq.pop();
            if(d != states[v].dist) continue;
            for(int edid : adj[v]){
                edge & ed = edges[edid];
                if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
                    states[ed.u].dist = states[v].dist + ed.cost;
                    states[ed.u].prev = edid;
                    states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
                    pq.push(make_pair(states[ed.u].dist, ed.u));
                }
            }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        // if(any_of(edges.begin(), edges.end(), [](const edge & ed){
        //     return ed.flow > 0 && ed.cost < 0;
        // })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};

const int maxn = 3030;
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++)
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1) solver.add_edge(out[e], in[f], 1, 0);
			else if((arr[e] % 7) == (arr[f] % 7)) solver.add_edge(out[e], in[f], 1, 0);
		}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
		vector<int> inqueue(n, 0);
		queue<int> q;
        states[source] = {0, -2, INT_MAX};
        q.push(source);
		inqueue[source] = 1;
        while(!q.empty()){
			int v = q.front(); q.pop();
			inqueue[v] = 0;
			for(int edid : adj[v]){
				edge & ed = edges[edid];
				if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
					states[ed.u].dist = states[v].dist + ed.cost;
					states[ed.u].prev = edid;
					states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
					if(!inqueue[ed.u]){
						q.push(ed.u);
						inqueue[ed.u] = 1;
					}
				}
			}
            // int d, v; tie(d, v) = pq.top(); pq.pop();
            // if(d != states[v].dist) continue;
            // for(int edid : adj[v]){
            //     edge & ed = edges[edid];
            //     if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
            //         states[ed.u].dist = states[v].dist + ed.cost;
            //         states[ed.u].prev = edid;
            //         states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
            //         pq.push(make_pair(states[ed.u].dist, ed.u));
            //     }
            // }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        // if(any_of(edges.begin(), edges.end(), [](const edge & ed){
        //     return ed.flow > 0 && ed.cost < 0;
        // })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};
const int maxn = 3030;
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++)
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1) solver.add_edge(out[e], in[f], 1, 0);
			else if((arr[e] % 7) == (arr[f] % 7)) solver.add_edge(out[e], in[f], 1, 0);
		}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include "bits/stdc++.h"
using namespace std;
struct SSP{
	int n, source, sink;
    vector<vector<int> > adj;
	struct edge {
        int u, flow, cap, cost, origcost;
    };
	vector<edge> edges;
	SSP(int n, int source, int sink): n(n),source(source),sink(sink),adj(n) {}
    int add_edge(int a, int b, int cap, int cost){
        int result = edges.size();
        adj[a].push_back(edges.size());
        edges.push_back({b, 0, cap, cost, cost});
        adj[b].push_back(edges.size());
        edges.push_back({a, 0, 0, -cost, -cost});
        return result;
    }
    pair<int, int> djk(){
        struct state_t{
            int dist, prev, maxf;
        };
        queue<int> q;
        vector<state_t> states(n, {INT_MAX/2, -1, 0});
        states[source] = {0, -2, INT_MAX};
        vector<int> inqueue(n, 0);
        inqueue[source] = 1;
        q.push(source);
        while(!q.empty()){
            int v = q.front(); q.pop();
            inqueue[v] = 0;
            for(int edid : adj[v]){
                edge & ed = edges[edid];
                if(ed.flow < ed.cap && states[ed.u].dist > states[v].dist + ed.cost){
                    states[ed.u].dist = states[v].dist + ed.cost;
                    states[ed.u].prev = edid;
                    states[ed.u].maxf = min(states[v].maxf, ed.cap - ed.flow);
                    if(!inqueue[ed.u]) q.push(ed.u);
                }
            }
        }
        int lastid = states[sink].prev, extraflow = states[sink].maxf, atcost = 0;
        if(lastid == -1) return {0, 0};
        for(int id = lastid; id != -2; id = states[edges[id^1].u].prev){
            edges[id].flow += extraflow;
            edges[id^1].flow -= extraflow;
            atcost += edges[id].origcost;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(states[v].prev != -1 && states[u].prev != -1)
                edges[id].cost += states[v].dist - states[u].dist;
        }
        return {extraflow, atcost};
    }
    pair<int, int> mfmc(){
        int flow = 0, cost = 0;
        if(any_of(edges.begin(), edges.end(), [](const edge & ed){
            return ed.flow > 0 && ed.cost < 0;
        })) bellamanford();
        int extraflow, atcost;
        while(tie(extraflow, atcost) = djk(), extraflow > 0)
            flow += extraflow, cost += extraflow * atcost;
        return {flow, cost};
    }
    void bellamanford(){
        vector<int> dist(n, INT_MAX/2);
        dist[source] = 0;
        for(int rep = 0; rep < n; rep++){
            bool changed = false;
            for(int id = 0; id < (int)edges.size(); id++){
                int v = edges[id^1].u, u = edges[id].u;
                if(edges[id].flow < edges[id].cap && dist[v] != INT_MAX/2 &&
                    dist[u] > dist[v] + edges[id].cost){
                    dist[u] = dist[v] + edges[id].cost;
                    changed = true;
                    assert(rep < n - 1);
                }
            }
            if(!changed) break;
        }
        for(int id = 0; id < (int) edges.size(); id++){
            int v = edges[id^1].u, u = edges[id].u;
            if(dist[v] < INT_MAX/2 && dist[u] < INT_MAX/2)
                edges[id].cost += dist[v] - dist[u];
        }
    }
};

const int maxn = 3030;
const int magic = ((int)log2(maxn))<<2;
int in[maxn], out[maxn], arr[maxn];
int cnt = 0;
int get_node(){
	cnt++;
	return cnt-1;
}
int main(){
	int n; scanf("%d", &n);
	for(int e = 0; e < n; e++)
		scanf("%d", arr + e);
	int source = get_node();
	int sink = get_node();
	int ssink = get_node();
	for(int e = 0; e < n; e++)
		in[e] = get_node();
	for(int e = 0; e < n; e++)
		out[e] = get_node();
	SSP solver(cnt, source, ssink);
	for(int e = 0; e < n; e++)
		solver.add_edge(in[e], out[e], 1, -1);
	for(int e = 0; e < n; e++)
		solver.add_edge(source, in[e], 1, 0);
	for(int e = 0; e < n; e++)
		solver.add_edge(out[e], sink, 1, 0);
	for(int e = 0; e < n; e++){
		int qtd_by_1 = 0;
		int qtd_by_7 = 0;
		for(int f = e + 1; f < n; f++){
			if(abs(arr[e] - arr[f]) == 1 && qtd_by_1 < 2 * magic) {
				solver.add_edge(out[e], in[f], 1, 0);
				qtd_by_1++;
			} else if((arr[e] % 7) == (arr[f] % 7) && qtd_by_7 < magic) {
				solver.add_edge(out[e], in[f], 1, 0);
				qtd_by_7++;
			}
		}
	}
	solver.add_edge(sink, ssink, 4, 0);
	pair<int, int> ans = solver.mfmc();
	printf("%d\n", -ans.second);
	return 0;
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < n; i++)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;

const double EPS = 1e-10;
const int INF = 100000000;
const int MOD = 1000000007;

struct edge{int to, cap, cost, rev; };

#define MAX_V 6010

int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost){
	G[from].push_back((edge){to, cap, cost, G[to].size()});
	G[to].push_back((edge){from, 0, -cost, G[from].size()-1});
}

int min_cost_flow(int s, int t, int f){
	int res = 0;
    bool first_time = true;
	fill(h, h+V, 0);
	while(f > 0){
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist+V, INF);
		dist[s] = 0;
        if(!first_time) {
            que.push(P(0,s));
            while(!que.empty()){
                P p = que.top(); que.pop();
                int v = p.second;
                if(dist[v] < p.first) continue;
                for(int i = 0; i < G[v].size(); i++){
                    edge &e = G[v][i];
                    if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
                        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        que.push(P(dist[e.to],e.to));
                    }
                }
            }
        } else {
            while(true) {
                bool end = true;
                rep(i,V) {
                    if(dist[i] == INF) continue;
                    rep(j, G[i].size()) {
                        edge e = G[i][j];
                        if(e.cap > 0 && dist[e.to] > dist[i] + e.cost) {
                            dist[e.to] = dist[i] + e.cost;
                            prevv[e.to] = i;
                            preve[e.to] = j;
                            end = false;
                        }
                    }
                }
                if(end) break;
            }
        }
        first_time = false;
		if(dist[t] == INF){
			return -1;
		}
		for(int v = 0; v < V; v++) h[v] += dist[v];

		int d = f;
		for(int v = t; v != s; v = prevv[v]){
			d = min(d, G[prevv[v]][preve[v]].cap);
		}
		f -= d;
		res += d*h[t];
		for(int v = t; v != s; v = prevv[v]){
			edge &e = G[prevv[v]][preve[v]];
			e.cap -= d;
			G[v][e.rev].cap += d;
		}
	}
	return res;
}

int n;
int a[3000];

int main(){
    scanf("%d", &n);
    rep(i,n) scanf("%d", a+i);
    rep(i,n) {
        add_edge(i, i+n, 1, -1);
    }
    rep(i,n) {
        for(int j = i+1; j < n; j++) {
            if(abs(a[i]-a[j]) <= 1 || a[i]%7 == a[j]%7) {
                add_edge(i+n, j, 1, 0);
            }
        }
    }
    rep(i,n) {
        add_edge(2*n, i, 1, 0);
        add_edge(i+n, 2*n+1, 1, 0);
    }
    V = 2*n+2;
    printf("%d\n", -1*min_cost_flow(2*n, 2*n+1, 4));
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < n; i++)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;

const double EPS = 1e-10;
const int INF = 100000000;
const int MOD = 1000000007;

struct edge{int to, cap, cost, rev; };

#define MAX_V 6010

int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost){
	G[from].push_back((edge){to, cap, cost, G[to].size()});
	G[to].push_back((edge){from, 0, -cost, G[from].size()-1});
}

int min_cost_flow(int s, int t, int f){
	int res = 0;
    bool first_time = true;
	fill(h, h+V, 0);
	while(f > 0){
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist+V, INF);
		dist[s] = 0;
        if(!first_time) {
            que.push(P(0,s));
            while(!que.empty()){
                P p = que.top(); que.pop();
                int v = p.second;
                if(dist[v] < p.first) continue;
                for(int i = 0; i < G[v].size(); i++){
                    edge &e = G[v][i];
                    if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
                        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        que.push(P(dist[e.to],e.to));
                    }
                }
            }
        } else {
            while(true) {
                bool end = true;
                rep(i,V) {
                    if(dist[i] == INF) continue;
                    rep(j, G[i].size()) {
                        edge e = G[i][j];
                        if(e.cap > 0 && dist[e.to] > dist[i] + e.cost) {
                            dist[e.to] = dist[i] + e.cost;
                            prevv[e.to] = i;
                            preve[e.to] = j;
                            end = false;
                        }
                    }
                }
                if(end) break;
            }
        }
        first_time = false;
		if(dist[t] == INF){
			return -1;
		}
		for(int v = 0; v < V; v++) h[v] += dist[v];

		int d = f;
		for(int v = t; v != s; v = prevv[v]){
			d = min(d, G[prevv[v]][preve[v]].cap);
		}
		f -= d;
		res += d*h[t];
		for(int v = t; v != s; v = prevv[v]){
			edge &e = G[prevv[v]][preve[v]];
			e.cap -= d;
			G[v][e.rev].cap += d;
		}
	}
	return res;
}

int n;
int a[3000];

int main(){
    scanf("%d", &n);
    rep(i,n) scanf("%d", a+i);
    rep(i,n) {
        add_edge(i, i+n, 1, -1);
    }
    rep(i,n) {
        int cnt[3] = {0, 0, 0};
        for(int j = i+1; j < n; j++) {
            if(a[i]%7 == a[j]%7 && cnt[0] < 100) {
                cnt[0]++;
                add_edge(i+n, j, 1, 0);
            } else if(a[i]-a[j] == 1 && cnt[1] < 100) {
                cnt[1]++;
                add_edge(i+n, j, 1, 0);
            } else if(a[i]-a[j] == -1 && cnt[2] < 100) {
                cnt[2]++;
                add_edge(i+n, j, 1, 0);
            }
        }
    }
    rep(i,n) {
        add_edge(2*n, i, 1, 0);
        add_edge(i+n, 2*n+1, 1, 0);
    }
    V = 2*n+2;
    printf("%d\n", -1*min_cost_flow(2*n, 2*n+1, 4));
}


#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0; i < n; i++)
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;

const double EPS = 1e-10;
const int INF = 100000000;
const int MOD = 1000000007;

struct edge{int to, cap, cost, rev; };

#define MAX_V 6010

int V;
vector<edge> G[MAX_V];
int h[MAX_V];
int dist[MAX_V];
int prevv[MAX_V], preve[MAX_V];

void add_edge(int from, int to, int cap, int cost){
	G[from].push_back((edge){to, cap, cost, G[to].size()});
	G[to].push_back((edge){from, 0, -cost, G[from].size()-1});
}

int min_cost_flow(int s, int t, int f){
	int res = 0;
    bool first_time = true;
	fill(h, h+V, 0);
	while(f > 0){
		priority_queue<P, vector<P>, greater<P> > que;
		fill(dist, dist+V, INF);
		dist[s] = 0;
        if(!first_time) {
            que.push(P(0,s));
            while(!que.empty()){
                P p = que.top(); que.pop();
                int v = p.second;
                if(dist[v] < p.first) continue;
                for(int i = 0; i < G[v].size(); i++){
                    edge &e = G[v][i];
                    if(e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]){
                        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        que.push(P(dist[e.to],e.to));
                    }
                }
            }
        } else {
            while(true) {
                bool end = true;
                rep(i,V) {
                    if(dist[i] == INF) continue;
                    rep(j, G[i].size()) {
                        edge e = G[i][j];
                        if(e.cap > 0 && dist[e.to] > dist[i] + e.cost) {
                            dist[e.to] = dist[i] + e.cost;
                            prevv[e.to] = i;
                            preve[e.to] = j;
                            end = false;
                        }
                    }
                }
                if(end) break;
            }
        }
        first_time = false;
		if(dist[t] == INF){
			return -1;
		}
		for(int v = 0; v < V; v++) h[v] += dist[v];

		int d = f;
		for(int v = t; v != s; v = prevv[v]){
			d = min(d, G[prevv[v]][preve[v]].cap);
		}
		f -= d;
		res += d*h[t];
		for(int v = t; v != s; v = prevv[v]){
			edge &e = G[prevv[v]][preve[v]];
			e.cap -= d;
			G[v][e.rev].cap += d;
		}
	}
	return res;
}

int n;
int a[3000];

int main(){
    scanf("%d", &n);
    rep(i,n) scanf("%d", a+i);
    rep(i,n) {
        add_edge(i, i+n, 1, -1);
    }
    rep(i,n) {
        int cnt[3] = {0, 0, 0};
        for(int j = i+1; j < n; j++) {
            if(a[i]%7 == a[j]%7 && cnt[0] < 10) {
                cnt[0]++;
                add_edge(i+n, j, 1, 0);
            } else if(a[i]-a[j] == 1 && cnt[1] < 10) {
                cnt[1]++;
                add_edge(i+n, j, 1, 0);
            } else if(a[i]-a[j] == -1 && cnt[2] < 10) {
                cnt[2]++;
                add_edge(i+n, j, 1, 0);
            }
        }
    }
    rep(i,n) {
        add_edge(2*n, i, 1, 0);
        add_edge(i+n, 2*n+1, 1, 0);
    }
    V = 2*n+2;
    printf("%d\n", -1*min_cost_flow(2*n, 2*n+1, 4));
}


#include<bits/stdc++.h>
#define inf 100000
using namespace std;
/*
book:http://cs.yazd.ac.ir/hasheminezhad/STSCS4R1.pdf
read the 9th chapter of this book
the algorithm used is successive shortest path algorithm
modifications:
1.reduced cost is defined as c[i][j]' = c[i][j]+potential[i]-potential[j] (not -potential[i]+potential[j])
2.so in lemma 9.11 a:
  potential'=potential+d  (not -d as we have changed the reduced cost potential)
3.initial node potential are set not to 0 but bellman ford algorithm is used to set
  it to the distances(u can verify that it is a valid node potential)
  this is done so that even negative costs can also be accomodated
4.instead of considering various nodes with excess and deficits we just add one source
  and one destination node and they have infinite excess and deficit respectively
    a)source is connected to nodes that have excess by an edge of capacity equal to the
      excess and of cost 0
    b)similarly nodes with deficit are connected to dest of capacity equal to deficit
      and cost 0
5.so in this algorithm we continuously try to send flow from source to dest(excess to deficit)
  if the dest becomes unreachable it means it cant send anymore flow check if the
  arcs from source and arcs to dest are saturated it means the its feasible and optimal
  solution has been obtained
*/
struct edge
{
    int to,cap,flow,cost,index;
    edge(int to,int cap,int flow,int cost,int index):
    to(to),cap(cap),flow(flow),cost(cost),index(index){

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

    }
    void addedge(int from,int to,int cap,int cost)
    {
        g[from].push_back(edge(to,cap,0,cost,g[to].size()));
        g[to].push_back(edge(from,0,0,-cost,g[from].size()-1));
    }
    void bellman_ford(int source,vector<int> &dist)
    {
        fill(dist.begin(),dist.end(),inf);
        dist[source]=0;
        inqueue[source]=true;
        queue<int>q;
        q.push(source);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inqueue[u]=false;
            for(auto &e:g[u])
            {
               if(e.flow==e.cap)//if the arc is saturated
               continue;
               int newdist=dist[u]+e.cost;
               if(dist[e.to]>newdist)
               {
                   dist[e.to]=newdist;
                   if(!inqueue[e.to])
                   {
                       inqueue[e.to]=true;
                       q.push(e.to);
                   }
               }
            }
        }
    }
    pair<int,int> mincostflow(int source,int dest)
    {
        bellman_ford(source,potential);
        int flow=0;
        int flowcost=0;
        while(true)
        {
            priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
            fill(prio.begin(),prio.end(),inf);
            prio[source]=0;
            q.push({
            0,source
            });
            curflow[source]=inf;
            while(!q.empty())
            {
                int d=q.top().first;
                int u=q.top().second;
                q.pop();
                if(d!=prio[u])
                continue;//means if there is a shorter path to the node than this one
                for(int i=0;i<g[u].size();i++)
                {
                    edge &e=g[u][i];
                    if(e.flow==e.cap)
                    continue;
                    int newdist=prio[u]+potential[u]-potential[e.to]+e.cost;
                    if(prio[e.to]>newdist)
                    {
                        prio[e.to]=newdist;
                        q.push({
                            newdist,e.to
                        });
                        curflow[e.to]=min(curflow[u],e.cap-e.flow);
                        prevnode[e.to]=u;
                        prevedge[e.to]=i;
                    }
                }
            }
            if(prio[dest]==inf)
            break;
            int temp=curflow[dest];
            flow += temp;
            for(int i=0;i<n;i++)
            potential[i] += prio[i];
            for(int i=dest;i!=source;i=prevnode[i])
            {
                edge &e=g[prevnode[i]][prevedge[i]];
                e.flow += temp;
                g[i][e.index].flow -= temp;
                flowcost += e.cost*temp;
            }
        }
        return {
            flow,flowcost
        };
    }
};
int n,a[3003];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    mincostmaxflow mcmf(2*n + 3);
    mcmf.addedge(0,2*n + 1,4,0);
    for(int i=1;i<=n;i++)
    {
        mcmf.addedge(i,i+n,1,-1);
        mcmf.addedge(i+n,2*n + 2,1,0);
        mcmf.addedge(2*n + 1,i,1,0);
        for(int j=i+1;j<=n;j++)
        {
            if((a[i]%7 == a[j]%7) || abs(a[i]-a[j])==1)
            mcmf.addedge(i+n,j,1,0);
        }
    }
    printf("%d\n",-mcmf.mincostflow(0,2*n + 2).second);
    return 0;
}


#include<bits/stdc++.h>
#define inf 100000
using namespace std;
/*
book:http://cs.yazd.ac.ir/hasheminezhad/STSCS4R1.pdf
read the 9th chapter of this book
the algorithm used is successive shortest path algorithm
modifications:
1.reduced cost is defined as c[i][j]' = c[i][j]+potential[i]-potential[j] (not -potential[i]+potential[j])
2.so in lemma 9.11 a:
  potential'=potential+d  (not -d as we have changed the reduced cost potential)
3.initial node potential are set not to 0 but bellman ford algorithm is used to set
  it to the distances(u can verify that it is a valid node potential)
  this is done so that even negative costs can also be accomodated
4.instead of considering various nodes with excess and deficits we just add one source
  and one destination node and they have infinite excess and deficit respectively
    a)source is connected to nodes that have excess by an edge of capacity equal to the
      excess and of cost 0
    b)similarly nodes with deficit are connected to dest of capacity equal to deficit
      and cost 0
5.so in this algorithm we continuously try to send flow from source to dest(excess to deficit)
  if the dest becomes unreachable it means it cant send anymore flow check if the
  arcs from source and arcs to dest are saturated it means the its feasible and optimal
  solution has been obtained
*/
struct edge
{
    int to,cap,flow,cost,index;
    edge(int to,int cap,int flow,int cost,int index):
    to(to),cap(cap),flow(flow),cost(cost),index(index){

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

    }
    void addedge(int from,int to,int cap,int cost)
    {
        g[from].push_back(edge(to,cap,0,cost,g[to].size()));
        g[to].push_back(edge(from,0,0,-cost,g[from].size()-1));
    }
    void bellman_ford(int source,vector<int> &dist)
    {
        fill(dist.begin(),dist.end(),inf);
        dist[source]=0;
        inqueue[source]=true;
        queue<int>q;
        q.push(source);
        while(!q.empty())
        {
            int u=q.front();
            q.pop();
            inqueue[u]=false;
            for(auto &e:g[u])
            {
               if(e.flow==e.cap)//if the arc is saturated
               continue;
               int newdist=dist[u]+e.cost;
               if(dist[e.to]>newdist)
               {
                   dist[e.to]=newdist;
                   if(!inqueue[e.to])
                   {
                       inqueue[e.to]=true;
                       q.push(e.to);
                   }
               }
            }
        }
    }
    pair<int,int> mincostflow(int source,int dest)
    {
        //bellman_ford(source,potential);
        int flow=0;
        int flowcost=0;
        while(true)
        {
            priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
            fill(prio.begin(),prio.end(),inf);
            prio[source]=0;
            q.push({
            0,source
            });
            curflow[source]=inf;
            while(!q.empty())
            {
                int d=q.top().first;
                int u=q.top().second;
                q.pop();
                if(d!=prio[u])
                continue;//means if there is a shorter path to the node than this one
                for(int i=0;i<g[u].size();i++)
                {
                    edge &e=g[u][i];
                    if(e.flow==e.cap)
                    continue;
                    int newdist=prio[u]+potential[u]-potential[e.to]+e.cost;
                    if(prio[e.to]>newdist)
                    {
                        prio[e.to]=newdist;
                        q.push({
                            newdist,e.to
                        });
                        curflow[e.to]=min(curflow[u],e.cap-e.flow);
                        prevnode[e.to]=u;
                        prevedge[e.to]=i;
                    }
                }
            }
            if(prio[dest]==inf)
            break;
            int temp=curflow[dest];
            flow += temp;
            for(int i=0;i<n;i++)
            potential[i] += prio[i];
            for(int i=dest;i!=source;i=prevnode[i])
            {
                edge &e=g[prevnode[i]][prevedge[i]];
                e.flow += temp;
                g[i][e.index].flow -= temp;
                flowcost += e.cost*temp;
            }
        }
        return {
            flow,flowcost
        };
    }
};
int n,a[3003];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    scanf("%d",&a[i]);
    mincostmaxflow mcmf(2*n + 3);
    mcmf.addedge(0,2*n + 1,4,0);
    for(int i=1;i<=n;i++)
    {
        mcmf.addedge(i,i+n,1,-1);
        mcmf.addedge(i+n,2*n + 2,1,0);
        mcmf.addedge(2*n + 1,i,1,0);
        for(int j=i+1;j<=n;j++)
        {
            if((a[i]%7 == a[j]%7) || abs(a[i]-a[j])==1)
            mcmf.addedge(i+n,j,1,0);
        }
    }
    printf("%d\n",-mcmf.mincostflow(0,2*n + 2).second);
    return 0;
}


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

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

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