#include <bits/stdc++.h>
using namespace std;
const long long int maxn = 5100, inf = 1e17, mod = 1e9 + 7;
vector<long long int> f[maxn];
long long int pref[maxn][maxn];
signed main() {
  cin.tie(0);
  cout.tie(0);
  ios_base::sync_with_stdio(false);
  long long int n, m;
  cin >> n >> m;
  vector<long long int> mas(n, 0);
  for (long long int d = 0; d < n; d++) {
    cin >> mas[d];
    mas[d]--;
  }
  for (long long int d = 0; d < m; d++) {
    long long int f1, h1;
    cin >> f1 >> h1;
    f1--;
    f[f1].push_back(h1);
  }
  for (long long int d = 0; d < n; d++) {
    if (f[d].size() > 0) {
      sort(f[d].begin(), f[d].end());
    }
  }
  for (long long int d = 0; d < n; d++) {
    pref[0][d] = 0;
  }
  for (long long int d = 1; d <= n; d++) {
    for (long long int i = 0; i < n; i++) {
      pref[d][i] = pref[d - 1][i];
    }
    pref[d][mas[d - 1]]++;
  }
  long long int max1 = 0, cnt = 1;
  for (long long int d = 0; d <= n; d++) {
    if (d == 0) {
      long long int raz = 0;
      long long int cnt1 = 1;
      for (long long int i = 0; i < n; i++) {
        long long int kol1 = pref[n][i] - pref[d][i];
        long long int cnt2 = 1;
        bool check1 = 0;
        auto it1 = upper_bound(f[i].begin(), f[i].end(), kol1);
        if (it1 != f[i].begin()) {
          it1--;
          long long int dist = (it1 - f[i].begin()) + 1;
          cnt2 *= dist;
          check1 = 1;
        }
        if (check1) {
          raz += check1;
          cnt1 *= cnt2;
          cnt1 %= mod;
        }
      }
      if (raz == max1) {
        cnt += cnt1;
        cnt %= mod;
      }
      if (raz > max1) {
        max1 = raz;
        cnt = cnt1;
      }
      continue;
    }
    long long int f1 = mas[d - 1];
    long long int tkol = pref[d][f1];
    bool check = 0;
    auto it = lower_bound(f[f1].begin(), f[f1].end(), tkol);
    if (it != f[f1].end()) {
      if ((*it) == tkol) {
        check = 1;
      }
    }
    if (!check) {
      continue;
    }
    long long int raz = 0;
    long long int cnt1 = 1;
    for (long long int i = 0; i < n; i++) {
      long long int kol = pref[d][i];
      long long int kol1 = pref[n][i] - pref[d][i];
      auto it = upper_bound(f[i].begin(), f[i].end(), kol);
      long long int cnt2 = 1;
      long long int min1 = inf;
      bool check = 0;
      bool check1 = 0;
      long long int cn = 0;
      long long int dist1 = 0, dist2 = 0;
      if (i != f1) {
        if (it != f[i].begin()) {
          --it;
          dist1 = (it - f[i].begin()) + 1;
          cnt2 *= dist1;
          min1 = min(min1, dist1);
          check = 1;
        } else {
          min1 = 0;
        }
        auto it1 = upper_bound(f[i].begin(), f[i].end(), kol1);
        if (it1 != f[i].begin()) {
          it1--;
          dist2 = (it1 - f[i].begin()) + 1;
          cnt2 *= dist2;
          min1 = min(min1, dist2);
          check1 = 1;
        } else {
          min1 = 0;
        }
        cnt2 -= min1;
        long long int cn = check + check1;
        if (dist1 == 1 && dist2 == 1) {
          cn--;
          cnt2 = 2;
        }
        raz += cn;
        cnt1 *= cnt2;
        cnt1 %= mod;
      } else {
        check = 1;
        auto it = upper_bound(f[i].begin(), f[i].end(), kol1);
        if (it != f[i].begin()) {
          check1 = 1;
          it--;
          dist2 = (it - f[i].begin()) + 1;
          if ((*it) >= tkol) {
            dist2--;
          }
          if (dist2 == 0) {
            check1 = 0;
          } else {
            cnt2 *= dist2;
          }
        }
        if (check || check1) {
          raz += check;
          raz += check1;
          cnt1 *= cnt2;
          cnt1 %= mod;
        }
      }
    }
    if (raz == max1) {
      cnt += cnt1;
      cnt %= mod;
    }
    if (raz > max1) {
      max1 = raz;
      cnt = cnt1;
    }
  }
  if (max1 == 0) {
    cnt = 1;
  }
  cout << max1 << " " << cnt;
}
