import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.StringTokenizer;

public class E {
    public static void main(String[] args) {
        var scanner = new BufferedScanner();
        var writer = new PrintWriter(new BufferedOutputStream(System.out));

        var n = scanner.nextInt();
        var m = scanner.nextInt();
        var s = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            s[i] = scanner.nextInt();
        }
        var f = new int[m + 1];
        var h = new int[m + 1];
        for (int i = 1; i <= m; i++) {
            f[i] = scanner.nextInt();
            h[i] = scanner.nextInt();
        }
        var ans = solve(n, m, s, f, h);
        writer.println(ans[0] + " " + ans[1]);

        scanner.close();
        writer.flush();
        writer.close();
    }

    static final int MODULO = (int) (1e9 + 7);

    static class IntList extends ArrayList<Integer> {}

    private static int[] solve(int n, int m, int[] s, int[] f, int[] h) {
        var sleepLeft = new int[m + 1];
        var sleepRight = new int[m + 1];
        var byFH = new HashMap<Integer, Integer>() {
            public Integer get(int f, int h) {
                return get(hash(f, h));
            }

            void put(int f, int h, int i) {
                put(hash(f, h), i);
            }

            private int hash(int f, int h) {
                return f * (n + 1) + h;
            }
        };
        for (int i = 1; i <= m; i++) {
            byFH.put(f[i], h[i], i);
        }
        {
            var countS = new int[n + 1];
            for (int i = 1; i <= n; i++) {
                countS[s[i]]++;
                var cow = byFH.get(s[i], countS[s[i]]);
                if (cow != null) {
                    sleepLeft[cow] = i;
                }
            }
            Arrays.fill(countS, 0);
            for (int i = n; i >= 1; i--) {
                countS[s[i]]++;
                var cow = byFH.get(s[i], countS[s[i]]);
                if (cow != null) {
                    sleepRight[cow] = i;
                }
            }
        }
//        var bySweet = new HashMap<Integer, List<Integer>>();
        var bySweet3 = new IntList[n + 1];
        for (int i = 1; i <= n; i++) {
            bySweet3[i] = new IntList();
        }
        var sweetSet = new HashSet<Integer>();
        for (int i = 1; i <= m; i++) {
//            bySweet.putIfAbsent(f[i], new ArrayList<>());
//            bySweet.get(f[i]).add(i);
            bySweet3[f[i]].add(i);
            sweetSet.add(f[i]);
        }
//        var sweets = bySweet.keySet().stream().mapToInt(i -> i).toArray();
        var sweets = sweetSet.stream().mapToInt(i -> i).toArray();
//        var bySweet2 = new int[n + 1][];
//        for (int sweet : sweets) {
//            bySweet2[sweet] = bySweet.get(sweet).stream().mapToInt(i -> i).toArray();
//        }
        var maxCows = Integer.MIN_VALUE;
        var maxWays = Long.MIN_VALUE;
        // first==0表示左边不选；first一定要用在左边，这样避免计数重复
        for (int first = 0; first <= m; first++) {
            var leftStart = 1;
            var leftEnd = sleepLeft[first];
            var rightStart = leftEnd + 1;
            var rightEnd = n;
            if (first != 0 && (sleepLeft[first] < leftStart || sleepLeft[first] > leftEnd)) {
                continue;
            }
            var cows = 0;
            var ways = 1L;
            for (int sweet : sweets) {
                var left = 0L;
                var right = 0L;
                var both = 0L;
                for (var i : bySweet3[sweet]) {
                    var t = 0;
                    if (sleepLeft[i] >= leftStart && sleepLeft[i] <= leftEnd) {
                        left++;
                        t++;
                    }
                    if (i == first) { // first一定在左边
                        continue;
                    }
                    if (sleepRight[i] >= rightStart && sleepRight[i] <= rightEnd) {
                        right++;
                        t++;
                    }
                    if (t == 2) {
                        both++;
                        left--;
                        right--;
                    }
                }
                if (sweet == f[first]) {
                    left = 1; // left被first占据了
                }
                if (left + right + both == 0) {
                    continue;
                }
                long thisWays;
                if (sweet == f[first]) {
                    thisWays = right + both;
                } else {
                    // 尝试任意放两个
                    thisWays = left * (right + both) + both * (right + both - 1);
                }
                if (thisWays > 0) {
                    cows += 2;
                    ways = (ways * thisWays) % MODULO;
                    continue;
                }
                cows++;
                // 放一个的方案
                thisWays = left + right + both * 2;
                ways = (ways * thisWays) % MODULO;
            }
            if (cows > maxCows) {
                maxCows = cows;
                maxWays = ways;
            } else if (cows == maxCows && cows > 0) {
                maxWays = (maxWays + ways) % MODULO;
            }
        }
        return new int[]{maxCows, (int) maxWays};
    }

    public static class BufferedScanner {
        BufferedReader br;
        StringTokenizer st;

        public BufferedScanner(Reader reader) {
            br = new BufferedReader(reader);
        }

        public BufferedScanner() {
            this(new InputStreamReader(System.in));
        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int nextInt() {
            return Integer.parseInt(next());
        }

        long nextLong() {
            return Long.parseLong(next());
        }

        double nextDouble() {
            return Double.parseDouble(next());
        }

        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            } catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }

        void close() {
            try {
                br.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

    }

    static long gcd(long a, long b) {
        if (a < b) {
            return gcd(b, a);
        }
        while (b > 0) {
            long tmp = b;
            b = a % b;
            a = tmp;
        }
        return a;
    }

    static long inverse(long a, long m) {
        long[] ans = extgcd(a, m);
        return ans[0] == 1 ? (ans[1] + m) % m : -1;
    }

    private static long[] extgcd(long a, long m) {
        if (m == 0) {
            return new long[]{a, 1, 0};
        } else {
            long[] ans = extgcd(m, a % m);
            long tmp = ans[1];
            ans[1] = ans[2];
            ans[2] = tmp;
            ans[2] -= ans[1] * (a / m);
            return ans;
        }
    }

    private static List<Integer> primes(double upperBound) {
        var limit = (int) Math.sqrt(upperBound);
        var isComposite = new boolean[limit + 1];
        var primes = new ArrayList<Integer>();
        for (int i = 2; i <= limit; i++) {
            if (isComposite[i]) {
                continue;
            }
            primes.add(i);
            int j = i + i;
            while (j <= limit) {
                isComposite[j] = true;
                j += i;
            }
        }
        return primes;
    }

}


#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
using namespace std;

//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5001
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               temp1=mat1[j][arr[j]];
               temp2=arr[j];
               if(temp2!=arr[i]  && cows[temp2][temp1]==1){
                  l[temp2]++;
                  cows[temp2][temp1]=-1;
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               temp2=arr[j];
               temp1 =cows[arr[j]][total[temp2]-mat1[j-1][arr[j]]];

               if(temp1==-1){
                  l[temp2]--;
                  b[temp2]++;
               }else{
                  if(temp1 ==1)
                  r[temp2]++;
               }

            }
         }

         if(i>1){
            FOR1(j,i-1,1){
               temp1=mat1[j][arr[j]];
               temp2=arr[j];
               if(temp2!=arr[i] && cows[temp2][temp1]==-1){
                  cows[temp2][temp1]=1;
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]));
               if(temp2>MOD)
                  temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=(l[j]+2*b[j]+r[j]);
                  if(temp2>MOD)
                     temp2%=MOD;
               }
            }
         }

         ans[temp1]+=temp2;
         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
using namespace std;

//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5001
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]  && cows[arr[j]][mat1[j][arr[j]]]==1){
                  l[arr[j]]++;
                  cows[arr[j]][mat1[j][arr[j]]]=-1;
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               temp1 =cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]];

               if(temp1==-1){
                  l[arr[j]]--;
                  b[arr[j]]++;
               }else{
                  if(temp1 ==1)
                  r[arr[j]]++;
               }

            }
         }

         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i] && cows[arr[j]][mat1[j][arr[j]]]==-1){
                  cows[arr[j]][mat1[j][arr[j]]]=1;
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]));
               if(temp2>MOD)
                  temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=(l[j]+2*b[j]+r[j]);
                  if(temp2>MOD)
                     temp2%=MOD;
               }
            }
         }

         ans[temp1]+=temp2;
         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int arr[sz2],ans[sz2], mat1[sz2][sz2],mat2[sz2][sz2];;
set<int> cows[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1,temp2;

   cin>>n>>m;

   FOR(i,1,n+1)
      cin>>arr[i];

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,m){
      cin>>f>>h;
      cows[f].insert(h);
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]].find(mat1[i][arr[i]])!=cows[arr[i]].end()){
         if(i!=0 )
            cows[arr[i]].erase(mat1[i][arr[i]]);
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]].find(mat1[j][arr[j]])!=cows[arr[j]].end()){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]].find(mat2[j][arr[j]]) != cows[arr[j]].end()){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;

         ans[temp1]+=temp2;

         if(i!=0)
            cows[arr[i]].insert(mat1[i][arr[i]]);
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   int cows[n+10][n+10];
   mset(cows);

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     cows[arr[j]][mat1[j][arr[j]]]=-1;
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]]){
                  if(cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]]==-1){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==-1){
                     cows[arr[j]][mat1[j][arr[j]]]=1;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

         ans[temp1]+=temp2;
         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
using namespace std;

//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5001
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;

         if(i>1){
            FOR1(j,i-1,1){
               temp1=mat1[j][arr[j]];
               temp2=arr[j];
               if(temp2!=arr[i]  && cows[temp2][temp1]==1){
                  l[temp2]++;
                  cows[temp2][temp1]=-1;
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               temp2=arr[j];
               temp1 =cows[arr[j]][total[temp2]-mat1[j-1][arr[j]]];

               if(temp1==-1){
                  l[temp2]--;
                  b[temp2]++;
               }else{
                  if(temp1 ==1)
                  r[temp2]++;
               }

            }
         }

         if(i>1){
            FOR1(j,i-1,1){
               temp1=mat1[j][arr[j]];
               temp2=arr[j];
               if(temp2!=arr[i] && cows[temp2][temp1]==-1){
                  cows[temp2][temp1]=1;
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]));
               if(temp2>MOD)
                  temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=(l[j]+2*b[j]+r[j]);
                  if(temp2>MOD)
                     temp2%=MOD;
               }
            }
            l[j]=r[j]=b[j]=0;
         }

         ans[temp1]+=temp2;
         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],mat2[sz2][sz2];

int ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   int cows[n+10][n+10];
   mset(cows);

   FOR(i,1,n+1)
      cin>>arr[i];
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;
   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]][mat2[j][arr[j]]] ==1){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;
         temp2+=ans[temp1];
         temp2%=MOD;

         ans[temp1]=temp2;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],mat2[sz2][sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1)
      cin>>arr[i];
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;
   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]][mat2[j][arr[j]]] ==1){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;

         ans[temp1]+=temp2;
         ans[temp1]%=MOD;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]  && cows[arr[j]][mat1[j][arr[j]]]==1){
                  l[arr[j]]++;
                  cows[arr[j]][mat1[j][arr[j]]]=-1;
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               temp1 =cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]];

               if(temp1==-1){
                  l[arr[j]]--;
                  b[arr[j]]++;
               }else{
                  if(temp1 ==1)
                  r[arr[j]]++;
               }

            }
         }

         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i] && cows[arr[j]][mat1[j][arr[j]]]==-1){
                  cows[arr[j]][mat1[j][arr[j]]]=1;
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]));
               if(temp2>MOD)
                  temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=(l[j]+2*b[j]+r[j]);
                  if(temp2>MOD)
                     temp2%=MOD;
               }
            }
         }

         ans[temp1]+=temp2;
         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],ans[sz2],mat1[sz2][sz2],mat2[sz2][sz2];;
set<int32_t> cows[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1,temp2;

   cin>>n>>m;

   FOR(i,1,n+1)
      cin>>arr[i];

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,m){
      cin>>f>>h;
      cows[f].insert(h);
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]].find(mat1[i][arr[i]])!=cows[arr[i]].end()){
         if(i!=0 )
            cows[arr[i]].erase(mat1[i][arr[i]]);
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]].find(mat1[j][arr[j]])!=cows[arr[j]].end()){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]].find(mat2[j][arr[j]]) != cows[arr[j]].end()){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;

         ans[temp1]+=temp2;
         ans[temp1]%=MOD;

         if(i!=0)
            cows[arr[i]].insert(mat1[i][arr[i]]);
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],mat2[sz2][sz2],cows[sz2][sz2];

int ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1)
      cin>>arr[i];
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;
   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]][mat2[j][arr[j]]] ==1){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;
         temp2+=ans[temp1];
         temp2%=MOD;

         ans[temp1]=temp2;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 500
#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t main(){
   fastio;

   int n,m,f,h,temp1,temp2;

   cin>>n>>m;

   int arr[n+1];

   FOR(i,1,n+1)
      cin>>arr[i];

   int ans[m+1];
   mset(ans);

   int mat1[n+10][n+10],mat2[n+10][n+10];
   mset(mat1);
   mset(mat2);

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   set<int> cows[n+1];

   FOR(i,0,m){
      cin>>f>>h;
      cows[f].insert(h);
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]].find(mat1[i][arr[i]])!=cows[arr[i]].end()){
         if(i!=0 )
            cows[arr[i]].erase(mat1[i][arr[i]]);
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]].find(mat1[j][arr[j]])!=cows[arr[j]].end()){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         FOR(j,i+1,n+1){

            if(cows[arr[j]].find(mat2[j][arr[j]])!=cows[arr[j]].end()){
               if(my.find({arr[j],mat2[j][arr[j]]})!=my.end()){
                  l[arr[j]]--;
                  b[arr[j]]++;
               }
               else{
                  r[arr[j]]++;
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;

         ans[temp1]+=temp2;

         if(i!=0 )
            cows[arr[i]].insert(mat1[i][arr[i]]);
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2];

int ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   int cows[n+10][n+10];
   mset(cows);

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

//   cout<<total[2]<<endl;

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
//                     cout<<j<<" "<<arr[j]<<" "<<mat1[j][arr[j]]<<endl;
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
//               cout<<j<<" "<<arr[j]<<" "<<total[arr[j]]-mat1[j-1][arr[j]]<<endl;
               if(cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]] ==1){
                  if(my.find({arr[j],total[arr[j]]-mat1[j-1][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;
         temp2+=ans[temp1];
         temp2%=MOD;

         ans[temp1]=temp2;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   int cows[n+10][n+10];
   mset(cows);

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

//   cout<<total[2]<<endl;

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
//                     cout<<j<<" "<<arr[j]<<" "<<mat1[j][arr[j]]<<endl;
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
//               cout<<j<<" "<<arr[j]<<" "<<total[arr[j]]-mat1[j-1][arr[j]]<<endl;
               if(cows[arr[j]][total[arr[j]]-mat1[j-1][arr[j]]] ==1){
                  if(my.find({arr[j],total[arr[j]]-mat1[j-1][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;
//         temp2+=ans[temp1];
//         temp2%=MOD;

         ans[temp1]+=temp2;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("avx2")
using namespace std;

//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5001
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],total[sz2],cows[sz2][sz2];

LL ans[sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   FOR(i,1,n+1){
      cin >> arr[i];
      total[arr[i]]++;
   }
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;

   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }
   int id=2;
   vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]=0;

         if(i>1){
            FOR1(j,i-1,1){
               temp1=mat1[j][arr[j]];
               temp2=arr[j];
               if(temp2!=arr[i]  && cows[temp2][temp1]){
                  l[temp2]++;
                  cows[temp2][temp1]=id;
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               temp2=arr[j];
               temp1 =cows[arr[j]][total[temp2]-mat1[j-1][arr[j]]];

               if(temp1==id){
                  l[temp2]--;
                  b[temp2]++;
               }else{
                  if(temp1)
                     r[temp2]++;
               }

            }
         }

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;

         id++;

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]));
               if(temp2>MOD)
                  temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=(l[j]+2*b[j]+r[j]);
                  if(temp2>MOD)
                     temp2%=MOD;
               }
            }
            l[j]=r[j]=b[j]=0;
         }

         ans[temp1]+=temp2;

      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<(ans[i]%MOD)<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#include<bits/stdc++.h>
using namespace std;
//g++-9 -Wl,-stack_size -Wl,100000000 test.cpp -o test
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>
//using namespace __gnu_pbds;
//#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
#define mp make_pair
#define f first
#define pb push_back
#define pob pop_back
#define s second
#define t third
#define MOD 1000000007
// #define MOD 987654319
//#define MOD 998244353
#define LL long long
#define  U_map unordered_map
#define PI 3.14159265
#define fastio  ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
#define INFF 9223372036854775807
#define INF 1000000000000000000
#define priorqmax priority_queue<LL>
#define priorqmin priority_queue<LL,vector<LL>,greater<LL> >
#define takein(a,b,c) for(LL  i=a;i<b;++i)cin>>c[i];
#define sz1 100010
#define sz2 5010
//#define int LL
#define vec(a) vector<a>
#define len length()
#define vii vector<int>
#define mapii map<int,int>
#define pairi pair<int,int>
#define mset(a) memset(a,0,sizeof(a))
#define FOR(j,a,n) for(int j=a;j<n;++j)
#define FOR1(j,a,n) for(int j=a;j>=n;--j)
#define debug1 cout<<"helo 1"<<endl;
#define debug2 cout<<"helo 2"<<endl;
class trio{public: int first,second, third;};
// ifstream iFile("input.txt");
// ofstream oFile("output.txt");

int32_t arr[sz2],mat1[sz2][sz2],mat2[sz2][sz2],cows[sz2][sz2];

int32_t main(){
   fastio;

   int n,m,f,h,temp1;
   LL temp2;

   cin>>n>>m;

   LL ans[sz2];

   FOR(i,1,n+1)
      cin>>arr[i];
   FOR(i,0,m){
      cin>>f>>h;
      cows[f][h]++;
   }

   FOR(i,1,n+1){
      FOR(j,1,n+1)
         mat1[i][j]=mat1[i-1][j];
      mat1[i][arr[i]]++;
   }

   FOR1(i,n,1){
      FOR1(j,n,1)
         mat2[i][j]=mat2[i+1][j];
      mat2[i][arr[i]]++;
   }

   FOR(i,0,n+1){
      if(i==0 || cows[arr[i]][mat1[i][arr[i]]]==1){
         if(i!=0 )
            cows[arr[i]][mat1[i][arr[i]]]--;
         set<pairi>my;

         vec(int) b(n+1,0),l(n+1,0),r(n+1,0);
         if(i>1){
            FOR1(j,i-1,1){
               if(arr[j]!=arr[i]){
                  if(cows[arr[j]][mat1[j][arr[j]]]==1){
                     l[arr[j]]++;
                     my.insert({arr[j],mat1[j][arr[j]]});
                  }
               }
            }
         }

         if(i<n){
            FOR(j,i+1,n+1){
               if(cows[arr[j]][mat2[j][arr[j]]] ==1){
                  if(my.find({arr[j],mat2[j][arr[j]]}) != my.end()){
                     l[arr[j]]--;
                     b[arr[j]]++;
                  }else{
                     r[arr[j]]++;
                  }
               }
            }
         }

         if(i==0)
            temp1=0;
         else
            temp1=1;

         temp2=1;

         FOR(j,1,n+1){
//            cout<<j<<" "<<l[j]<<" "<<r[j]<<" "<<b[j]<<endl;
            if((l[j]>0 && (r[j]+b[j]>0))  || (b[j]+l[j]>0 && r[j]>0 ) || b[j]>1){
               temp1+=2;
               temp2*=((l[j]*(b[j]+r[j]))+b[j]*(b[j]-1+r[j]))%MOD;
               temp2%=MOD;
            }
            else{
               if(b[j]>0 || l[j]>0 || r[j]>0){
                  temp1++;
                  temp2*=l[j]+2*b[j]+r[j];
                  temp2%=MOD;
               }
            }
         }

//         cout<<i<<" "<<temp1<<" "<<temp2<<endl;

         ans[temp1]+=temp2;
         ans[temp1]%=MOD;

         if(i!=0)
            cows[arr[i]][mat1[i][arr[i]]]=1;
      }
   }

   bool fl=1;

   FOR1(i,m,1){
      if(ans[i]>0){
         cout<<i<<" "<<ans[i]<<endl;
         fl=0;
         break;
      }
   }

   if(fl){
      cout<<"0 1";
   }

   return 0;
}


#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) { // rightmost left cow stops here
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1; // no left cows
    for(auto x: s) {
      int L = 0, R = 0, both = 0;
      for(auto c: cows[x]) {
        int l = c.fs, r = c.sc;
        if( l == i ) {
          ok = 1; // must include, all is well
        } else if(l < i && r > i) {
          ++both;
        } else if(l < i) {
          ++L;
        } else if(r > i) {
          ++R;
        }
      }
      if(v[i] == x) {
        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 += num;
    }
  }
  cout<<ret<<" "<<cnt<<"\n";
}


#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) { // rightmost left cow stops here
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1; // no left cows is ok

    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; // must include, all is well
        } 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) { // can do 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";
}


#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) { // rightmost left cow stops here
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1; // no left cows is ok
    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; // must include, all is well
        } 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>
#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) { // rightmost left cow stops here
    ll rez = 0, num = 1;
    int ok = 0;
    if(i == 0) ok = 1; // no left cows
    for(auto x: s) {
      int L = 0, R = 0, both = 0;
      for(auto c: cows[x]) {
        int l = c.fs, r = c.sc;
        if( l == i ) {
          ok = 1; // must include, all is well
        } else if(l < i && r > i) {
          ++both;
        } else if(l < i) {
          ++L;
        } else if(r > i) {
          ++R;
        }
      }
      if(v[i] == x) {
        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";
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define inf 1000000000
#define Inf 223372036854775807
#define maxn 5010
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const long double eps=1e-9;
const long double PI=acos(-1.0);

int n, m, s[maxn], maxres;
ll ans;
vector<int> cow[maxn];
unordered_map<int, int> l[maxn], r[maxn];

int main()
{
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        cin>>s[i];
    for (int i=1, f, h; i<=m; i++)
    {
        cin>>f>>h;
        cow[f].push_back(h);
    }
    for (int i=1; i<=n; i++)
    {
        int cnt=0;
        for (int j=1; j<=n; j++)
            if (s[j]==i)
                l[i][++cnt]=j;
        cnt=0;
        for (int j=n; j>=1; j--)
            if (s[j]==i)
                r[i][++cnt]=j;
    }
    for (int P=1; P<=n; P++)
    {
        int res=0;
        ll bufans=1;
        for (int i=1; i<=n; i++)
        {
            if (s[P]==i) continue;
            if (cow[i].size()==0) continue;
            int lf=0, rf=0, lr=0;
            for (auto j: cow[i])
            {
                if (l[i][j] && l[i][j]<P && r[i][j]>P) lr++;
                else if (l[i][j] && l[i][j]<P) lf++;
                else if (r[i][j]>P) rf++;
            }
            int temp=min(2, min(1, lf)+min(1, rf)+ min(2, lr));
            res+=temp;
            if (temp==2) bufans=bufans*(rf*lf+lr*lf+lr*rf+lr*(lr-1))%mod;
            else if (temp==1) bufans=bufans*(lf+rf+2*lr)%mod;
        }
        int f=0, fr=0, temp=0, tempans=0;
        for (auto j: cow[s[P]])
        {
            if (l[s[P]][j]==P) {f=1; continue;}
            if (r[s[P]][j]>P) fr++;
        }
        if (f) temp=f+min(1, fr), tempans=max(1, fr);
        res+=temp;
        if (temp) bufans=bufans*tempans%mod;
        if (temp && res>maxres) ans=0, maxres=res;
        if (temp && res==maxres) ans=(ans+bufans)%mod;
    }
    int res=0;
    ll bufans=1;
    for (int i=1; i<=n; i++)
    {
        if (cow[i].size()==0) continue;
        int rf=0;
        for (auto j: cow[i])
            if (r[i][j]>0) rf++;
        res+=min(1, rf);
        if (rf) bufans=bufans*rf%mod;
    }
    if (res>maxres) ans=0, maxres=res;
    if (res==maxres) ans=(ans+bufans)%mod;
    if (maxres=0) ans=1;
    cout<<maxres<<" "<<ans;
    return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define inf 1000000000
#define Inf 223372036854775807
#define maxn 5010
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const long double eps=1e-9;
const long double PI=acos(-1.0);

int n, m, s[maxn], maxres;
ll ans=1;
vector<int> cow[maxn];
unordered_map<int, int> l[maxn], r[maxn];

int main()
{
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        cin>>s[i];
    for (int i=1, f, h; i<=m; i++)
    {
        cin>>f>>h;
        cow[f].push_back(h);
    }
    for (int i=1; i<=n; i++)
    {
        int cnt=0;
        for (int j=1; j<=n; j++)
            if (s[j]==i)
                l[i][++cnt]=j;
        cnt=0;
        for (int j=n; j>=1; j--)
            if (s[j]==i)
                r[i][++cnt]=j;
    }
    for (int P=1; P<=n; P++)
    {
        int res=0;
        ll bufans=1;
        for (int i=1; i<=n; i++)
        {
            if (s[P]==i) continue;
            if (cow[i].size()==0) continue;
            int lf=0, rf=0, lr=0;
            for (auto j: cow[i])
            {
                if (l[i][j] && l[i][j]<P && r[i][j]>P) lr++;
                else if (l[i][j] && l[i][j]<P) lf++;
                else if (r[i][j]>P) rf++;
            }
            int temp=min(2, min(1, lf)+min(1, rf)+ min(2, lr));
            res+=temp;
            if (temp==2) bufans=bufans*(rf*lf+lr*lf+lr*rf+lr*(lr-1))%mod;
            else if (temp==1) bufans=bufans*(lf+rf+2*lr)%mod;
        }
        int f=0, fr=0, temp=0, tempans=0;
        for (auto j: cow[s[P]])
        {
            if (l[s[P]][j]==P) {f=1; continue;}
            if (r[s[P]][j]>P) fr++;
        }
        if (f) temp=f+min(1, fr), tempans=max(1, fr);
        res+=temp;
        if (temp) bufans=bufans*tempans%mod;
        if (temp && res>maxres) ans=0, maxres=res;
        if (temp && res==maxres) ans=(ans+bufans)%mod;
    }
    int res=0;
    ll bufans=1;
    for (int i=1; i<=n; i++)
    {
        if (cow[i].size()==0) continue;
        int rf=0;
        for (auto j: cow[i])
            if (r[i][j]>0) rf++;
        res+=min(1, rf);
        if (rf) bufans=bufans*rf%mod;
    }
    if (res>maxres) ans=0, maxres=res;
    if (res==maxres) ans=(ans+bufans)%mod;
    cout<<maxres<<" "<<ans;
    return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define inf 1000000000
#define Inf 223372036854775807
#define maxn 5010
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const long double eps=1e-9;
const long double PI=acos(-1.0);

int n, m, s[maxn], maxres;
ll ans=1;
vector<int> cow[maxn];
unordered_map<int, int> l[maxn], r[maxn];

int main()
{
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        cin>>s[i];
    for (int i=1, f, h; i<=m; i++)
    {
        cin>>f>>h;
        cow[f].push_back(h);
    }
    for (int i=1; i<=n; i++)
    {
        int cnt=0;
        for (int j=1; j<=n; j++)
            if (s[j]==i)
                l[i][++cnt]=j;
        cnt=0;
        for (int j=n; j>=1; j--)
            if (s[j]==i)
                r[i][++cnt]=j;
    }
    for (int P=1; P<=n; P++)
    {
        int res=0;
        ll bufans=1;
        for (int i=1; i<=n; i++)
        {
            if (s[P]==i) continue;
            if (cow[i].size()==0) continue;
            int lf=0, rf=0, lr=0;
            for (auto j: cow[i])
            {
                if (l[i][j] && l[i][j]<P && r[i][j]>P) lr++;
                else if (l[i][j] && l[i][j]<P) lf++;
                else if (r[i][j]>P) rf++;
            }
            int temp=min(2, min(1, lf)+min(1, rf)+ min(2, lr));
            res+=temp;
            if (temp==2) bufans=bufans*(rf*lf+lr*lf+lr*rf+lr*(lr-1))%mod;
            else if (temp==1) bufans=bufans*(lf+rf+2*lr)%mod;
        }
        int f=0, fr=0, temp=0, tempans=0;
        for (auto j: cow[s[P]])
        {
            if (l[s[P]][j]==P) {f=1; continue;}
            if (r[s[P]][j]>P) fr++;
        }
        if (f) temp=f+min(1, fr), tempans=max(1, fr);
        if (temp==1 || temp==0)
        {
            f=0;
            for (auto j: cow[s[P]])
                if (r[s[P]][j]==P) f=1;
            if (f) tempans++, temp=1;
        }
        res+=temp;
        if (temp) bufans=bufans*tempans%mod;
        if (temp && res>maxres) ans=0;
        if (temp) maxres=max(maxres, res);
        if (temp && res==maxres) ans=(ans+bufans)%mod;
    }
    cout<<maxres<<" "<<ans;
    return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define inf 1000000000
#define Inf 223372036854775807
#define maxn 5010
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const long double eps=1e-9;
const long double PI=acos(-1.0);

int n, m, s[maxn], maxres;
ll ans=1;
vector<int> cow[maxn];
unordered_map<int, int> l[maxn], r[maxn];

int main()
{
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        cin>>s[i];
    for (int i=1, f, h; i<=m; i++)
    {
        cin>>f>>h;
        cow[f].push_back(h);
    }
    for (int i=1; i<=n; i++)
    {
        int cnt=0;
        for (int j=1; j<=n; j++)
            if (s[j]==i)
                l[i][++cnt]=j;
        cnt=0;
        for (int j=n; j>=1; j--)
            if (s[j]==i)
                r[i][++cnt]=j;
    }
    for (int P=1; P<=n; P++)
    {
        int res=0;
        ll bufans=1;
        for (int i=1; i<=n; i++)
        {
            if (s[P]==i) continue;//*
            if (cow[i].size()==0) continue;
            int lf=0, rf=0, lr=0;
            for (auto j: cow[i])
            {
                if (l[i][j]!=0 && l[i][j]<P && r[i][j]>P) lr++;
                else if (l[i][j]!=0 && l[i][j]<P) lf++;
                else if (r[i][j]>P) rf++;
            }
            int temp=min(2, min(1, lf)+min(1, rf)+ min(2, lr));
            res+=temp;
            if (temp==2) bufans=bufans*(rf*lf+lr*lf+lr*rf+lr*(lr-1))%mod;
            else if (temp==1) bufans=bufans*(lf+rf+lr)%mod;
        }
        int f=0, fr=0, fl=0, temp=0, tempans=0;
        for (auto j: cow[s[P]])
        {
            if (l[s[P]][j]==P) {f=1; continue;}
            if (r[s[P]][j]>P) fr++;
        }
        if (f) temp=f+min(1, fr), tempans=max(1, fr);
        if (temp==1 || temp==0)
        {
            f=0;
            for (auto j: cow[s[P]])
                if (r[s[P]][j]==P) f=1;
            if (f) tempans++, temp=1;
        }
        res+=temp;
        if (temp) bufans=bufans*tempans%mod;
        if (temp && res>maxres) ans=0;
        if (temp) maxres=max(maxres, res);
        if (temp && res==maxres) ans=(ans+bufans)%mod;
        //if (temp)
        //    cout<<"P  "<<P<<" "<<temp<<" "<<bufans<<" "<<tempans<<" "<<ans<<endl;
    }
    cout<<maxres<<" "<<ans;
    return 0;
}


#pragma GCC optimize(3)
#include <bits/stdc++.h>
#define inf 1000000000
#define Inf 223372036854775807
#define maxn 5010
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
const long double eps=1e-9;
const long double PI=acos(-1.0);

int n, m, s[maxn], maxres;
ll ans;
vector<int> cow[maxn];
unordered_map<int, int> l[maxn], r[maxn];

int main()
{
    cin>>n>>m;
    for (int i=1; i<=n; i++)
        cin>>s[i];
    for (int i=1, f, h; i<=m; i++)
    {
        cin>>f>>h;
        cow[f].push_back(h);
    }
    for (int i=1; i<=n; i++)
    {
        int cnt=0;
        for (int j=1; j<=n; j++)
            if (s[j]==i)
                l[i][++cnt]=j;
        cnt=0;
        for (int j=n; j>=1; j--)
            if (s[j]==i)
                r[i][++cnt]=j;
    }
    for (int P=1; P<=n; P++)
    {
        int res=0;
        ll bufans=1;
        for (int i=1; i<=n; i++)
        {
            if (s[P]==i) continue;
            if (cow[i].size()==0) continue;
            int lf=0, rf=0, lr=0;
            for (auto j: cow[i])
            {
                if (l[i][j] && l[i][j]<P && r[i][j]>P) lr++;
                else if (l[i][j] && l[i][j]<P) lf++;
                else if (r[i][j]>P) rf++;
            }
            int temp=min(2, min(1, lf)+min(1, rf)+ min(2, lr));
            res+=temp;
            if (temp==2) bufans=bufans*(rf*lf+lr*lf+lr*rf+lr*(lr-1))%mod;
            else if (temp==1) bufans=bufans*(lf+rf+2*lr)%mod;
        }
        int f=0, fr=0, temp=0, tempans=0;
        for (auto j: cow[s[P]])
        {
            if (l[s[P]][j]==P) {f=1; continue;}
            if (r[s[P]][j]>P) fr++;
        }
        if (f) temp=f+min(1, fr), tempans=max(1, fr);
        res+=temp;
        if (temp) bufans=bufans*tempans%mod;
        if (temp && res>maxres) ans=0, maxres=res;
        if (temp && res==maxres) ans=(ans+bufans)%mod;
    }
    int res=0;
    ll bufans=1;
    for (int i=1; i<=n; i++)
    {
        if (cow[i].size()==0) continue;
        int rf=0;
        for (auto j: cow[i])
            if (r[i][j]>0) rf++;
        res+=min(1, rf);
        if (rf) bufans=bufans*rf%mod;
    }
    if (res>maxres) ans=0, maxres=res;
    if (res==maxres) ans=(ans+bufans)%mod;
    if (maxres==0) ans=1;
    cout<<maxres<<" "<<ans;
    return 0;
}


#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 color, dist;
        scanf("%d %d", &color, &dist);
        --color;
        if (dist <= pref[color][n]) {
            cow[color].insert(dist);
        }
    }

    int mx = 0, cnt = 1;
    for (int x = 0; x < n; ++x) {
        l[x] = 0;
        r[x] = sz(cow[x]);
        if (sz(cow[x])) {
            ++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_mx = r[x];
            } else {
                cur_mx = 1;
                cur_mx = 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]) {
                    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;

#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);
        if (dist <= pref[col][n]) {
            --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]);
        if (sz(cow[x])) {
            ++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);

}


use std::cmp::min;
use std::io;
use std::io::Stdin;
use std::str::FromStr;

fn read_line(stdin : &Stdin, line : &mut String) {
    match stdin.read_line(line) {
        Ok(_) => return,
        Err(msg) => panic!("Could not read line! Message: {}.", msg),
    }
}

fn parse_t<T : FromStr>(s : &str) -> T {
    match s.trim().parse() {
        Ok(y) => y,
        Err(_) => panic!("Could not read from string!"),
    }
}

fn read_ts<T : FromStr>(stdin : &Stdin, ts : &mut Vec<T>) {
    let mut line = String::new();
    read_line(stdin, &mut line);
    let word_iter = line.split_whitespace();
    for word in word_iter {
        let x = parse_t(word);
        ts.push(x);
    }
}

fn read_day_schedule(stdin : &Stdin, day_schedule : &mut Vec<usize>) {
    let zero_one = "01".as_bytes();
    let zero = zero_one[0];
    let one = zero_one[1];
    let mut str_schedule = String::new();
    read_line(&stdin, &mut str_schedule);
    let mut hour = 1;
    for &b in str_schedule.trim().as_bytes().iter() {
        if b == zero {
            // Do nothing ...
        } else if b == one {
            day_schedule.push(hour);
        } else {
            panic!("Unknown character in day schedule.");
        }
        hour = hour + 1;
    }
}

fn read_week_schedule(n : usize,
                      stdin : &Stdin,
                      week_schedule : &mut Vec<Vec<usize>>) {
    for _ in 0 .. n {
        let mut day_schedule = vec![];
        read_day_schedule(&stdin, &mut day_schedule);
        week_schedule.push(day_schedule);
    }
}

// Computes the optimal hours at school for a skip with
// given start and end hour.
fn optimal_skip_for_start_end(day_schedule : &Vec<usize>,
                                start_idx : usize,
                                end_idx : usize) -> (usize, usize, usize) {
    // If you are attending a single class, then skipping it
    // means, you don't have to go to school.
    if start_idx == end_idx {
        (0, start_idx, end_idx)
    } else {
        // Note that we reduce time spent at school, by only
        // skipping the first/last class.
        // Try skipping the first class.
        let skip_start_idx = start_idx + 1;
        let skip_end_idx = end_idx - 1;
        let start = day_schedule[start_idx];
        let start_after_skip = day_schedule[skip_start_idx];
        let end = day_schedule[end_idx];
        let end_after_skip = day_schedule[skip_end_idx];
        let skip_start_hours = end - start_after_skip + 1;
        let skip_end_hours = end_after_skip - start + 1;
        if skip_start_hours < skip_end_hours {
            (skip_start_hours, skip_start_idx, end_idx)
        } else if skip_start_hours > skip_end_hours {
            (skip_end_hours, start_idx, skip_end_idx)
        } else {
            if skip_start_hours <= 1 {
                (skip_start_hours, skip_start_idx, end_idx)
            } else {
                println!("(skip_start_hours > 1) && (skip_start_hours == skip_end_hours).");
                panic!("(skip_start_hours > 1) && (skip_start_hours == skip_end_hours).");
            }
        }
    }
}

fn optimal_skips_for_day(k : usize,
                         day_schedule : &Vec<usize>,
                         hours_at_school : &mut Vec<usize>) {
    // If there are no classes on a day, then hours at school
    // is 0 for all skips.
    if day_schedule.is_empty() {
        let k_plus_1 = k + 1;
        for _ in 0 .. k_plus_1 {
            hours_at_school.push(0);
        }
    } else {
        let mut done = false;
        let mut start_idx = 0;
        let mut end_idx = day_schedule.len() - 1;
        let hours_no_skip = day_schedule[end_idx] - day_schedule[start_idx] + 1;
        hours_at_school.push(hours_no_skip);
        let mut num_skips = 1;
        loop {
            if num_skips > k {
                break;
            } else {
                if start_idx == end_idx {
                    if done {
                        hours_at_school.push(0);
                    } else {
                        let (optimal_hours, new_start_idx, new_end_idx) =
                            optimal_skip_for_start_end(day_schedule,
                                                       start_idx,
                                                       end_idx);
                        hours_at_school.push(optimal_hours);
                        start_idx = new_start_idx;
                        end_idx = new_end_idx;
                        done = true;
                    }
                } else {
                    let (optimal_hours, new_start_idx, new_end_idx) =
                        optimal_skip_for_start_end(day_schedule,
                                                   start_idx,
                                                   end_idx);
                    hours_at_school.push(optimal_hours);
                    start_idx = new_start_idx;
                    end_idx = new_end_idx;
                }
            }
            num_skips = num_skips + 1;
        }
    }
}

fn update_min_hours_so_far(k : usize,
                           hours_at_school : &Vec<usize>,
                           min_hours_so_far : &Vec<usize>,
                           new_min_hours_so_far : &mut Vec<usize>) {
    let k_plus_1 = k + 1;
    for i in 0 .. k_plus_1 {
        let i_plus_1 = i + 1;
        for j in 0 .. i_plus_1 {
            let i_minus_j = i - j;
            let x = hours_at_school[j] + min_hours_so_far[i_minus_j];
            new_min_hours_so_far[i] = min(x, new_min_hours_so_far[i]);
        }
    }
}

const INFINITY : usize = usize::max_value();

fn min_hours_at_school(n : usize,
                       k : usize,
                       week_schedule : &Vec<Vec<usize>>) -> usize {
    let mut min_hours_so_far = vec![];
    optimal_skips_for_day(k, &(week_schedule[0]), &mut min_hours_so_far);
    for i in 1 .. n {
        let mut hours_at_school = vec![];
        optimal_skips_for_day(k, &(week_schedule[i]), &mut hours_at_school);
        // println!("{} -> {:?}", i, hours_at_school);
        let mut new_min_hours_so_far = vec![INFINITY; k + 1];
        update_min_hours_so_far(k,
                                &hours_at_school,
                                &min_hours_so_far,
                                &mut new_min_hours_so_far);
        min_hours_so_far = new_min_hours_so_far;
    }
    min_hours_so_far[k]
}

fn main() {
    let stdin = io::stdin();
    let mut n_m_k : Vec<usize> = vec![];
    read_ts(&stdin, &mut n_m_k);
    // println!("n_m_k = {:?}", n_m_k);
    let n = n_m_k[0];
    let k = n_m_k[2];
    let mut week_schedule = vec![];
    read_week_schedule(n, &stdin, &mut week_schedule);
    // println!("{:?}", week_schedule);
    let min_hours = min_hours_at_school(n, k, &week_schedule);
    println!("{}", min_hours);
}