#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#pragma GCC target("popcnt")
#pragma GCC target("avx2")
using namespace std;
template <typename T1, typename T2>
inline void mine(T1 &x, T2 y) {
  if (x > y) x = y;
}
template <typename T1, typename T2>
inline void maxe(T1 &x, T2 y) {
  if (x < y) x = y;
}
ostream &operator<<(ostream &a, const vector<long long> &b) {
  for (auto k : b) cout << k << ' ';
  return a;
}
const long long MOD = 1000000007;
const long long INF = 1000000050;
const long long BIG = (long long)2e18 + 50;
const long long MX = 5010;
const double EPS = 1e-9;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
long long leftb[MX];
long long rightb[MX];
long long f[MX];
long long h[MX];
vector<long long> leftf[MX];
vector<long long> rightf[MX];
long long who[MX];
long long res[MX];
long long s[MX];
int32_t main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  cout.tie(NULL);
  long long n, m;
  cin >> n >> m;
  for (long long i = 0; i < n; i++) {
    who[i] = -1;
    cin >> s[i];
    --s[i];
  }
  for (long long i = 0; i < m; i++) {
    cin >> f[i] >> h[i];
    --f[i];
    leftb[i] = INF;
    long long cnt = 0;
    for (long long j = 0; j < n; j++) {
      cnt += s[j] == f[i];
      if (cnt == h[i]) {
        leftb[i] = j;
        break;
      }
    }
    if (leftb[i] != INF) {
      who[leftb[i]] = i;
      leftf[f[i]].push_back(leftb[i]);
    }
    rightb[i] = -INF;
    cnt = 0;
    for (long long j = n - 1; j >= 0; j--) {
      cnt += s[j] == f[i];
      if (cnt == h[i]) {
        rightb[i] = j;
        break;
      }
    }
    if (rightb[i] != -INF) rightf[f[i]].push_back(rightb[i]);
  }
  for (long long i = 0; i < n; i++) {
    sort(leftf[i].begin(), leftf[i].end());
    sort(rightf[i].begin(), rightf[i].end());
  }
  long long mx = 0;
  for (long long i = -1; i < n; i++) {
    if (i != -1) {
      if (who[i] == -1) continue;
      long long cnt = 1;
      for (long long j = 0; j < n; j++) {
        if (s[i] == j) {
          long long canl = upper_bound(leftf[j].begin(), leftf[j].end(), i) -
                           leftf[j].begin();
          long long canr = rightf[j].end() -
                           upper_bound(rightf[j].begin(), rightf[j].end(), i);
          if (canr && (canr > 1 || canl > 1)) ++cnt;
        } else {
          long long canl = upper_bound(leftf[j].begin(), leftf[j].end(), i) -
                           leftf[j].begin();
          long long canr = rightf[j].end() -
                           upper_bound(rightf[j].begin(), rightf[j].end(), i);
          if ((canl && canr) && (canl > 1 || canr > 1)) {
            cnt += 2;
          } else if (canl || canr) {
            cnt++;
          }
        }
      }
      res[i + 1] = cnt;
      maxe(mx, cnt);
    } else {
      long long cnt = 0;
      for (long long j = 0; j < n; j++) {
        cnt += !rightf[j].empty();
      }
      res[i + 1] = cnt;
      maxe(mx, cnt);
    }
  }
  long long ways = 0;
  for (long long i = -1; i < n; i++) {
    if (res[i + 1] != mx) continue;
    if (i != -1) {
      long long cur = 1;
      for (long long j = 0; j < n; j++) {
        if (s[i] == j) {
          long long canl = upper_bound(leftf[j].begin(), leftf[j].end(), i) -
                           leftf[j].begin();
          long long canr = rightf[j].end() -
                           upper_bound(rightf[j].begin(), rightf[j].end(), i);
          if (canr && (canr > 1 || canl > 1)) {
            cur = cur * (canr < canl ? canr : canr - 1) % MOD;
          }
        } else {
          long long canl = upper_bound(leftf[j].begin(), leftf[j].end(), i) -
                           leftf[j].begin();
          long long canr = rightf[j].end() -
                           upper_bound(rightf[j].begin(), rightf[j].end(), i);
          if ((canl && canr) && (canl > 1 || canr > 1)) {
            cur = cur * (canl * canr - min(canl, canr)) % MOD;
          } else if (canl || canr) {
            cur = cur * (canl + canr) % MOD;
          }
        }
      }
      ways += cur;
    } else {
      long long cur = 1;
      for (long long j = 0; j < n; j++) {
        if (!rightf[j].empty()) cur = cur * (long long)rightf[j].size() % MOD;
      }
      ways += cur;
    }
  }
  if (mx == 0) {
    cout << "0 1\n";
  } else {
    cout << mx << ' ' << ways % MOD << '\n';
  }
}
