#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int, int> pii;

const int MOD = (int)1e9 + 7;

int mult(int a, int b) {
    return (a * 1LL * b) % MOD;
}

const int N = 5050;

int s[N];
int l[N], r[N];
int pref[N][N];
set<int> cow[N];

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", &s[i]), --s[i];

    for (int i = 0; i < n; ++i) {
        for (int x = 0; x < n; ++x)
            pref[x][i + 1] = pref[x][i] + (s[i] == x);
    }

    while(m--) {
        int col, dist;
        scanf("%d %d", &col, &dist);
        --col;
        cow[col].insert(dist);
    }

    int mx = 0, cnt = 1;
    for (int x = 0; x < n; ++x) {
        l[x] = 0;
        r[x] = sz(cow[x]);
        int cur_cnt = 0;
        for (int h : cow[x])
            if (h <= pref[x][n]) ++cur_cnt;
        if (cur_cnt) {
            ++mx;
            cnt = mult(cnt, sz(cow[x]));
        }
    }

    for (int i = 0; i < n; ++i)
    {
        int x = s[i];
        if (cow[x].count(pref[x][n] - pref[x][i]))
            --r[x];
        if (!cow[x].count(pref[x][i + 1]))
            continue;
        ++l[x];

        /*
        for (int c = 0; c < n; ++c)
            printf("%d: %d %d\n", c, l[c], r[c]);
        printf("\n");
        */

        int cur_mx = 1, cur_cnt = 1;
        if (n - i - 1 >= i + 1) {
            if (r[x] > 1) {
                cur_mx = 2;
                cur_cnt = r[x] - 1;
            }
        }
        else {
            if (r[x] > 0) {
                cur_mx = 2;
                cur_cnt = r[x];
            }
        }
        //printf("%d %d\n", cur_mx, cur_cnt);

        for (int c = 0; c < n; ++c) {
            if (c == x) continue;
            //printf("%d %d\n", cur_mx, cur_cnt);
            int cnt_one, cnt_pair;
            cnt_one = l[c] + r[c];
            cnt_pair = min(l[c], r[c]) * (max(l[c], r[c]) - 1);
            if (cnt_pair != 0) {
                cur_mx += 2;
                cur_cnt = mult(cur_cnt, cnt_pair);
            } else if (cnt_one != 0) {
                cur_mx += 1;
                cur_cnt = mult(cur_cnt, cnt_one);
            }
        }

        //printf("%d %d\n\n\n", cur_mx, cur_cnt);

        if (cur_mx > mx) {
            mx = cur_mx;
            cnt = cur_cnt;
        } else if (cur_mx == mx) {
            cnt += cur_cnt;
            cnt %= MOD;
        }
    }

    printf("%d %d\n", mx, cnt);

}


#include <bits/stdc++.h>

using namespace std;

#define all(v) (v).begin(), (v).end()
#define sz(v) (int)(v).size()

typedef long long ll;
typedef pair<int, int> pii;

const int MOD = (int)1e9 + 7;

int mult(int a, int b) {
    return (a * 1LL * b) % MOD;
}

const int N = 5050;

int s[N];
int pref[N][N];
int l[N], r[N];
vector<int> cow[N];

int main()
{

#ifndef ONLINE_JUDGE
    freopen("input.txt", "r", stdin);
#endif

    int n, m;
    scanf("%d %d", &n, &m);
    for (int i = 0; i < n; ++i)
        scanf("%d", &s[i]), --s[i];

    for (int i = 0; i < n; ++i) {
        for (int x = 0; x < n; ++x)
            pref[x][i + 1] = pref[x][i] + (s[i] == x);
    }

    for (int i = 0; i < m; ++i) {
        int col, dist;
        scanf("%d %d", &col, &dist);
        --col;
        cow[col].push_back(dist);
    }

    int mx = 0, cnt = 1;
    for (int x = 0; x < n; ++x) {
        sort(all(cow[x]));
        l[x] = 0;
        r[x] = sz(cow[x]);
        if (!cow[x].empty()) {
            ++mx;
            cnt = mult(cnt, sz(cow[x]));
        }
    }

    for (int i = 0; i < n; ++i)
    {
        int x = s[i];
        auto it = lower_bound(all(cow[x]), n - i);
        if (it != cow[x].end() || *it == n - i)
            --r[x];
        it = lower_bound(all(cow[x]), i + 1);
        if (it == cow[x].end() || *it != i + 1)
            continue;
        ++l[x];

        //printf("%d %d %d\n", i + 1, l[0], r[0]);

        int cur_mx, cur_cnt;
        if (n - i - 1 >= i + 1) {
            if (r[x] > 1) {
                cur_mx = 2;
                cur_cnt = r[x] - 1;
            } else {
                cur_mx = 1;
                cur_cnt = 1;
            }
        }
        else {
            if (r[x] > 0) {
                cur_mx = 2;
                cur_cnt = r[x];
            } else {
                cur_mx = 1;
                cur_cnt = 1;
            }
        }

        for (int c = 0; c < n; ++c) {
            if (c == x) continue;
            //printf("%d %d\n", cur_mx, cur_cnt);
            ll ccnt;
            if (i + 1 <= n - i - 1) {
                ccnt = l[c] * 1LL * (r[c] - 1);
            } else {
                ccnt = r[c] * 1LL * (l[c] - 1);
            }
            if (ccnt != 0) {
                cur_mx += 2;
                cur_cnt = mult(cur_cnt, ccnt % MOD);
            } else {
                if (l[c] || r[c]) {
                    cur_mx += 1;
                    cur_cnt = mult(cur_cnt, l[c] + r[c]);
                }
            }
        }

        //printf("%d %d\n\n", cur_mx, cur_cnt);

        if (cur_mx > mx) {
            mx = cur_mx;
            cnt = cur_cnt;
        } else if (cur_mx == mx) {
            cnt += cur_cnt;
            cnt %= MOD;
        }
    }

    printf("%d %d\n", mx, cnt);

}


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

typedef long long ll;
const int maxn=5007;
const int inf=INT_MAX;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

vector<int> type[5007],cows[maxn];
vector<pii> v[5007];

int b[5007];

int ways2[maxn][maxn],ways1[maxn][maxn];
int a[5007];

//BIT
int d[maxn];

void init()
{
    for (int i=1;i<=5000;i++) d[i]=0;
}

void add(int x,int dd)
{
    for (int i=x;i<=5000;i+=(i&(-i))) d[i]+=dd;
}

int query(int x)
{
    if (x==0) return 0;
    int ret=0;
    for (int i=x;i>0;i-=(i&(-i))) ret+=d[i];
    return ret;
}
//

int32_t main()
{
    IOS
    int n,m;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        type[a[i]].pb(i);
    }
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        cows[x].pb(y);
        if (y<=sz(type[x])) b[type[x][y-1]]=y;
    }
    b[0]=inf;

    for (int i=1;i<=n;i++)
    {
        int N=sz(cows[i]);
        sort(all(cows[i]));
        for (int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                if (j!=k&&cows[i][j]-1<sz(type[i])-cows[i][k]
                    &&cows[i][j]-1<sz(type[i])&&sz(type[i])-cows[i][k]>=0)
                    v[i].pb(mkp(type[i][cows[i][j]-1],type[i][sz(type[i])-cows[i][k]]));
    }

    const int C=10008;
    for (int i=1;i<=n;i++)
    {
        if (sz(v[i])>0)
        {
            init();
            for (int j=0;j<=n;j++) v[i].pb(mkp(j,C+n-j));
            sort(all(v[i]));

            for (pii j:v[i])
            {
                if (j.S>C) ways2[i][j.F]=query(j.S-C);
                else add(j.S,1);
            }
        }
        for (int j:cows[i])
        {
            if (j>sz(type[i])) continue;
            for (int k=type[i][j-1];k<=n;k++) ways1[i][k]++;
            for (int k=type[i][sz(type[i])-j]-1;k>=0;k--) ways1[i][k]++;
        }
    }

    pair<ll,ll> ans=mkp(-1,-1);
    for (int i=0;i<=n;i++)
    {
        if (!b[i]) continue;
        ll nowans=1,nowcnt=0;
        for (int j=1;j<=n;j++)
        {
            if (a[i]==j)
            {
                int tmp=upper_bound(all(cows[j]),sz(type[j])-b[i])-cows[j].begin();
                //cout<<tmp<<endl;
                if (b[i]<=sz(type[j])-b[i]) tmp--;
                if (tmp==0) nowcnt++;
                else nowcnt+=2,nowans=(nowans*tmp)%mod;
            }
            else if (ways1[j][i]==0) continue;
            else if (ways2[j][i]==0) nowans=(nowans*ways1[j][i])%mod,nowcnt++;
            else nowans=(nowans*ways2[j][i])%mod,nowcnt+=2;
        }
       // cout<<i<<' '<<nowcnt<<' '<<nowans<<endl;
        if (nowcnt>ans.F) ans=mkp(nowcnt,nowans);
        else ans.S=(ans.S+nowans)%mod;
    }
    cout<<ans.F<<' '<<ans.S<<endl;
}


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

typedef long long ll;
const int maxn=1e6+7;
const int inf=INT_MAX;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

int32_t main()
{
    IOS
}


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

typedef long long ll;
const int maxn=5007;
const int inf=INT_MAX;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

vector<int> type[5007],cows[maxn];
vector<pii> v[5007];

int b[5007];

int ways2[maxn][maxn],ways1[maxn][maxn];
int a[5007];

//BIT
int d[maxn];

void init()
{
    for (int i=1;i<=5000;i++) d[i]=0;
}

void add(int x,int dd)
{
    for (int i=x;i<=5000;i+=(i&(-i))) d[i]+=dd;
}

int query(int x)
{
    if (x==0) return 0;
    int ret=0;
    for (int i=x;i>0;i-=(i&(-i))) ret+=d[i];
    return ret;
}
//

int32_t main()
{
    IOS
    int n,m;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        type[a[i]].pb(i);
    }
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        cows[x].pb(y);
        if (y<=sz(type[x])) b[type[x][y-1]]=y;
    }
    b[0]=inf;

    for (int i=1;i<=n;i++)
    {
        int N=sz(cows[i]);
        sort(all(cows[i]));
        for (int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                if (j!=k&&cows[i][j]-1<sz(type[i])-cows[i][k])
                    v[i].pb(mkp(type[i][cows[i][j]-1],type[i][sz(type[i])-cows[i][k]]));
    }

    const int C=10008;
    for (int i=1;i<=n;i++)
    {
        if (sz(v[i])>0)
        {
            init();
            for (int j=0;j<=n;j++) v[i].pb(mkp(j,C+n-j));
            sort(all(v[i]));

            for (pii j:v[i])
            {
                if (j.S>C) ways2[i][j.F]=query(j.S-C);
                else add(j.S,1);
            }
        }
        for (int j:cows[i])
        {
            if (j>sz(type[i])) continue;
            for (int k=type[i][j-1];k<=n;k++) ways1[i][k]++;
            for (int k=type[i][sz(type[i])-j]-1;k>=0;k--) ways1[i][k]++;
        }
    }

    pair<ll,ll> ans=mkp(-1,-1);
    for (int i=0;i<=n;i++)
    {
        if (!b[i]) continue;
        ll nowans=1,nowcnt=0;
        for (int j=1;j<=n;j++)
        {
            if (a[i]==j)
            {
                int tmp=upper_bound(all(cows[j]),sz(type[j])-b[i])-cows[j].begin();
                //cout<<tmp<<endl;
                if (b[i]<=sz(type[j])-b[i]) tmp--;
                if (tmp==0) nowcnt++;
                else nowcnt+=2,nowans=(nowans*tmp)%mod;
            }
            else if (ways1[j][i]==0) continue;
            else if (ways2[j][i]==0) nowans=(nowans*ways1[j][i])%mod,nowcnt++;
            else nowans=(nowans*ways2[j][i])%mod,nowcnt+=2;
        }
       // cout<<i<<' '<<nowcnt<<' '<<nowans<<endl;
        if (nowcnt>ans.F) ans=mkp(nowcnt,nowans);
        else if (nowcnt==ans.F) ans.S=(ans.S+nowans)%mod;
    }
    cout<<ans.F<<' '<<ans.S<<endl;
}


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

typedef long long ll;
const int maxn=5007;
const int inf=INT_MAX;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

vector<int> type[5007],cows[maxn];
vector<pii> v[5007];

int b[5007];

int ways2[maxn][maxn],ways1[maxn][maxn];
int a[5007];

//BIT
int d[maxn];

void init()
{
    for (int i=1;i<=5000;i++) d[i]=0;
}

void add(int x,int dd)
{
    for (int i=x;i<=5000;i+=(i&(-i))) d[i]+=dd;
}

int query(int x)
{
    if (x==0) return 0;
    int ret=0;
    for (int i=x;i>0;i-=(i&(-i))) ret+=d[i];
    return ret;
}
//

int32_t main()
{
    IOS
    int n,m;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        type[a[i]].pb(i);
    }
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        cows[x].pb(y);
        if (y<=sz(type[x])) b[type[x][y-1]]=y;
    }
    b[0]=inf;

    for (int i=1;i<=n;i++)
    {
        int N=sz(cows[i]);
        sort(all(cows[i]));
        for (int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                if (j!=k&&cows[i][j]-1<sz(type[i])-cows[i][k])
                    v[i].pb(mkp(type[i][cows[i][j]-1],n+1-type[i][sz(type[i])-cows[i][k]]));
    }

    const int C=10008;
    for (int i=1;i<=n;i++)
    {
        if (sz(v[i])>0)
        {
            init();
            for (int j=0;j<=n;j++) v[i].pb(mkp(j,C+n-j));
            sort(all(v[i]));

            for (pii j:v[i])
            {
                if (j.S>C) ways2[i][j.F]=query(j.S-C);
                else add(j.S,1);
            }
        }
        for (int j:cows[i])
        {
            if (j>sz(type[i])) continue;
            for (int k=type[i][j-1];k<=n;k++) ways1[i][k]++;
            for (int k=type[i][sz(type[i])-j]-1;k>=0;k--) ways1[i][k]++;
        }
    }

    pair<ll,ll> ans=mkp(-1,-1);
    for (int i=0;i<=n;i++)
    {
        if (!b[i]) continue;
        ll nowans=1,nowcnt=0;
        for (int j=1;j<=n;j++)
        {
            if (a[i]==j)
            {
                int tmp=upper_bound(all(cows[j]),sz(type[j])-b[i])-cows[j].begin();
                if (b[i]<=sz(type[j])-b[i]) tmp--;
                //cout<<tmp<<endl;
                if (tmp==0) nowcnt++;
                else nowcnt+=2,nowans=(nowans*tmp)%mod;
            }
            else if (ways1[j][i]==0) continue;
            else if (ways2[j][i]==0) nowans=(nowans*ways1[j][i])%mod,nowcnt++;
            else nowans=(nowans*ways2[j][i])%mod,nowcnt+=2;
        }
        //cout<<i<<' '<<nowcnt<<' '<<nowans<<endl;
        if (nowcnt>ans.F) ans=mkp(nowcnt,nowans);
        else if (nowcnt==ans.F) ans.S=(ans.S+nowans)%mod;
    }
    cout<<ans.F<<' '<<ans.S<<endl;
}


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

typedef long long ll;
const int maxn=5007;
const int inf=INT_MAX;
const ll inff=1e18;
const ll mod=1e9+7;
#define pii pair<int,int>
#define mkp make_pair
#define F first
#define S second
#define pb push_back
#define sz(v) ((int)(v).size())
#define all(v) (v).begin(),(v).end()
//#define int ll

#ifdef HNO2
#define IOS
#else
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#endif // HNO2

vector<int> type[5007],cows[maxn];
vector<pii> v[5007];

int b[5007],a[5007];
int ways2[maxn],ways1[maxn];

ll ans1[maxn],ans2[maxn];

//BIT
int d[maxn];

void init()
{
    for (int i=1;i<=5000;i++) d[i]=0;
}

void add(int x,int dd)
{
    for (int i=x;i<=5000;i+=(i&(-i))) d[i]+=dd;
}

int query(int x)
{
    if (x==0) return 0;
    int ret=0;
    for (int i=x;i>0;i-=(i&(-i))) ret+=d[i];
    return ret;
}
//

int32_t main()
{
    IOS
    int n,m;
    cin>>n>>m;
    for (int i=1;i<=n;i++)
    {
        cin>>a[i];
        type[a[i]].pb(i);
    }
    for (int i=1;i<=m;i++)
    {
        int x,y;
        cin>>x>>y;
        cows[x].pb(y);
        if (y<=sz(type[x])) b[type[x][y-1]]=y;
    }
    b[0]=inf;

    for (int i=1;i<=n;i++)
    {
        int N=sz(cows[i]);
        sort(all(cows[i]));
        for (int j=0;j<N;j++)
            for (int k=0;k<N;k++)
                if (j!=k&&cows[i][j]-1<sz(type[i])-cows[i][k])
                    v[i].pb(mkp(type[i][cows[i][j]-1],n+1-type[i][sz(type[i])-cows[i][k]]));
    }

    for (int i=0;i<=n;i++) ans1[i]=0,ans2[i]=1;

    const int C=10008;
    for (int i=1;i<=n;i++)
    {
        memset(ways1,0,sizeof(ways1));
        memset(ways2,0,sizeof(ways2));
        if (sz(v[i])>0)
        {
            init();
            for (int j=0;j<=n;j++) v[i].pb(mkp(j,C+n-j));
            sort(all(v[i]));

            for (pii j:v[i])
            {
                if (j.S>C) ways2[j.F]=query(j.S-C);
                else add(j.S,1);
            }
        }
        for (int j:cows[i])
        {
            if (j>sz(type[i])) continue;
            for (int k=type[i][j-1];k<=n;k++) ways1[k]++;
            for (int k=type[i][sz(type[i])-j]-1;k>=0;k--) ways1[k]++;
        }
        for (int j=0;j<=n;j++)
        {
             if (a[j]==i)
            {
                int tmp=upper_bound(all(cows[i]),sz(type[i])-b[j])-cows[i].begin();
                if (b[j]<=sz(type[i])-b[j]) tmp--;
                if (tmp==0) ans1[j]++;
                else ans1[j]+=2,ans2[j]=(ans2[j]*tmp)%mod;
            }
            else if (ways1[j]==0) continue;
            else if (ways2[j]==0) ans2[j]=(ans2[j]*ways1[j])%mod,ans1[j]++;
            else ans2[j]=(ans2[j]*ways2[j])%mod,ans1[j]+=2;
            //if (i==1) cout<<j<<' '<<ans1[j]<<' '<<ans2[j]<<endl;
        }
    }

    pair<ll,ll> ans=mkp(-1,-1);
    for (int i=0;i<=n;i++)
    {
        if (!b[i]) continue;
        ll nowans=ans2[i],nowcnt=ans1[i];
        if (nowcnt>ans.F) ans=mkp(nowcnt,nowans);
        else if (nowcnt==ans.F) ans.S=(ans.S+nowans)%mod;
    }
    cout<<ans.F<<' '<<ans.S<<endl;
}


/*/ Author---> adityapathak1630 /*/
/*/ Copyright © 2020 Aditya Pathak. All rights reserved. /*/
/*/_____________________________________________08-08-2019_____I WILL NEVER FORGET__________________________________________/*/

#include "bits/stdc++.h"

#define Nmax 5050
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fs first
#define sc second

using namespace std;

typedef long long ll;
int N, M;
int f, h, v[Nmax];
set<int> s;
vector<pair<int, int> > cows[Nmax];

int main()
{
  cin>>N>>M;
  for(int i=1;i<=N;++i)
  {
    cin>>v[i];
    s.insert(v[i]);
  }
  for(int i=1;i<=M;++i)
  {
    cin>>f>>h;

    int H = h, l = -1, r = -1;
    for(int j=1;j<=N;++j)
	{
      if(v[j] == f) --H;
      if(H == 0) {
        l = j;
        break;
      }
    }
    H = h;
    for(int j=N;j>=1;--j)
	{
      if(v[j] == f) --H;
      if(H == 0)
	  {
        r = j;
        break;
      }
    }
    if( l != -1)
	{
      cows[f].pb(mp(l, r));
    }
  }
  ll ret = -1, cnt = -1;

  for(int i=0;i<=N;++i)
  {
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1;
    for(auto x: s)
	{
      int L = 0, R = 0, both = 0;
      for(auto p: cows[x])
	  {
        int l = p.fs, r = p.sc;
        if( l == i )
		{
          ok = 1;
        }
		else
		if(l < i && r > i)
		{
          ++both;
        }
		else
		if(l < i)
		{
          ++L;
        }
		else
		if(r > i)
		{
          ++R;
        }
      }
      if(v[i] == x || i == 0)
	  {
        if(ok && i) ++rez;
        if(R || both)
		{
          ++rez;
          num = (num * (R + both)) % MOD;
        }
      }
	  else
	  {
        if(L*R || L*both || R*both || both >= 2)
		{
          rez += 2;
          ll ways = 0;
          ways += 1LL* L * R;
          ways += 1LL* L * both;
          ways += 1LL* both * R;
          ways += (1LL* both * (both - 1) / 2 );
          num = (num * ways) % MOD;
        }
		else
		if(L + R + both)
		{
          ++rez;
          if(L) num *= L;
          if(R) num *= R;
          if(both) num *= 2;
          num %= MOD;
        }
      }

    }
    if(!ok)
	continue;

    if(rez > ret)
	{
      ret = rez;
      cnt = num;
    }
    else
    if (rez == ret)
	{
      cnt = (cnt + num) % MOD;
    }
  }
  cout<<ret<<" "<<cnt<<"\n";
}


/*/ Author---> adityapathak1630 /*/
/*/ Copyright © 2020 Aditya Pathak. All rights reserved. /*/
/*/_____________________________________________08-08-2019_____I WILL NEVER FORGET__________________________________________/*/
                                                /*/___________500 ✌ __________/*/
#include "bits/stdc++.h"

#define Nmax 5050
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fs first
#define sc second

using namespace std;

typedef long long ll;
int N, M, v[Nmax];
set<int> s;
vector<pair<int, int> > cows[Nmax];

int main()
{
  cin>>N>>M;
  for(int i=1;i<=N;++i)
  {
    cin>>v[i];
    s.insert(v[i]);
  }

  for(int i=1;i<=M;++i)
  {
    int f, h;
	cin>>f>>h;

    int H = h, l = -1, r = -1;
    for(int j=1;j<=N;++j)
	{
      if(v[j] == f) --H;
      if(H == 0)
	  {
        l = j;
        break;
      }
    }

    H = h;
    for(int j=N;j>=1;--j)
	{
      if(v[j] == f) --H;
      if(H == 0)
	  {
        r = j;
        break;
      }
    }

    if( l != -1)
	{
      cows[f].pb(mp(l, r));
    }
  }

  ll ret = -1, cnt = -1;

  for(int i=0; i<=N; ++i)
  {
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1;

    for(auto x: s)
	{
      int L = 0, R = 0, both = 0;
      for(auto p: cows[x])
	  {
        int l = p.fs, r = p.sc;
        if( l == i )
		{
          ok = 1;
        }
		else
		if(l < i && r > i)
		{
          ++both;
        }
		else
		if(l < i)
		{
          ++L;
        }
		else
		if(r > i)
		{
          ++R;
        }
      }
      if(v[i] == x || i == 0)
	  {
        if(ok && i) ++rez; // only one extra way i think who knows idk
        if(R + both)
		{ // choose the righty
          ++rez;
          num = (num * (R + both)) % MOD;
        }
      }
	  else
	  {
        if(L*R || L*both || R*both || both >= 2)
		{
          rez += 2;

          ll ways = 0;
          ways += 1LL* L * R;
          ways += 1LL* L * both;
          ways += 1LL* both * R;
          ways += (1LL* both * (both - 1));

          num = (num * ways) % MOD;
        }
		else
		if(L + R + both)
		{
          ++rez;
          if(L) num *= L;
          if(R) num *= R;
          if(both) num *= 2;
          num %= MOD;
        }
      }
    }

    if(!ok)
	continue;

    if(rez > ret)
	{
      ret = rez;
      cnt = num;
    }
	else
	if (rez == ret)
	{
      cnt = (cnt + num) % MOD;
    }
  }
  cout<<ret<<" "<<cnt<<"\n";
}


/*/ Author---> adityapathak1630 /*/
/*/ Copyright © 2020 Aditya Pathak. All rights reserved. /*/
/*/_____________________________________________08-08-2019_____I WILL NEVER FORGET__________________________________________/*/

#include "bits/stdc++.h"

#define Nmax 5050
#define MOD 1000000007
#define mp make_pair
#define pb push_back
#define fs first
#define sc second

using namespace std;

typedef long long ll;
int N, M;
int f, h, v[Nmax];
set<int> s;
vector<pair<int, int> > cows[Nmax];

int main()
{
  cin>>N>>M;
  for(int i=1;i<=N;++i)
  {
    cin>>v[i];
    s.insert(v[i]);
  }
  for(int i=1;i<=M;++i)
  {
    cin>>f>>h;

    int H = h, l = -1, r = -1;
    for(int j=1;j<=N;++j)
	{
      if(v[j] == f) --H;
      if(H == 0) {
        l = j;
        break;
      }
    }
    H = h;
    for(int j=N;j>=1;--j)
	{
      if(v[j] == f) --H;
      if(H == 0)
	  {
        r = j;
        break;
      }
    }
    if( l != -1)
	{
      cows[f].pb(mp(l, r));
    }
  }
  ll ret = -1, cnt = -1;

  for(int i=0;i<=N;++i)
  {
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1;
    for(auto x: s)
	{
      int L = 0, R = 0, both = 0;
      for(auto p: cows[x])
	  {
        int l = p.fs, r = p.sc;
        if( l == i )
		{
          ok = 1;
        }
		else
		if(l < i && r > i)
		{
          ++both;
        }
		else
		if(l < i)
		{
          ++L;
        }
		else
		if(r > i)
		{
          ++R;
        }
      }
      if(v[i] == x || i == 0)
	  {
        if(ok && i) ++rez;
        if(R || both)
		{
          ++rez;
          num = (num * (R + both)) % MOD;
        }
      }
	  else
	  {
        if(L*R || L*both || R*both || both >= 2)
		{
          rez += 2;
          ll ways = 0;
          ways += 1LL* L * R;
          ways += 1LL* L * both;
          ways += 1LL* both * R;
          ways += (1LL* both * (both - 1) / 2 );
          num = (num * ways) % MOD;
        }
		else
		if(L + R + both)
		{
          ++rez;
          if(L) num *= L;
          if(R) num *= R;
          if(both) num *= 2;
          num %= MOD;
        }
      }

    }
    if(!ok)
	continue;

    if(rez > ret)
	{
      ret = rez;
      cnt = num;
    } else if (rez == ret)
	{
      cnt = (cnt + num) % MOD;
    }
  }
  cout<<ret<<" "<<cnt<<"\n";
}


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

typedef long long ll;

const int N=6000;
const int M=1000000007;

vector<int> g[N];
int ch[N], fa[N], s[N], l[N], r[N];
ll ans1, ans2;

ll rev(ll x) {
	ll ret=1, y=M-2; for (;y;y>>=1, x=x*x%M) if (y&1) ret=ret*x%M; return ret;
}
void cal(int c) {
	//printf("cal %d\n", c);
	int a = upper_bound(g[c].begin(), g[c].end(), l[c]) - g[c].begin();
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	int c1 = a*b-min(a,b);
	int c2 = a+b;
	if (c1>0) {
		ch[c]=2;
		fa[c]=c1;
	} else if (c2>0) {
		ch[c]=1;
		fa[c]=c2;
	} else {
		ch[c]=0;
		fa[c]=1;
	}
	//printf("%d %d\n", ch[c], fa[c]);
}
void cals(int c) {
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	if (r[c] >= l[c]) b--;
	if (b>0) {
		ch[c]=2;
		fa[c]=b;
	} else  {
		ch[c]=1;
		fa[c]=1;
	}
}

void update(int ans, int fas) {
//	printf("update %d %d\n", ans, fas);
	if (ans>ans1) ans1=ans, ans2=fas; else
	if (ans==ans1) ans2+=fas, ans2%=M;
}

int main()
{
	int n, m; scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) {
		scanf("%d", &s[i]);
		r[s[i]]++;
	}
	for (int i=1, f, h; i<=m; i++) {
		scanf("%d%d", &f, &h);
		g[f].push_back(h);
	}
	for (int i=1; i<=n; i++) sort(g[i].begin(), g[i].end());

	ll ans = 0, fas = 1;
	for (int i=1; i<=n; i++) if (g[i].size()) {
		cal(i);
		fas = fas * fa[i] % M;
		ans = ans + ch[i];
	//	printf("ch %d %d\n", ch[i], fa[i]);
	}
	update(ans, fas);

	for (int i=1; i<=n; i++) if (g[s[i]].size()){
		l[s[i]]++;
		r[s[i]]--;
		ans -= ch[s[i]];
		fas = fas * rev(fa[s[i]]) % M;
	//	printf("bf: %lld %lld\n", ans, fas);
		if (binary_search(g[s[i]].begin(), g[s[i]].end(), l[s[i]])) {
			cals(s[i]);
			ll tans = ans + ch[s[i]];
			ll tfas = fas * fa[s[i]] % M;
	//		printf("%d %d\n", tans, fas);
	//		printf("%d %d\n", ch[s[i]], fa[s[i]]);
			update(tans, tfas);
		}
		cal(s[i]);
		ans += ch[s[i]];
		fas = fas * fa[s[i]] % M;
	}
	printf("%lld %lld\n", ans1, ans2);
	return 0;
}


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

typedef long long ll;

const int N=6000;
const int M=1000000007;

vector<int> g[N];
int ch[N], fa[N], s[N], l[N], r[N];
ll ans1, ans2;

ll rev(ll x) {
	ll ret=1, y=M-2; for (;y;y>>=1, x=x*x%M) if (y&1) ret=ret*x%M; return ret;
}
void cal(int c) {
	//printf("cal %d\n", c);
	int a = upper_bound(g[c].begin(), g[c].end(), l[c]) - g[c].begin();
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	int c1 = a*b-min(a,b);
	int c2 = a+b;
	if (c1>0) {
		ch[c]=2;
		fa[c]=c1;
	} else if (c2>0) {
		ch[c]=1;
		fa[c]=c2;
	} else {
		ch[c]=0;
		fa[c]=1;
	}
	//printf("%d %d\n", ch[c], fa[c]);
}
void cals(int c) {
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	if (r[c] >= l[c]) b--;
	if (b>0) {
		ch[c]=2;
		fa[c]=b;
	} else {
		ch[c]=1;
		fa[c]=1;
	}
}

void update(int ans, int fas) {
	//printf("update %d %d\n", ans, fas);
	if (ans>ans1) ans1=ans, ans2=fas; else
	if (ans==ans1) ans2+=fas, ans2%=M;
}

int main()
{
	int n, m; scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) {
		scanf("%d", &s[i]);
		r[s[i]]++;
	}
	for (int i=1, f, h; i<=m; i++) {
		scanf("%d%d", &f, &h);
		g[f].push_back(h);
	}
	for (int i=1; i<=n; i++) sort(g[i].begin(), g[i].end());

	ll ans = 0, fas = 1;
	for (int i=1; i<=n; i++) if (g[i].size()) {
		cal(i);
		fas = fas * fa[i] % M;
		ans = ans + ch[i];
		update(ans, fas);
	}
	for (int i=1; i<=n; i++) {
		l[s[i]]++;
		r[s[i]]--;
		ans -= ch[s[i]];
		fas = fas * rev(fa[s[i]]) % M;
		if (binary_search(g[s[i]].begin(), g[s[i]].end(), l[s[i]])) {
			cals(s[i]);
			ll tans = ans + ch[s[i]];
			ll tfas = fas * fa[s[i]] % M;
			update(tans, tfas);
		}
		cal(s[i]);
		ans += ch[s[i]];
		fas = fas * fa[s[i]] % M;
	}
	printf("%lld %lld\n", ans1, ans2);
	return 0;
}


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

typedef long long ll;

const int N=6000;
const int M=1000000007;

vector<int> g[N];
int ch[N], fa[N], s[N], l[N], r[N];
ll ans1, ans2;

ll rev(ll x) {
	ll ret=1, y=M-2; for (;y;y>>=1, x=x*x%M) if (y&1) ret=ret*x%M; return ret;
}
void cal(int c) {
	//printf("cal %d\n", c);
	int a = upper_bound(g[c].begin(), g[c].end(), l[c]) - g[c].begin();
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	int c1 = a*b-min(a,b);
	int c2 = a+b;
	if (c1>0) {
		ch[c]=2;
		fa[c]=c1;
	} else if (c2>0) {
		ch[c]=1;
		fa[c]=c2;
	} else {
		ch[c]=0;
		fa[c]=1;
	}
	//printf("%d %d\n", ch[c], fa[c]);
}
void cals(int c) {
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	if (r[c] >= l[c]) b--;
	if (b>0) {
		ch[c]=2;
		fa[c]=b;
	} if (b==0) else {
		ch[c]=1;
		fa[c]=1;
	}
}

void update(int ans, int fas) {
//	printf("update %d %d\n", ans, fas);
	if (ans>ans1) ans1=ans, ans2=fas; else
	if (ans==ans1) ans2+=fas, ans2%=M;
}

int main()
{
	int n, m; scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) {
		scanf("%d", &s[i]);
		r[s[i]]++;
	}
	for (int i=1, f, h; i<=m; i++) {
		scanf("%d%d", &f, &h);
		g[f].push_back(h);
	}
	for (int i=1; i<=n; i++) sort(g[i].begin(), g[i].end());

	ll ans = 0, fas = 1;
	for (int i=1; i<=n; i++) if (g[i].size()) {
		cal(i);
		fas = fas * fa[i] % M;
		ans = ans + ch[i];
	//	printf("ch %d %d\n", ch[i], fa[i]);
	}
	update(ans, fas);

	for (int i=1; i<=n; i++) if (g[s[i]].size()){
		l[s[i]]++;
		r[s[i]]--;
		ans -= ch[s[i]];
		fas = fas * rev(fa[s[i]]) % M;
	//	printf("bf: %lld %lld\n", ans, fas);
		if (binary_search(g[s[i]].begin(), g[s[i]].end(), l[s[i]])) {
			cals(s[i]);
			ll tans = ans + ch[s[i]];
			ll tfas = fas * fa[s[i]] % M;
	//		printf("%d %d\n", tans, fas);
	//		printf("%d %d\n", ch[s[i]], fa[s[i]]);
			update(tans, tfas);
		}
		cal(s[i]);
		ans += ch[s[i]];
		fas = fas * fa[s[i]] % M;
	}
	printf("%lld %lld\n", ans1, ans2);
	return 0;
}


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

typedef long long ll;

const int N=6000;
const int M=1000000007;

vector<int> g[N];
int ch[N], fa[N], s[N], l[N], r[N];
ll ans1, ans2;

ll rev(ll x) {
	ll ret=1, y=M-2; for (;y;y>>=1, x=x*x%M) if (y&1) ret=ret*x%M; return ret;
}
void cal(int c) {
	//printf("cal %d\n", c);
	int a = upper_bound(g[c].begin(), g[c].end(), l[c]) - g[c].begin();
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	int c1 = a*b-min(a,b);
	int c2 = a+b;
	if (c1>0) {
		ch[c]=2;
		fa[c]=c1;
	} else if (c2>0) {
		ch[c]=1;
		fa[c]=c2;
	} else {
		ch[c]=0;
		fa[c]=1;
	}
	//printf("%d %d\n", ch[c], fa[c]);
}
void cals(int c) {
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	if (r[c] >= l[c]) b--;
	if (b>0) {
		ch[c]=2;
		fa[c]=b;
	} else {
		ch[c]=1;
		fa[c]=1;
	}
}

void update(int ans, int fas) {
	printf("update %d %d\n", ans, fas);
	if (ans>ans1) ans1=ans, ans2=fas; else
	if (ans==ans1) ans2+=fas, ans2%=M;
}

int main()
{
	int n, m; scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) {
		scanf("%d", &s[i]);
		r[s[i]]++;
	}
	for (int i=1, f, h; i<=m; i++) {
		scanf("%d%d", &f, &h);
		g[f].push_back(h);
	}
	for (int i=1; i<=n; i++) sort(g[i].begin(), g[i].end());

	ll ans = 0, fas = 1;
	for (int i=1; i<=n; i++) if (g[i].size()) {
		cal(i);
		fas = fas * fa[i] % M;
		ans = ans + ch[i];
		update(ans, fas);
	//	printf("ch %d %d\n", ch[i], fa[i]);
	}
	for (int i=1; i<=n; i++) if (g[s[i]].size()){
		l[s[i]]++;
		r[s[i]]--;
		ans -= ch[s[i]];
		fas = fas * rev(fa[s[i]]) % M;
	//	printf("bf: %lld %lld\n", ans, fas);
		if (binary_search(g[s[i]].begin(), g[s[i]].end(), l[s[i]])) {
			cals(s[i]);
			ll tans = ans + ch[s[i]];
			ll tfas = fas * fa[s[i]] % M;
	//		printf("%d %d\n", tans, fas);
	//		printf("%d %d\n", ch[s[i]], fa[s[i]]);
			update(tans, tfas);
		}
		cal(s[i]);
		ans += ch[s[i]];
		fas = fas * fa[s[i]] % M;
	}
	printf("%lld %lld\n", ans1, ans2);
	return 0;
}


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

typedef long long ll;

const int N=6000;
const int M=1000000007;

vector<int> g[N];
int ch[N], fa[N], s[N], l[N], r[N];
ll ans1, ans2;

ll rev(ll x) {
	ll ret=1, y=M-2; for (;y;y>>=1, x=x*x%M) if (y&1) ret=ret*x%M; return ret;
}
void cal(int c) {
	//printf("cal %d\n", c);
	int a = upper_bound(g[c].begin(), g[c].end(), l[c]) - g[c].begin();
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	int c1 = a*b-min(a,b);
	int c2 = a+b;
	if (c1>0) {
		ch[c]=2;
		fa[c]=c1;
	} else if (c2>0) {
		ch[c]=1;
		fa[c]=c2;
	} else {
		ch[c]=0;
		fa[c]=1;
	}
	//printf("%d %d\n", ch[c], fa[c]);
}
void cals(int c) {
	int b = upper_bound(g[c].begin(), g[c].end(), r[c]) - g[c].begin();
	if (r[c] >= l[c]) b--;
	if (b>0) {
		ch[c]=2;
		fa[c]=b;
	} else {
		ch[c]=1;
		fa[c]=1;
	}
}

void update(int ans, int fas) {
//	printf("update %d %d\n", ans, fas);
	if (ans>ans1) ans1=ans, ans2=fas; else
	if (ans==ans1) ans2+=fas, ans2%=M;
}

int main()
{
	int n, m; scanf("%d%d", &n, &m);
	for (int i=1; i<=n; i++) {
		scanf("%d", &s[i]);
		r[s[i]]++;
	}
	for (int i=1, f, h; i<=m; i++) {
		scanf("%d%d", &f, &h);
		g[f].push_back(h);
	}
	for (int i=1; i<=n; i++) sort(g[i].begin(), g[i].end());

	ll ans = 0, fas = 1;
	for (int i=1; i<=n; i++) if (g[i].size()) {
		cal(i);
		fas = fas * fa[i] % M;
		ans = ans + ch[i];
		update(ans, fas);
	//	printf("ch %d %d\n", ch[i], fa[i]);
	}
	for (int i=1; i<=n; i++) if (g[s[i]].size()){
		l[s[i]]++;
		r[s[i]]--;
		ans -= ch[s[i]];
		fas = fas * rev(fa[s[i]]) % M;
	//	printf("bf: %lld %lld\n", ans, fas);
		if (binary_search(g[s[i]].begin(), g[s[i]].end(), l[s[i]])) {
			cals(s[i]);
			ll tans = ans + ch[s[i]];
			ll tfas = fas * fa[s[i]] % M;
	//		printf("%d %d\n", tans, fas);
	//		printf("%d %d\n", ch[s[i]], fa[s[i]]);
			update(tans, tfas);
		}
		cal(s[i]);
		ans += ch[s[i]];
		fas = fas * fa[s[i]] % M;
	}
	printf("%lld %lld\n", ans1, ans2);
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int sww=1;sww<=n;sww++){
        for(int u: cws[sww]){
            int ate = go(u);
            if(ate == n+1)
                continue;
            int ans = 0;
            ll nn = 1;
            for(int sw=1;sw<=n;sw++){
                int cnt[4];
                cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
                for(int id: cws[sw]){
                    int val = 0;
                    if(go(id) <= ate)
                        val += 1;
                    if(bck(id) > ate)
                        val += 2;
                    if(id == u)
                        val = 1;
                    debug("(ate %d) vaca %d (go %d bck %d) val %d\n", ate, id, go(id), bck(id), val);
                    cnt[val]++;
                }
                if(sw == sww){
                    cnt[1] = 1;
                    cnt[2] += cnt[3];
                    cnt[3] = 0;
                }
                int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
                ans += val;
                if(val == 2){
                    nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
                }
                else if(val == 1){
                    nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
                }
            }
            if(res == ans){
                debug("com vaca %d andando ate %d ans %d e nn %lld\n", u, ate, ans, nn);
                nw = mod(nw + nn);
            }
            else if(res > ans){
                assert(false);
            }
        }
    }

    int ate = 0;
    int ans = 0;
    ll nn = 1;
    for(int sw=1;sw<=n;sw++){
        int cnt[4];
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        for(int id: cws[sw]){
            int val = 0;
            if(go(id) <= ate)
                assert(false);
            if(bck(id) > ate)
                val += 2;
            cnt[val]++;
        }
        int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        ans += val;
        if(val == 2){
            assert(false);
        }
        else if(val == 1){
            nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
        }
    }
    if(res == ans){
        debug("got a leftie ans %lld\n", nn);
        nw = mod(nw + nn);
    }
    else if(res < ans){
        debug("ans MAIOR res %d ans %d\n", res, ans);
        assert(false);
    }
    printf("%d %lld\n", res, nw);
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(2, cnt[3]),
                    max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1))
                    );
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int sww=1;sww<=n;sww++){
        for(int u: cws[sww]){
            int ate = go(u);
            if(ate == n+1)
                continue;
            int ans = 0;
            ll nn = 1;
            for(int sw=1;sw<=n;sw++){
                int cnt[4];
                cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
                for(int id: cws[sw]){
                    int val = 0;
                    if(go(id) <= ate)
                        val += 1;
                    if(bck(id) > ate)
                        val += 2;
                    if(id == u)
                        val = 1;
                    debug("(ate %d) vaca %d (go %d bck %d) val %d\n", ate, id, go(id), bck(id), val);
                    cnt[val]++;
                }
                if(sw == sww){
                    cnt[1] = 1;
                    cnt[2] += cnt[3];
                    cnt[3] = 0;
                }
                int val =  max(min(2, cnt[3]),
                    max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1))
                    );
                ans += val;
                if(val == 2){
                    nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
                }
                else if(val == 1){
                    nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
                }
            }
            if(res == ans){
                debug("com vaca %d andando ate %d ans %d e nn %lld\n", u, ate, ans, nn);
                nw = mod(nw + nn);
            }
            else if(res < ans){
                assert(false);
            }
        }
    }

    int ate = 0;
    int ans = 0;
    ll nn = 1;
    for(int sw=1;sw<=n;sw++){
        int cnt[4];
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        for(int id: cws[sw]){
            int val = 0;
            if(go(id) <= ate)
                assert(false);
            if(bck(id) > ate)
                val += 2;
            cnt[val]++;
        }
        int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        ans += val;
        if(val == 2){
            assert(false);
        }
        else if(val == 1){
            nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
        }
    }
    if(res == ans){
        debug("got a leftie ans %lld\n", nn);
        nw = mod(nw + nn);
    }
    else if(res < ans){
        debug("ans MAIOR res %d ans %d\n", res, ans);
        assert(false);
    }
    printf("%d %lld\n", res, nw);
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int sww=1;sww<=n;sww++){
        for(int u: cws[sww]){
            int ate = go(u);
            if(ate == n+1)
                continue;
            int ans = 0;
            ll nn = 1;
            for(int sw=1;sw<=n;sw++){
                int cnt[4];
                cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
                for(int id: cws[sw]){
                    int val = 0;
                    if(go(id) <= ate)
                        val += 1;
                    if(bck(id) > ate)
                        val += 2;
                    if(id == u)
                        val = 1;
                    debug("(ate %d) vaca %d (go %d bck %d) val %d\n", ate, id, go(id), bck(id), val);
                    cnt[val]++;
                }
                if(sw == sww){
                    cnt[1] = 1;
                    cnt[2] += cnt[3];
                    cnt[3] = 0;
                }
                int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
                ans += val;
                if(val == 2){
                    nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
                }
                else if(val == 1){
                    nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
                }
            }
            if(res == ans){
                debug("com vaca %d andando ate %d ans %d e nn %lld\n", u, ate, ans, nn);
                nw = mod(nw + nn);
            }
            else if(res < ans){
                assert(false);
            }
        }
    }

    int ate = 0;
    int ans = 0;
    ll nn = 1;
    for(int sw=1;sw<=n;sw++){
        int cnt[4];
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        for(int id: cws[sw]){
            int val = 0;
            if(go(id) <= ate)
                assert(false);
            if(bck(id) > ate)
                val += 2;
            cnt[val]++;
        }
        int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        ans += val;
        if(val == 2){
            assert(false);
        }
        else if(val == 1){
            nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
        }
    }
    if(res == ans){
        debug("got a leftie ans %lld\n", nn);
        nw = mod(nw + nn);
    }
    else if(res < ans){
        debug("ans MAIOR res %d ans %d\n", res, ans);
        assert(false);
    }
    printf("%d %lld\n", res, nw);
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) //fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int sww=1;sww<=n;sww++){
        for(int u: cws[sww]){
            int ate = go(u);
            if(ate == n+1)
                continue;
            int ans = 0;
            ll nn = 1;
            for(int sw=1;sw<=n;sw++){
                int cnt[4];
                cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
                for(int id: cws[sw]){
                    int val = 0;
                    if(go(id) <= ate)
                        val += 1;
                    if(bck(id) > ate)
                        val += 2;
                    if(id == u)
                        val = 1;
                    debug("(ate %d) vaca %d (go %d bck %d) val %d\n", ate, id, go(id), bck(id), val);
                    cnt[val]++;
                }
                if(sw == sww){
                    cnt[1] = 1;
                    cnt[2] += cnt[3];
                    cnt[3] = 0;
                }
                int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
                ans += val;
                if(val == 2){
                    nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
                }
                else if(val == 1){
                    nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
                }
            }
            if(res == ans){
                debug("com vaca %d andando ate %d ans %d e nn %lld\n", u, ate, ans, nn);
                nw = mod(nw + nn);
            }
        }
    }

    int ate = 0;
    int ans = 0;
    ll nn = 1;
    for(int sw=1;sw<=n;sw++){
        int cnt[4];
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        for(int id: cws[sw]){
            int val = 0;
            if(go(id) <= ate)
                assert(false);
            if(bck(id) > ate)
                val += 2;
            cnt[val]++;
        }
        int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        ans += val;
        if(val == 2){
            assert(false);
        }
        else if(val == 1){
            nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
        }
    }
    if(res == ans){
        debug("got a leftie ans %lld\n", nn);
        nw = mod(nw + nn);
    }

    /*for(int ate=0;ate<=n;ate++){
        int ans = 0;
        ll nn = 1;
        bool ok = (ate == 0);
        bool has1 = false;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) == ate)
                    ok = true;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
            ans += val;
            if(val == 2){
                nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
            }
            else if(val == 1){
                nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
            }
        }
        if(res == ans && ok){
            printf("ate %d nn %lld\n", ate, nn);
            nw = mod(nw + nn);
        }
    }*/
    printf("%d %lld\n", res, nw);
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) //fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int sww=1;sww<=n;sww++){
        for(int u: cws[sww]){
            int ate = go(u);
            if(ate == n+1)
                continue;
            int ans = 0;
            ll nn = 1;
            for(int sw=1;sw<=n;sw++){
                int cnt[4];
                cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
                for(int id: cws[sw]){
                    int val = 0;
                    if(go(id) <= ate)
                        val += 1;
                    if(bck(id) > ate)
                        val += 2;
                    if(id == u)
                        val = 1;
                    debug("(ate %d) vaca %d (go %d bck %d) val %d\n", ate, id, go(id), bck(id), val);
                    cnt[val]++;
                }
                if(sw == sww){
                    cnt[1] = 1;
                    cnt[2] += cnt[3];
                    cnt[3] = 0;
                }
                int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
                ans += val;
                if(val == 2){
                    nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
                }
                else if(val == 1){
                    nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
                }
            }
            if(res == ans){
                debug("com vaca %d andando ate %d ans %d e nn %lld\n", u, ate, ans, nn);
                nw = mod(nw + nn);
            }
            else if(res > ans){
                assert(false);
            }
        }
    }

    int ate = 0;
    int ans = 0;
    ll nn = 1;
    for(int sw=1;sw<=n;sw++){
        int cnt[4];
        cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
        for(int id: cws[sw]){
            int val = 0;
            if(go(id) <= ate)
                assert(false);
            if(bck(id) > ate)
                val += 2;
            cnt[val]++;
        }
        int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        ans += val;
        if(val == 2){
            assert(false);
        }
        else if(val == 1){
            nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
        }
    }
    if(res == ans){
        debug("got a leftie ans %lld\n", nn);
        nw = mod(nw + nn);
    }
    else if(res > ans){
        assert(false);
    }
    printf("%d %lld\n", res, nw);
}


#include <bits/stdc++.h>
using namespace std;
#define fst first
#define snd second
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int, int> pii;
#define pb push_back
#define for_tests(t, tt) int t; scanf("%d", &t); for(int tt = 1; tt <= t; tt++)
#ifndef ONLINE_JUDGE
#define debug(args...) fprintf(stderr,args)
#else
#define debug(args...)
#endif //ONLINE_JUDGE
template<typename T> inline T abs(T t) { return t < 0? -t : t; }
const ll modn = 1000000007;
inline ll mod(ll x) { return x % modn; }

const int MAXN = 5123;

int n, m, k;
int g[MAXN], s[MAXN], h[MAXN];
vector<int> pos[MAXN];

int go(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return n+1;
    return pos[sw][hg-1];
}

int bck(int id){
    int sw = s[id], hg = h[id];
    if(hg > pos[sw].size())
        return 0;
    return pos[sw][pos[sw].size() - hg];
}

vector<int> cws[MAXN];

int main (){
	scanf("%d%d", &n, &m);
	for(int a=1;a<=n;a++){
        scanf("%d", g+a);
        pos[g[a]].pb(a);
	}
    for(int a=0;a<m;a++){
        scanf("%d%d", s+a, h+a);
        cws[s[a]].pb(a);
    }
    int res = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            ans += max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
        }
        res = max(ans, res);
    }
    if(res == 0){
        puts("0 1");
        return 0;
    }
    ll nw = 0;
    for(int ate=0;ate<=n;ate++){
        int ans = 0;
        ll nn = 1;
        bool ok = false;
        for(int sw=1;sw<=n;sw++){
            int cnt[4];
            cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0;
            for(int id: cws[sw]){
                int val = 0;
                if(go(id) == ate)
                    ok = true;
                if(go(id) <= ate)
                    val += 1;
                if(bck(id) > ate)
                    val += 2;
                cnt[val]++;
            }
            int val = max(min(cnt[1] + cnt[3], 1) + min(cnt[2], 1),
                        min(cnt[1], 1) + min(cnt[2] + cnt[3], 1));
            ans += val;
            if(val == 2){
                nn = mod(nn*mod(cnt[1]*cnt[2] + cnt[3]*cnt[2] + cnt[3]*cnt[1] + cnt[3]*(cnt[3]-1)));
            }
            else if(val == 1){
                nn = mod(nn*(cnt[1] + cnt[2] + cnt[3]*2));
            }
        }
        if(res == ans && ok){
            nw = mod(nw + nn);
        }
    }
    printf("%d %lld\n", res, nw);
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					if(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR) ok=ok*2%MOD;
				}
				if(sz(go[col2])>=2)
				{
					if(col2==col)
					{
						pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;
						cnt++;ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
					}
					else
					{
						bool ok2=(go[col2][0].FR<tt.FR and go[col2][1].SE>tt.FR);
						bool ok3=(go[col2][1].FR<tt.FR and go[col2][0].SE>tt.FR);
						if(!ok2 and !ok3)
						{
							bool ok0=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);if(!ok0) continue;
							ok=ok*( calcL(col2,tt.FR)+calcR(col2,tt.FR) )%MOD;cnt++;
						}
						else
						{
							ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);
							for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;sum%=MOD;
							ok=ok*sum%MOD;cnt+=2;
						}
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					if(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR) ok=ok*2%MOD;
				}
				if(sz(go[col2])>=2)
				{
					ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);
					for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;
					if(sum) ok=ok*sum%MOD,cnt+=2;
					else
					{
						sum=calcL(col2,tt.FR)+calcR(col2,tt.FR);
						if(sum) ok=ok*sum%MOD,cnt++;
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					if(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR) ok=ok*2%MOD;
				}
				if(sz(go[col2])>=2)
				{
					if(col2==col)
					{
						pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;
						cnt++;ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
					}
					else
					{
						ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);
						for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;
						if(sum) ok=ok*sum%MOD,cnt+=2;
						else
						{
							sum=calcL(col2,tt.FR)+calcR(col2,tt.FR);
							if(sum) ok=ok*sum%MOD,cnt++;
						}
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(col2==col)
				{
					if(sz(go[col2])==1) continue;
					pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;
					cnt++;ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
				}
				else
				{
					ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;
					if(sum) ok=ok*sum%MOD,cnt+=2;
					else
					{
						sum=calcL(col2,tt.FR)+calcR(col2,tt.FR);
						if(sum) ok=ok*sum%MOD,cnt++;
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;
				fo(i,1,n){
				ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;}
				}
				int pos2=0,ned2=ned;fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0)  {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2});
				debug("col=%d ned=%d %d,%d\n",col,ned,pos1,pos2);
			}
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1,ok=0;ll ok2=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					ok+=(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR);
				}
				if(sz(go[col2])>=2)
				{
					if(col2==col)
					{
						pii oth=(go[col][go[col][0]==tt]);
						cnt+=(oth.SE>tt.FR);
					}
					else
					{
						bool ok2=(go[col2][0].FR<tt.FR or go[col2][1].SE>tt.FR);
						bool ok3=(go[col2][1].FR<tt.FR or go[col2][0].SE>tt.FR);
						if(ok2 and ok3) cnt+=2,ok+=1;
						else if(ok2 or ok3) cnt+=2;
						else
						{
							bool ok0=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
							bool ok1=(go[col2][1].FR<tt.FR or go[col2][1].SE>tt.FR);
							if((ok0|ok1)==0) continue;
							int tmp=int(go[col2][0].FR<tt.FR)+(go[col2][0].SE>tt.FR)+(go[col2][1].FR<tt.FR)+(go[col2][1].SE>tt.FR);
							ok2=ok2*tmp%MOD;cnt++;
						}
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%d ok2=%lld\n",col,tt.FR,tt.SE,cnt,ok,ok2);
			if(cnt>ans) ans=cnt,sum=qpower(2,ok)*ok2%MOD; else if(cnt==ans) add(sum,qpower(2,ok)*ok2%MOD);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1,ok=0;ll ok2=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2])) cnt+=(go[col2][0].SE>tt.SE);
			if(cnt>ans) ans=cnt,sum=qpower(2,ok)*ok2%MOD; else if(cnt==ans) add(sum,qpower(2,ok)*ok2%MOD);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(col2==col)
				{
					if(sz(go[col2])==1) continue;
					pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;
					cnt++;ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
				}
				else
				{
					ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.FR) sum--;
					if(sum) ok=ok*sum%MOD,cnt+=2;
					else
					{
						sum=calcL(col2,tt.FR)+calcR(col2,tt.FR);
						if(sum) ok=ok*sum%MOD,cnt++;
					}
				}
				debug("  col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					if(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR) ok=ok*2%MOD;
				}
				if(sz(go[col2])>=2)
				{
					if(col2==col)
					{
						pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;
						cnt++;ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
					}
					else
					{
						bool ok2=(go[col2][0].FR<tt.FR or go[col2][1].SE>tt.FR);
						bool ok3=(go[col2][1].FR<tt.FR or go[col2][0].SE>tt.FR);
						if(!ok2 and !ok3)
						{
							bool ok0=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);if(!ok0) continue;
							ok=ok*( calcL(col2,tt.FR)+calcR(col2,tt.FR) )%MOD;cnt++;
						}
						else
						{
							cnt+=2;
							ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);
							for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;sum%=MOD;
							ok=ok*sum%MOD;
						}
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


//Zory-2020
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
// typedef __int128 ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
#define FR first
#define SE second
#define MP make_pair
#define PB push_back
#define vc vector
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define bin(x) (1ll<<(x))
#define fo(i,l,r) for(int i=(l),I=(r);i<=I;i++)
#define fd(i,r,l) for(int i=(r),I=(l);i>=I;i--)
#define mem(x,val) memset(x,val,sizeof x)
#define Swap(a,b,n) for(int I=0;I<=n;I++) swap(a[I],b[I])
#define PC __builtin_popcountll
#ifdef DEBUG
#define DD 1
#else
#define DD 0
#endif
#define Debug if(DD) printf("line %d\n",__LINE__)
#define deb(x) if(DD) cerr<<#x<<'='<<x<<endl
#define debug if(DD) printf
namespace mine
{
	ll qread()
	{
		ll ans=0,f=1;char c=getchar();
		while(c<'0' or c>'9') {if(c=='-')f=-1;c=getchar();}
		while('0'<=c and c<='9') ans=ans*10+c-'0',c=getchar();
		return ans*f;
	}
	void write(ll num){if(num<0) putchar('-'),num=-num;if(num>=10) write(num/10);putchar('0'+num%10);}
	void write1(ll num){write(num);putchar(' ');}
	void write2(ll num){write(num);putchar('\n');}
	template<typename T>inline bool chmax(T&a,const T&b){return a<b?a=b,1:0;}
	template<typename T>inline bool chmin(T&a,const T&b){return a>b?a=b,1:0;}
	ll gcd(ll x,ll y){return y?gcd(y,x%y):x;}
	bool IN(ll x,ll l,ll r){return l<=x and x<=r;}
	void gg1(){write2(-1);exit(0);}
	void gg2(){puts("NO");exit(0);}

	const double eps=1e-8;
	const int INF=0x3f3f3f3f;
	const int MOD=1e9+7;
	int mm(const int x){return x>=MOD?x-MOD:x;}
	template<typename T> void add(T &x,const int &y){x=(x+y>=MOD?x+y-MOD:x+y);}
	ll qpower(ll x,ll e,int mod=MOD){ll ans=1;while(e){if(e&1)ans=ans*x%mod;x=x*x%mod;e>>=1;}return ans;}
	ll invm(ll x){return qpower(x,MOD-2);}
	const int N=1e6+10;

	int a[N];vc<int> ss[N];vc<pii> go[N];
	vc<int> L[N],R[N];
	ll calcL(int col,int pos)
	{
		return lower_bound(all(L[col]),pos)-L[col].begin();
	}
	ll calcR(int col,int pos)
	{
		return sz(R[col])-1-( upper_bound(all(R[col]),pos)-R[col].begin() )+1;
	}
	void main()
	{
		int n=qread(),m=qread();fo(i,1,n) a[i]=qread();
		fo(i,1,m) { int wt=qread(),ned=qread();ss[wt].PB(ned); }
		fo(col,1,n)
		{
			sort(all(ss[col]));
			for(auto ned:ss[col])
			{
				int pos1=INF,ned1=ned;fo(i,1,n){ ned1-=(a[i]==col);if(ned1==0) {pos1=i;break;} }
				int pos2=0,ned2=ned;  fd(i,n,1){ ned2-=(a[i]==col);if(ned2==0) {pos2=i;break;} }
				if(pos1<INF or pos2>0) go[col].PB({pos1,pos2}),L[col].PB(pos1),R[col].PB(pos2);
			}sort(all(R[col]));
		}int ans=0,sum=1;
		fo(col,1,n) for(auto tt:go[col]) if(tt.FR<INF)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n)
			{
				if(sz(go[col2])==1)
				{
					if(col2==col) continue;
					cnt+=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
					if(go[col2][0].FR<tt.FR and go[col2][0].SE>tt.FR) ok=ok*2%MOD;
				}
				if(sz(go[col2])>=2)
				{
					if(col2==col)
					{
						pii oth=(go[col][go[col][0]==tt]);if(oth.SE<=tt.FR) continue;cnt++;
						ok=ok*( calcR(col,tt.FR)-(tt.SE>tt.FR) )%MOD;
					}
					else
					{
						bool ok2=(go[col2][0].FR<tt.FR or go[col2][1].SE>tt.FR);
						bool ok3=(go[col2][1].FR<tt.FR or go[col2][0].SE>tt.FR);
						if(!ok2 and !ok3)
						{
							bool ok0=(go[col2][0].FR<tt.FR or go[col2][0].SE>tt.FR);
							bool ok1=(go[col2][1].FR<tt.FR or go[col2][1].SE>tt.FR);
							if((ok0|ok1)==0) continue;
							int tmp=int(go[col2][0].FR<tt.FR)+(go[col2][0].SE>tt.FR)+(go[col2][1].FR<tt.FR)+(go[col2][1].SE>tt.FR);
							ok=ok*tmp%MOD;cnt++;
						}
						else
						{
							cnt+=2;
							ll sum=calcL(col2,tt.FR)*calcR(col2,tt.FR);
							for(auto in:go[col2]) if(in.FR<tt.FR and in.SE>tt.SE) sum--;sum%=MOD;
							ok=ok*sum%MOD;
						}
					}
				}
			}
			debug("col=%d tt=%d,%d cnt=%d ok=%lld\n",col,tt.FR,tt.SE,cnt,ok);
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		fo(col,1,n) for(auto tt:go[col]) if(tt.SE>0)
		{
			int cnt=1;ll ok=1;
			fo(col2,1,n) if(col2!=col and sz(go[col2]) and go[col2][0].SE>tt.SE) cnt++,ok=ok*calcR(col2,tt.SE)%MOD;
			if(cnt>ans) ans=cnt,sum=ok; else if(cnt==ans) add(sum,ok);
		}
		write1(ans),write2(sum);
	}
};//变量重名！
signed main()
{
	#ifdef DEBUG
	//freopen("a.in","r",stdin);
	freopen("z.txt","r",stdin);
	#endif
	srand(time(0));
	mine::main();
	if(DD) cerr<<"\n---------------------Zory-------------------\nTime: " <<1.0*clock()/CLOCKS_PER_SEC<<"s";
}


#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 *= 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 == 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
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;

}