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

//macros
typedef long long ll;
typedef pair<ll, ll> ii;
typedef tuple<int, int, int> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define INF 1e9
#define pb push_back
#define fi first
#define se second

//===================//
//  Added libraries  //
//===================//

// mod library
const ll MOD=1e9+7;

inline ll mod(ll x_) {
	return (x_)%MOD;
}
ll modpow(ll x_, ll N_) {
    if(N_ == 0) return 1;
    ll a = modpow(x_,N_/2);
    a = (a*a)%MOD;
    if(N_%2) a = (a*x_)%MOD;
    return a;
}
ll inv(ll x_) {
    return modpow(x_, MOD-2);
}
class mi {
public:
    mi(ll v=0) {value = v;}
    mi  operator+ (ll rs) {return mod(value+rs);}
    mi  operator- (ll rs) {return mod(value-rs+MOD);}
    mi  operator* (ll rs) {return mod(value*rs);}
    mi  operator/ (ll rs) {return mod(value*inv(rs));}
    mi& operator+=(ll rs) {*this = (*this)+rs; return *this;}
    mi& operator-=(ll rs) {*this = (*this)-rs; return *this;}
    mi& operator*=(ll rs) {*this = (*this)*rs; return *this;}
    mi& operator/=(ll rs) {*this = (*this)/rs; return *this;}
    operator ll&() {return value;}

    ll value;
};
typedef vector<mi> vmi;

//===================//
//end added libraries//
//===================//

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

//===================//
//   begin program   //
//===================//

const int MX = 1e4;
int n, m, s[MX], f[MX], h[MX];
int cntS[MX], mx=0, cur=0;
bitset<MX> l, r;
int inUseL[MX], inUseR[MX];
mi ways=0;

void addInUse(int i) {
	if(inUseL[i] == 0 && inUseR[i] == 0) return;
	else if(inUseL[i] <= 1 && inUseR[i] <= 1) cur += 1;
	else if(inUseL[i] >= 1 && inUseR[i] >= 1) cur += 2;
	else cur += 1;
}
void removeInUse(int i) {
	if(inUseL[i] == 0 && inUseR[i] == 0) return;
	else if(inUseL[i] <= 1 && inUseR[i] <= 1) cur -= 1;
	else if(inUseL[i] >= 1 && inUseR[i] >= 1) cur -= 2;
	else cur -= 1;
}

void program() {
	cin>>n>>m;
	RE(i,n) cin>>s[i], s[i]--;
	RE(i,m) cin>>f[i]>>h[i], f[i]--;
	l.reset(); r.reset();

	RE(i,n) cntS[i] = 0;
	RE(i,n) {
		cntS[s[i]]++;
		RE(j,m) if(f[j] == s[i] && h[j] == cntS[s[i]]) l[i]=1;
	}

	RE(i,n) cntS[i] = 0;
	REV(i,0,n) {
		cntS[s[i]]++;
		RE(j,m) if(f[j] == s[i] && h[j] == cntS[s[i]]) r[i]=1;
	}

	RE(i,n) inUseL[i]=inUseR[i]=0;
	RE(i,n) if(r[i]) {
		removeInUse(s[i]);
		inUseR[s[i]]++;
		addInUse(s[i]);
	}

	mx=cur;
	RE(i,n) {
		if(r[i]) {
			removeInUse(s[i]);
			inUseR[s[i]]--;
			addInUse(s[i]);
		}
		if(l[i]) {
			removeInUse(s[i]);
			inUseL[s[i]]++;
			addInUse(s[i]);
		}
		mx = max(mx, cur);
	}

	RE(i,n) inUseL[i]=inUseR[i]=0;
	cur = 0;

	RE(i,n) if(r[i]) {
		removeInUse(s[i]);
		inUseR[s[i]]++;
		addInUse(s[i]);
	}
	RE(i,n) {
		if(i == 0 && cur == mx) {
			mi added=1;
			RE(j,n) if(inUseR[j]) added *= inUseR[j];
			ways += added;
		}
		if(r[i]) {
			removeInUse(s[i]);
			inUseR[s[i]]--;
			addInUse(s[i]);
		}
		if(l[i]) {
			removeInUse(s[i]);
			inUseL[s[i]]++;
			addInUse(s[i]);
			if(cur == mx) {
				mi added=1;
				RE(j,n) {
					if(j == s[i]) {
						if(inUseR[j]) {
							if(inUseR[j] > inUseL[j]) 	added *= inUseR[j]-1;
							else 						added *= inUseR[j];
						}
					} else {
						if(inUseL[j] && inUseR[j]) {
							mi small=inUseL[j], big=inUseR[j];
							if(small > big) swap(small, big);
							if(small == big) {
								added *= small*2;
							} else {
								big -= 1;
								if(big == 0) big = 1;
								added *= small*big;
							}
						} else {
							if(inUseL[j]) added *= inUseL[j];
							if(inUseR[j]) added *= inUseR[j];
						}
					}
				}
				ways += added;
			}
		}
	}

	cout<<mx<<" "<<ways<<endl;

}


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

//macros
typedef long long ll;
typedef pair<ll, ll> ii;
typedef tuple<int, int, int> iii;
typedef vector<ll> vi;
typedef vector<ii> vii;
typedef vector<iii> viii;
typedef vector<ll> vll;
#define REP(a,b,c) for(int a=int(b); a<int(c); a++)
#define RE(a,c) REP(a,0,c)
#define RE1(a,c) REP(a,1,c+1)
#define REI(a,b,c) REP(a,b,c+1)
#define REV(a,b,c) for(int a=int(c-1); a>=int(b); a--)
#define INF 1e9
#define pb push_back
#define fi first
#define se second

//===================//
//  Added libraries  //
//===================//

// mod library
ll MOD=1e9+7;

inline ll mod(ll x_) {
	return (x_)%MOD;
}
ll modpow(ll x_, ll N_) {
    if(N_ == 0) return 1;
    ll a = modpow(x_,N_/2);
    a = (a*a)%MOD;
    if(N_%2) a = (a*x_)%MOD;
    return a;
}
ll inv(ll x_) {
    return modpow(x_, MOD-2);
}
class mi {
public:
    mi(ll v=0) {value = v;}
    mi  operator+ (ll rs) {return mod(value+rs);}
    mi  operator- (ll rs) {return mod(value-rs+MOD);}
    mi  operator* (ll rs) {return mod(value*rs);}
    mi  operator/ (ll rs) {return mod(value*inv(rs));}
    mi& operator+=(ll rs) {*this = (*this)+rs; return *this;}
    mi& operator-=(ll rs) {*this = (*this)-rs; return *this;}
    mi& operator*=(ll rs) {*this = (*this)*rs; return *this;}
    mi& operator/=(ll rs) {*this = (*this)/rs; return *this;}
    operator ll&() {return value;}

    ll value;
};
typedef vector<mi> vmi;

//===================//
//end added libraries//
//===================//

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

//===================//
//   begin program   //
//===================//

const int MX = 1e4;
int n, m, s[MX], f[MX], h[MX];
int cntS[MX], mx=0, cur=0;
bitset<MX> l, r;
int inUseL[MX], inUseR[MX];
mi ways=0;

void addInUse(int i) {
	if(inUseL[i] == 0 && inUseR[i] == 0) return;
	else if(inUseL[i] <= 1 && inUseR[i] <= 1) cur += 1;
	else if(inUseL[i] >= 1 && inUseR[i] >= 1) cur += 2;
	else cur += 1;
}
void removeInUse(int i) {
	if(inUseL[i] == 0 && inUseR[i] == 0) return;
	else if(inUseL[i] <= 1 && inUseR[i] <= 1) cur -= 1;
	else if(inUseL[i] >= 1 && inUseR[i] >= 1) cur -= 2;
	else cur -= 1;
}

void program() {
	cin>>n>>m;
	RE(i,n) cin>>s[i], s[i]--;
	RE(i,m) cin>>f[i]>>h[i], f[i]--;
	l.reset(); r.reset();

	RE(i,n) cntS[i] = 0;
	RE(i,n) {
		cntS[s[i]]++;
		RE(j,m) if(f[j] == s[i] && h[j] == cntS[s[i]]) l[i]=1;
	}

	RE(i,n) cntS[i] = 0;
	REV(i,0,n) {
		cntS[s[i]]++;
		RE(j,m) if(f[j] == s[i] && h[j] == cntS[s[i]]) r[i]=1;
	}

	RE(i,n) inUseL[i]=inUseR[i]=0;
	RE(i,n) if(r[i]) {
		removeInUse(s[i]);
		inUseR[s[i]]++;
		addInUse(s[i]);
	}

	mx=cur;
	RE(i,n) {
		if(r[i]) {
			removeInUse(s[i]);
			inUseR[s[i]]--;
			addInUse(s[i]);
		}
		if(l[i]) {
			removeInUse(s[i]);
			inUseL[s[i]]++;
			addInUse(s[i]);
		}
		mx = max(mx, cur);
	}

	RE(i,n) inUseL[i]=inUseR[i]=0;
	cur = 0;

	RE(i,n) if(r[i]) {
		removeInUse(s[i]);
		inUseR[s[i]]++;
		addInUse(s[i]);
	}
	RE(i,n) {
		if(i == 0 && cur == mx) {
			mi added=1;
			RE(j,n) if(inUseR[j]) added *= inUseR[j];
			ways += added;
		}
		if(r[i]) {
			removeInUse(s[i]);
			inUseR[s[i]]--;
			addInUse(s[i]);
		}
		if(l[i]) {
			removeInUse(s[i]);
			inUseL[s[i]]++;
			addInUse(s[i]);
			if(cur == mx) {
				mi added=1;
				RE(j,n) {
					if(j == s[i]) {
						if(inUseR[j]) {
							if(inUseR[j] >= inUseL[j]) 	added *= max(1,inUseR[j]-1);
							else 						added *= inUseR[j];
						}
					} else {
						if(inUseL[j] && inUseR[j]) {
							mi small=inUseL[j], big=inUseR[j];
							if(small > big) swap(small, big);
							if(small == 1 && big == 1) big=3;
							big = max(1LL, ll(big-1));
							added *= small*big;
						} else {
							if(inUseL[j]) added *= inUseL[j];
							if(inUseR[j]) added *= inUseR[j];
						}
					}
				}
				ways += added;
			}
		}
	}

	cout<<mx<<" "<<ways<<endl;

}


#include<bits/stdc++.h>
using namespace std;
#define mp(a,b) make_pair(a,b)
#define ff first
#define setp(a) setprecision(a)<<fixed
#define ss second
#define all(a) a.begin() , a.end()
#define revall(a) a.rbegin() , a.rend()
#define intt long long
#define ll long long
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define vvi vector< vi >
#define vipi vector<pair< pair<int,int > , int > >
#define vdb vector<double>
#define length(a) (int)(a.size())
#define fori(v) for(int i=0; i<v; i++)
#define forj(v) for(int j=0; j<v; j++)
#define fork(v) for(int k=0; k<v; k++)
#define forl(v) for(int l=0; l<v; l++)
#define fort(v) for(int t=0; t<v; t++)
#define forz(v) for(int z=0; z<v; z++)
#define MAX (int)(pow(10,7) + 10)
#define pb(a) push_back(a)
#define endl "\n"
#define bo ' '
ll gesas;
ll inf = 100000000000000000LL;
ll modulo = pow(10,9) + 7;
double eps = 1e-6;
const long long int mod = 998244353;
ll n ; const int kons=500001;
//vi values(2000,0);
vector< ll > valuesforcows[50];

ll min (ll a, ll b)
{return a<b ? a : b;}
const int N = 3e5 + 7;

int main() {
    ll k,z,d,g, m, t, b, c, e, x, y, x1, y1, x2, y2;string he = "YES" , yox = "NO";
    int n,a;
//    cin>>t;
//        while (t--)
//    {
    cin>>n>>m;
    map< pair<int,int> , int >cowmap;
    int f[m],h[m],s[n+1];
    s[0]=0;
    for(int i=1;i<=n;i++)
    {cin>>s[i];}
    fork(m){cin>>f[k]>>h[k];
    valuesforcows[f[k]].pb(h[k]);
    cowmap[{f[k],h[k]}]++;}
    cowmap[{0,1}]++;
    for (int l = 0; l <=n; ++l) sort(all(valuesforcows[l]));
    ll sayansmax=0,numberofways=1;
    for(int i=0;i<n+1;i++){

        vi lefcounter(n+1,0),rigcounter(n+1,0);
//        for (int l = 0; l < n+1; ++l) lefcounter.push_back(0),rigcounter.push_back(0);
        for(int j=0;j<=i;j++)lefcounter[s[j]]++; for(int j=i+1;j<n+1;j++)rigcounter[s[j]]++;
if(!cowmap.count({s[i],lefcounter[s[i]]}))continue;
ll umberofways=0, cavab=0, upbon = (upper_bound(all(valuesforcows[s[i]]),rigcounter[s[i]])-valuesforcows[s[i]].begin());
if(lefcounter[s[i]]<=rigcounter[s[i]])upbon--;
if(upbon)     cavab += 2,(umberofways+=upbon)%=modulo;
else cavab++,(umberofways=umberofways+1)%=modulo;
if(!i)
    cavab--;
for(int ind =1;ind<=n ;ind++) {
    ll zupbon = (upper_bound(all(valuesforcows[ind]), rigcounter[ind]) - valuesforcows[ind].begin()), juppon = (upper_bound(all(valuesforcows[ind]),lefcounter[ind])-valuesforcows[ind].begin());
if(!zupbon  && !juppon )
    continue;
if( ind==s[i])
    continue;
    ll kuppon = zupbon;
    zupbon= zupbon*juppon-(min(zupbon,juppon));
if(zupbon)
{(umberofways *=zupbon)%=modulo;
cavab+=2;
    continue;}
(kuppon+=juppon)%=modulo;
    (umberofways*=kuppon)%=modulo;
    cavab++;}

if(cavab >sayansmax)
{    sayansmax = cavab;
 numberofways = (umberofways)%modulo;}
else if(cavab== sayansmax)
{(numberofways +=umberofways)%=modulo;}}
if(!sayansmax)
numberofways=1;
    cout<<sayansmax<<bo<<numberofways<<endl;}


#include<bits/stdc++.h>
using namespace std;
#define mp(a,b) make_pair(a,b)
#define ff first
#define setp(a) setprecision(a)<<fixed
#define ss second
#define all(a) a.begin() , a.end()
#define revall(a) a.rbegin() , a.rend()
#define intt long long
#define ll long long
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define vvi vector< vi >
#define vipi vector<pair< pair<int,int > , int > >
#define vdb vector<double>
#define length(a) (int)(a.size())
#define fori(v) for(int i=0; i<v; i++)
#define forj(v) for(int j=0; j<v; j++)
#define fork(v) for(int k=0; k<v; k++)
#define forl(v) for(int l=0; l<v; l++)
#define fort(v) for(int t=0; t<v; t++)
#define forz(v) for(int z=0; z<v; z++)
#define MAX (int)(pow(10,7) + 10)
#define pb(a) push_back(a)
#define endl "\n"
#define bo ' '
ll gesas;
ll inf = 100000000000000000LL;
ll modulo = pow(10,9) + 7;
double eps = 1e-6;
const long long int mod = 998244353;
ll n ; const int kons=500001;
//vi values(2000,0);
vector< ll > valuesforcows[50];

ll min (ll a, ll b)
{return a<b ? a : b;}
const int N = 3e5 + 7;

int main() {
    ll k,z,d,g, m, t, b, c, e, x, y, x1, y1, x2, y2;string he = "YES" , yox = "NO";
    int n,a;
//    cin>>t;
//        while (t--)
//    {
    cin>>n>>m;
    map< pair<int,int> , int >cowmap;
    int f[m],h[m],s[n+1];
    s[0]=0;
    for(int i=1;i<=n;i++)
    {cin>>s[i];}
    fork(m)cin>>f[k]>>h[k],valuesforcows[f[k]].pb(h[k]),cowmap[{f[k],h[k]}]++;
    cowmap[{0,1}]++;
    for (int l = 0; l <=n; ++l) sort(all(valuesforcows[l]));
    ll sayansmax=0,numberofways=1;
    for(int i=0;i<n+1;i++){

        vi lefcounter(n+1,0),rigcounter(n+1,0);
//        for (int l = 0; l < n+1; ++l) lefcounter.push_back(0),rigcounter.push_back(0);
        for(int j=0;j<=i;j++)lefcounter[s[j]]++; for(int j=i+1;j<n+1;j++)rigcounter[s[j]]++;
if(!cowmap.count({s[i],lefcounter[s[i]]}))continue;
ll umberofways=0, cavab=0, upbon = (upper_bound(all(valuesforcows[s[i]]),rigcounter[s[i]])-valuesforcows[s[i]].begin());
if(lefcounter[s[i]]<=rigcounter[s[i]])upbon--;
if(upbon)     cavab += 2,(umberofways+=upbon)%=modulo;
else cavab++,(umberofways=umberofways+1)%=modulo;
if(!i)
    cavab--;
for(int ind =1;ind<=n ;ind++) {
    ll zupbon = (upper_bound(all(valuesforcows[ind]), rigcounter[ind]) - valuesforcows[ind].begin()), juppon = (upper_bound(all(valuesforcows[ind]),lefcounter[ind])-valuesforcows[ind].begin());
if(!zupbon  && !juppon )
    continue;
if( ind==s[i])
    continue;
    ll kuppon = zupbon;
    zupbon= zupbon*juppon-(min(zupbon,juppon));
if(zupbon)
{(umberofways *=zupbon)%=modulo;
cavab+=2;
    continue;}
(kuppon+=juppon)%=modulo;
    (umberofways*=kuppon)%=modulo;
    cavab++;}

if(cavab >sayansmax)
{    sayansmax = cavab;
 numberofways = (umberofways)%modulo;}
else if(cavab== sayansmax)
{(numberofways +=umberofways)%=modulo;}}
if(!sayansmax)
numberofways=1;
    cout<<sayansmax<<bo<<numberofways<<endl;}


#include <cstdio>
#include <vector>
#include <algorithm>
#include <cassert>

const int MOD=1e9+7;

int modexp(int base,int exp){
  int ac=1;
  for(;exp;exp>>=1){
    if(exp&1) ac=1LL*ac*base%MOD;
    base=1LL*base*base%MOD;
  }
  return ac;
}

int inverse(int x){
  return modexp(x,MOD-2);
}

int fs[100005];
int left[100005],right[100005];
std::vector<int> cows[100005];//cows[f]: hunger of cows that like flavor f
int asleep[100005];
int ways[100005];
int total_asleep=0,total_ways=1;

void calc_ways(int f){
  int a=std::upper_bound(cows[f].begin(),cows[f].end(),left[f])-cows[f].begin();
  int b=std::upper_bound(cows[f].begin(),cows[f].end(),right[f])-cows[f].begin();
  if(a>b) std::swap(a,b);
  long long cnt2=1LL*a*b-a;
  int cnt1=a+b;
  cnt2%=MOD;
  if(cnt2>0){
    asleep[f]=2;
    ways[f]=cnt2;
  }else if(cnt1>0){
    asleep[f]=1;
    ways[f]=cnt1;
  }else{
    asleep[f]=0;
    ways[f]=1;
  }
}

//fixed left cow, with hunger left[i]
//precondition: such cow exists
void calc_ways_stuck(int f){
  int b=std::upper_bound(cows[f].begin(),cows[f].end(),right[f])-cows[f].begin();
  if(right[f]>=left[f])
    b--;
  int cnt2=b;
  if(cnt2>0){
    asleep[f]=2;
    ways[f]=cnt2;
  }else{
    asleep[f]=1;
    ways[f]=1;
  }
}

int ans_asleep=0,ans_ways=0;

void add_to_ans(int asleep,int ways){
  if(asleep>ans_asleep){
    ans_asleep=asleep;
    ans_ways=0;
  }
  if(asleep==ans_asleep)
    ans_ways=(ans_ways+ways)%MOD;
}

int main(){
  int N,M;
  scanf("%d %d",&N,&M);
  for(int i=1;i<=N;i++){
    scanf("%d",&fs[i]);
    right[fs[i]]++;
  }
  for(int i=0;i<M;i++){
    int F,H;
    scanf("%d %d",&F,&H);
    cows[F].push_back(H);
  }
  for(int f=1;f<=N;f++)
    std::sort(cows[f].begin(),cows[f].end());
  for(int f=1;f<=N;f++){
    calc_ways(f);
    total_asleep+=asleep[f];
    total_ways=1LL*total_ways*ways[f]%MOD;
  }
  add_to_ans(total_asleep,total_ways);
  for(int i=1;i<=N;i++){
    total_asleep-=asleep[fs[i]];
    total_ways=1LL*total_ways*inverse(ways[fs[i]])%MOD;
    right[fs[i]]--;
    left[fs[i]]++;
    if(std::binary_search(cows[fs[i]].begin(),cows[fs[i]].end(),left[fs[i]])){
      calc_ways_stuck(fs[i]);
      int here_asleep=total_asleep+asleep[fs[i]];
      int here_ways=1LL*total_ways*ways[fs[i]]%MOD;
      add_to_ans(here_asleep,here_ways);
    }
    calc_ways(fs[i]);
    total_asleep+=asleep[fs[i]];
    total_ways=1LL*total_ways*ways[fs[i]]%MOD;
  }
  printf("%d %d\n",ans_asleep,ans_ways);
}


#include<bits/stdc++.h>
using namespace std;
#define mp(a,b) make_pair(a,b)
#define ff first
#define setp(a) setprecision(a)<<fixed
#define ss second
#define all(a) a.begin() , a.end()
#define revall(a) a.rbegin() , a.rend()
#define intt long long
#define ll long long
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define vvi vector< vi >
#define vipi vector<pair< pair<int,int > , int > >
#define vdb vector<double>
#define length(a) (int)(a.size())
#define fori(v) for(int i=0; i<v; i++)
#define forj(v) for(int j=0; j<v; j++)
#define fork(v) for(int k=0; k<v; k++)
#define forl(v) for(int l=0; l<v; l++)
#define fort(v) for(int t=0; t<v; t++)
#define forz(v) for(int z=0; z<v; z++)
#define MAX (int)(pow(10,7) + 10)
#define pb(a) push_back(a)
#define endl "\n"
#define bo ' '
ll gesas;
ll inf = 100000000000000000LL;
ll modulo = pow(10,9) + 7;
double eps = 1e-6;
const long long int mod = 998244353;
ll n ; const int kons=500001;
//vi values(2000,0);
vector< ll > valuesforcows[50];

ll min (ll a, ll b)
{return a<b ? a : b;}
const int N = 3e5 + 7;

int main() {
    ll k,z,d,g, m, t, b, c, e, x, y, x1, y1, x2, y2;string he = "YES" , yox = "NO";
    int n,a;
//    cin>>t;
//        while (t--)
//    {
    cin>>n>>m;
    map< pair<int,int> , int >cowmap;
    int f[m],h[m],s[n];
    for(int i=0;i<n;i++)
    {cin>>s[i];}
    fork(m)
    {cin>>f[k]>>h[k];
 valuesforcows[f[k]].pb(h[k]);
    cowmap[{f[k],h[k]}]++;
    }
    for (int l = 0; l <=n; ++l) {
        sort(all(valuesforcows[l]));
    }
    ll sayansmax=0,numberofways=1;
    vi cavab1 ,umberofways1;
    vi lefcounter,rigcounter,lefcounteragain;
    for(int i=0;i<n;i++)
    {
        lefcounter.clear();
        umberofways1.clear();
        rigcounter.clear();
        lefcounteragain.clear();
        cavab1.clear();
        for (int i1 = 0; i1 <=n ; ++i1) {
            cavab1.pb(0);
            umberofways1.pb(0);
        lefcounter.pb(0);
        rigcounter.push_back(0);
        lefcounteragain.pb(0);
        }

        for(int j=0;j<=i;j++)lefcounter[s[j]]++; for(int j=i+1;j<n;j++)rigcounter[s[j]]++;
if(!cowmap.count({s[i],lefcounter[s[i]]}))
    continue;
ll umberofways=0, cavab=0;
ll upbon = (upper_bound(all(valuesforcows[s[i]]),rigcounter[s[i]])-valuesforcows[s[i]].begin());
if(lefcounter[s[i]]<=rigcounter[s[i]])
    upbon--;
bool fra=0;
if(upbon)     cavab += 2,(umberofways+=upbon)%=modulo;
else cavab++,(umberofways=umberofways+1)%=modulo,fra=1;

//        cavab1.resize(n,0) ,umberofways1.resize(n,0);
for(int j=0;j<i && s[j]!=s[i];j++)
{lefcounteragain[s[j]]++;
    if(!cowmap.count({s[j],lefcounteragain[s[j]]}))
        continue;
    ll upbon = (upper_bound(all(valuesforcows[s[j]]),rigcounter[s[j]])-valuesforcows[s[j]].begin());
    bool cek =0;
    if(lefcounteragain[s[j]]<=rigcounter[s[j]])
        upbon--,cek=1;
    if(upbon) {
        if(cavab1[s[j]] <2)
        cavab1[s[j]]= 2,umberofways1[s[j]]=upbon;
    else if(cavab1[s[j]]==2)
        umberofways1[s[j]]+=upbon;
    }
    else {
        if(cavab1[s[j]] <1)
        {cavab1[s[j]]= 1;
        if(cek)
            umberofways1[s[j]]=2;
        else umberofways1[s[j]]=1;}
        else if(cavab1[s[j]]==1) {
            if(cek)
                umberofways1[s[j]]+=2;
            else umberofways1[s[j]]+=1;

        }
    }}
        for (int l = 0; l <i && cavab1[s[l]] && umberofways1[s[l]]; ++l) {
cavab += cavab1[s[l]];
umberofways*=umberofways1[s[l]];
        }
       ll r= cavab1[0];
        r=umberofways1[0];
if(cavab >sayansmax)
{    sayansmax = max(sayansmax, cavab);
if(fra)
numberofways = (umberofways*2)%modulo;
else numberofways = (umberofways)%modulo;
}
else if(cavab== sayansmax)
{if(fra)
    (numberofways +=(umberofways*2)%modulo)%=modulo;
else (numberofways +=umberofways)%=modulo;
}
//cavab1.clear(),umberofways1.clear();
//cout<<"How are you";
//valuesforcows->clear();
    }

cout<<sayansmax<<bo<<numberofways<<endl;

}


#include<bits/stdc++.h>
using namespace std;
#define mp(a,b) make_pair(a,b)
#define ff first
#define setp(a) setprecision(a)<<fixed
#define ss second
#define all(a) a.begin() , a.end()
#define revall(a) a.rbegin() , a.rend()
#define intt long long
#define ll long long
#define vi vector<int>
#define pi pair<int,int>
#define vpi vector<pi>
#define vvi vector< vi >
#define vipi vector<pair< pair<int,int > , int > >
#define vdb vector<double>
#define length(a) (int)(a.size())
#define fori(v) for(int i=0; i<v; i++)
#define forj(v) for(int j=0; j<v; j++)
#define fork(v) for(int k=0; k<v; k++)
#define forl(v) for(int l=0; l<v; l++)
#define fort(v) for(int t=0; t<v; t++)
#define forz(v) for(int z=0; z<v; z++)
#define MAX (int)(pow(10,7) + 10)
#define pb(a) push_back(a)
#define endl "\n"
#define bo ' '
ll gesas;
ll inf = 100000000000000000LL;
ll modulo = pow(10,9) + 7;
double eps = 1e-6;
const long long int mod = 998244353;
ll n ; const int kons=500001;
//vi values(2000,0);
vector< ll > valuesforcows[5005];

ll min (ll a, ll b)
{return a<b ? a : b;}
const int N = 3e5 + 7;

int main() {
    ll k,z,d,g, m, t, b, c, e, x, y, x1, y1, x2, y2;string he = "YES" , yox = "NO";
    int n,a;
//    cin>>t;
//        while (t--)
//    {
    cin>>n>>m;
    map< pair<int,int> , int >cowmap;
    int f[m],h[m],s[n+1];
    s[0]=0;
    for(int i=1;i<=n;i++)
    {cin>>s[i];}
    fork(m){cin>>f[k]>>h[k];
    valuesforcows[f[k]].pb(h[k]);
    cowmap[{f[k],h[k]}]++;}
    cowmap[{0,1}]++;
    for (int l = 0; l <=n; ++l) sort(all(valuesforcows[l]));
    ll sayansmax=0,numberofways=1;
    for(int i=0;i<n+1;i++){

        vi lefcounter(n+1,0),rigcounter(n+1,0);
//        for (int l = 0; l < n+1; ++l) lefcounter.push_back(0),rigcounter.push_back(0);
        for(int j=0;j<=i;j++)lefcounter[s[j]]++; for(int j=i+1;j<n+1;j++)rigcounter[s[j]]++;
if(!cowmap.count({s[i],lefcounter[s[i]]}))continue;
ll umberofways=0, cavab=0, upbon = (upper_bound(all(valuesforcows[s[i]]),rigcounter[s[i]])-valuesforcows[s[i]].begin());
if(lefcounter[s[i]]<=rigcounter[s[i]])upbon--;
if(upbon)     cavab += 2,(umberofways+=upbon)%=modulo;
else cavab++,(umberofways=umberofways+1)%=modulo;
if(!i)
    cavab--;
for(int ind =1;ind<=n ;ind++) {
    ll zupbon = (upper_bound(all(valuesforcows[ind]), rigcounter[ind]) - valuesforcows[ind].begin()), juppon = (upper_bound(all(valuesforcows[ind]),lefcounter[ind])-valuesforcows[ind].begin());
if(!zupbon  && !juppon )
    continue;
if( ind==s[i])
    continue;
    ll kuppon = zupbon;
    zupbon= zupbon*juppon-(min(zupbon,juppon));
if(zupbon)
{(umberofways *=zupbon)%=modulo;
cavab+=2;
    continue;}
(kuppon+=juppon)%=modulo;
    (umberofways*=kuppon)%=modulo;
    cavab++;}

if(cavab >sayansmax)
{    sayansmax = cavab;
 numberofways = (umberofways)%modulo;}
else if(cavab== sayansmax)
{(numberofways +=umberofways)%=modulo;}}
if(!sayansmax)
numberofways=1;
    cout<<sayansmax<<bo<<numberofways<<endl;}


#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                                cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = 1LL * vars * inv(pl[cownum] - 1) % MOD;
                vars = 1LL * vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum]) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(2, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            }
            vars = 1LL * vars * inv(get_probs(0, pl[cownum] - 1)) % MOD;
            vars = 1LL * vars * pp(get_probs(0, pl[cownum])) % MOD;
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum] - (pr[rnum] <= pl[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum] - (pl[cownum] <= pr[cownum])) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (rnum == cownum) {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                        } else {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                        }
                        update(cur_pshum, cur_pshars);
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (pre[v] != 0) {
        return pre[v];
    }
    return pre[v] = binpow(v, MOD - 2);
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

ll get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return 1;
    }
    if (x == 0) {
        return y;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return x * y - x;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * get_probs(pl[rnum], pr[rnum]) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {

                        //cout << "JJ " << i << " " << j << " " << cur_sum << " " << cur_vars << "\n";
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (rnum == cownum) {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                        } else {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                        }
                        update(cur_pshum, cur_pshars);
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(2, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = 1LL * vars * inv(pl[cownum] - 1) % MOD;
                vars = 1LL * vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum]) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = 1LL * vars * inv(pl[cownum] - 1) % MOD;
                vars = 1LL * vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum]) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

ll get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return 1;
    }
    if (x == 0) {
        return y;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return x * y - x;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * get_probs(pl[rnum], pr[rnum]) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {

                        //cout << "JJ " << i << " " << j << " " << cur_sum << " " << cur_vars << "\n";
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (rnum == cownum) {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                        } else {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                        }
                        update(cur_pshum, cur_pshars);
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = 1LL * vars * inv(pl[cownum] - 1) % MOD;
                vars = 1LL * vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum]) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            }
            vars = 1LL * vars * inv(get_probs(0, pl[cownum] - 1)) % MOD;
            vars = 1LL * vars * pp(get_probs(0, pl[cownum])) % MOD;
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum] - 1) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum] - 1) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(1, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                                cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(2, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            }
            vars = 1LL * vars * inv(get_probs(0, pl[cownum] - 1)) % MOD;
            vars = 1LL * vars * pp(get_probs(0, pl[cownum])) % MOD;
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum] - 1) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum] - 1) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef long long ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = tmp * tmp % MOD;
    if (y % 2) {
        return x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

ll get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return 1;
    }
    if (x == 0) {
        return y;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return x * y - x;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = vars * inv(pl[cownum] - 1) % MOD;
                vars = vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0LL, 0LL)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = cur_vars * get_probs(pl[rnum], pr[rnum]) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {

                        //cout << "JJ " << i << " " << j << " " << cur_sum << " " << cur_vars << "\n";
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (rnum == cownum) {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                        } else {
                            cur_pshars = cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            cur_pshars = cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pl[rnum]) % MOD;
                            cur_pshars = cur_pshars * max(1LL, pr[cownum]) % MOD;
                        }
                        update(cur_pshum, cur_pshars);
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <utility>
#include <iostream>
#include <cmath>
#include <deque>
#include <string>
#include <time.h>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <algorithm>
#include <bitset>

#define pii pair<ll,ll>
#define X first
#define Y second
#define mp make_pair

typedef int ll;
using namespace std;
#define N 1000000
#define OFF 200001
#define MOD 1000000007
#define C 13000
#define NN 1000000
ll n, x, k, z, m, pos, q, ans_v, y, root;
ll a[5005];
vector<ll> cows[5005];
ll stl[5005], str[5005];
ll pl[5005], pr[5005];
ll sum_col[5005], sumcow[5005];
ll suml[5005], sumr[5005];
ll pre[100500];
pii cur_ans;
void update(ll x, ll y) {
    if (y == 0) {
        return;
    }
    if (x > cur_ans.X) {
        cur_ans = mp(x, y);
    } else if (x == cur_ans.X) {
        cur_ans.Y += y;
        if (cur_ans.Y >= MOD) {
            cur_ans.Y -= MOD;
        }
    }
}

ll binpow(ll x, ll y) {
    if (y == 0) {
        return 1;
    }
    ll tmp = binpow(x, y / 2);
    tmp = 1LL * tmp * tmp % MOD;
    if (y % 2) {
        return 1LL * x * tmp % MOD;
    }
    return tmp;
}

ll inv(ll v) {
    if (v < 100000 && pre[v] != 0) {
        return pre[v];
    }
    if (v < 100000) {
        return pre[v] = binpow(v, MOD - 2);
    } else {
        return binpow(v, MOD - 2);
    }
}

ll inv(pii v) {
    ll x = v.X;
    ll y = v.Y;
    ll ans = 1;
    if (pre[x] == 0) {
        pre[x] = binpow(x, MOD - 2);
    }
    if (pre[y] == 0) {
        pre[y] = binpow(y, MOD - 2);
    }
    return 1LL * pre[x] * pre[y] % MOD;
}

ll get_sum(ll x, ll y) {
    if (x + y == 0) {
        return 0;
    }
    if (x == 0 || y == 0) {
        return 1;
    }
    if (x == 1 && y == 1) {
        return 1;
    }
    return 2;
}

pii get_probs(ll x, ll y) {
    if (x > y) {
        swap(x, y);
    }
    if (x + y == 0) {
        return mp(1, 1);
    }
    if (x == 0) {
        return mp(y, 1);
    }
    if (x == 1 && y == 1) {
        return mp(2, 1);
    }
    return mp(x, y - 1);
}

ll pp(pii x) {
    return x.X * x.Y;
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(0);
    string s;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i];
        sum_col[a[i]]++;
    }
    for (int i = 0; i < m; i++) {
        cin >> x >> y;
        cows[x].push_back(y);
        if (y <= sum_col[x]) {
            sumcow[x]++;
        }
    }
    ll ans = 1;
    ll pshe = 0;
    for (int i = 1; i <= n; i++) {
        if (sumcow[i] > 0) {
            ans = 1LL * ans * sumcow[i] % MOD;
            pshe++;
        }
    }

    update(pshe, ans * 2 % MOD);

    if (pshe == 0) {
        cout << "0 1\n";
        return 0;
    }
    for (int i = 1; i <= n; i++) {
        sort(cows[i].begin(), cows[i].end());
    }

    ll suml = 0;
    ll vars = 1;
    for (int i = 0; i < n; i++) {
        ll cownum = a[i];
        stl[cownum]++;
        pii fixed = mp(0, 0);
        if (pl[cownum] < cows[cownum].size() && cows[cownum][pl[cownum]] == stl[cownum]) {
            fixed = mp(cownum, stl[cownum]);
            pl[cownum]++;
            if (pl[cownum] == 1) {
                suml++;
            } else {
                vars = 1LL * vars * inv(pl[cownum] - 1) % MOD;
                vars = 1LL * vars * pl[cownum] % MOD;
            }
        }
        ll cur_vars = vars;
        ll cur_sum = suml;
        for (int j = 1; j <= n; j++) {
            pr[j] = 0;
            str[j] = 0;
        }
        if (fixed != mp(0, 0)) {
            //cout << fixed.X << " " << fixed.Y << "\n";
            for (int j = n - 1; j > i; j--) {
                ll rnum = a[j];
                str[rnum]++;
                if (pr[rnum] < cows[rnum].size() && cows[rnum][pr[rnum]] == str[rnum]) {
                    pr[rnum]++;
                    cur_sum -= get_sum(pr[rnum] - 1, pl[rnum]);
                    cur_sum += get_sum(pr[rnum], pl[rnum]);
                    cur_vars = 1LL * cur_vars * inv(get_probs(pl[rnum], pr[rnum] - 1)) % MOD;
                    cur_vars = 1LL * cur_vars * pp(get_probs(pl[rnum], pr[rnum])) % MOD;
                    if (mp(rnum, str[rnum]) != fixed) {
                        ll cur_pshum = cur_sum;
                        ll cur_pshars = cur_vars;
                        if (cur_pshum >= cur_ans.X) {
                            if (rnum == cownum) {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                            } else {
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[rnum], pr[rnum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * inv(get_probs(pl[cownum], pr[cownum])) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pl[rnum] - 1) % MOD;
                                cur_pshars = 1LL * cur_pshars * max(1, pr[cownum] - 1) % MOD;
                            }
                            update(cur_pshum, cur_pshars);
                        }
                    }
                }
            }
        }
    }
    if (cur_ans.X == 0) {
        cout << "0 1\n";
        return 0;
    } else {
        cout << cur_ans.X << " " << cur_ans.Y << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
/*    #include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;       */
using namespace std;

#define ll int
#define ull unsigned long long
#define f(a, b) for (ll i = a; i < b; i++)
#define mod 1000000007
#define pb push_back
#define vll vector<ll>
#define pll vector<pair<ll, ll>>
#define ld long double
#define fr(a, b) for (ll j = a; j >= b; j--)
#define fi(a, b) for (ll j = a; j < b; j++)
#define fii(a, b) for (ll k = a; k < b; k++)
//      typedef tree<ll
//      ,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>
//      ordered_set;

template <class T> ostream &operator<<(ostream &os, vector<T> V) {
  os << "[ ";
  for (auto v : V)
    os << v << " ";
  os << "]";
  return os;
}
template <class T> ostream &operator<<(ostream &os, set<T> S) {
  os << "{ ";
  for (auto s : S)
    os << s << " ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, map<L, R> M) {
  os << "{ ";
  for (auto m : M)
    os << "(" << m.first << ":" << m.second << ") ";
  return os << "}";
}
template <class L, class R> ostream &operator<<(ostream &os, pair<L, R> P) {
  return os << "(" << P.first << "," << P.second << ")";
}

inline ll mul(ll x, ll y, ll m) {
  x %= mod;
  y %= mod;
  long long z = 1LL * x * y;
  if (z >= m)
    z %= m;
  return z;
}
inline ll add(ll x, ll y, ll m) {
  long long z = x + y;
  if (z >= m)
    z %= m;
  return z;
}
inline ll sub(ll x, ll y, ll m) {
  long long z = x - y;
  if (z < 0)
    z += m;
  z %= m;
  return z;
}

const ll N = 5005;
ll n, m, a[N], f[N], h[N], tot[N], pr[N][N], su[N][N];
vll v[N];

int main() {
#ifndef ONLINE_JUDGE
  freopen("input.txt", "rt", stdin);
  freopen("output.txt", "wt", stdout);
#endif
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);

  cin >> n >> m;
  f(1, n + 1) cin >> a[i], tot[a[i]]++, pr[a[i]][i]++;
  f(1, n + 1) fi(1, n + 1) pr[i][j] += pr[i][j - 1],
      su[i][j] = tot[i] - pr[i][j];
  f(1, m + 1) {
    ll f, h;
    cin >> f >> h;
    v[f].pb(h);
  }
  f(1, n + 1) sort(v[i].begin(), v[i].end());
  ll ans = 0, ways = 1;
  f(1, n + 1) {
    ll l = pr[a[i]][i];
    ll l1 = lower_bound(v[a[i]].begin(), v[a[i]].end(), l) - v[a[i]].begin();
    if (l1 == v[a[i]].size() || l != v[a[i]][l1])
      continue;
    ll c = 0, w = 1;
    fi(1, n + 1) {
      if (j == a[i]) {
        ll k = su[j][i];
        ll k1 = upper_bound(v[j].begin(), v[j].end(), k) - v[j].begin() - 1;
        if (k1 != -1) {
          if (k1 == 0 && v[j][k1] == l) {
            c++;
            continue;
          }
          c += 2;
          if (v[j][k1] >= l)
            w = mul(w, k1, mod);
          else
            w = mul(w, (k1 + 1), mod);
          w %= mod;
        } else {
          c++;
        }
      } else {
        ll k1 = upper_bound(v[j].begin(), v[j].end(), pr[j][i]) - v[j].begin();
        ll k2 = upper_bound(v[j].begin(), v[j].end(), su[j][i]) - v[j].begin();
        if (k1 != 0 && k2 != 0) {
          if (k1 == k2 && k1 == 1)
            c++, w = mul(w, 2, mod);
          else
            c += 2, w = mul(w, sub(mul(k1, k2, mod), min(k1, k2), mod), mod);
          if (w < 0)
            w += mod;
          w %= mod;
        } else if (k1 == 0 && k2 == 0) {
          continue;
        } else {
          c++;
          if (k1 != 0)
            w = mul(w, k1, mod);
          else
            w = mul(w, k2, mod);
          w %= mod;
        }
        if (w < 0)
          w += mod;
      }
      if (w < 0)
        w += mod;
    }
    if (c > ans)
      ans = c, ways = w;
    else if (c == ans)
      ways = add(ways, w, mod);
  }
  ll c = 0, w = 1;
  f(1, n + 1) {
    if (v[i].size() > 0) {
      ll k = upper_bound(v[i].begin(), v[i].end(), tot[i]) - v[i].begin();
      if (k != 0)
        c++, w = mul(w, k, mod);
      w %= mod;
    }
  }
  if (c == ans && c != 0)
    ways = add(ways, w, mod);
  cout << ans << ' ' << ways << '\n';

#ifndef ONLINE_JUDGE
  cout << "\nTime Elapsed : " << 1000 * (ld)clock() / (ld)CLOCKS_PER_SEC
       << " ms\n";
#endif
  return 0;
}