#include <iostream>
#include <vector>
#include <stack>
#include <algorithm>
#include <cstring>

using namespace std;
int m;  int n;
bool visited[300005];
stack<int>s;
vector<int>graph[300005];
vector<int>rev_graph[300005];
void dfs(int node){
visited[node]=true;
for(int i=0; i<graph[node].size(); i++){
 int sosed=graph[node][i];
 if(visited[sosed]==false){
    dfs(sosed);
}

}
    s.push(node);
}
vector<int> cycles;
void rev_dfs(int r_node){
visited[r_node]=true;
    cycles.push_back(r_node);
for(int i=0; i<rev_graph[r_node].size(); i++){
 int rev_sosed=rev_graph[r_node][i];
 if(visited[rev_sosed]==false){
    rev_dfs(rev_sosed);
 }
}
}
int cost[300005];
int main()
{
    cin>> n;
    for(int i = 0; i < n; i++) {
        cin >> cost[i];
    }
    cin >> m;
        for(int i=0; i<m; i++){
        int a, b;
        cin>>a>>b;
            a--;
            b--;
            
        graph[b].push_back(a);
        rev_graph[a].push_back(b);
    }
    memset(visited,  false, sizeof visited);

    for(int i=0; i<n; i++){
        if(visited[i]==false){
            dfs(i);
        }
    }
    long long total_cost = 0, combs = 1;
    long long MOD = 1e9 + 7;
    memset(visited,false , sizeof visited);
    while(!s.empty()){
        int node=s.top();
        if(visited[node]==false){
            cycles.clear();
            rev_dfs(node);
            int min_cost = 2e9;
            for(int i = 0; i < cycles.size(); i++) {
                min_cost = min(min_cost, cost[cycles[i]]);
            }
            total_cost += min_cost;
            long long cnt = 0;
            for(int i  =0; i < cycles.size(); i++) {
                if(min_cost == cost[cycles[i]]) {
                    cnt++;
                }
            }
            combs *= cnt;
            combs %= MOD;
        }
        s.pop();
        
    }
    
    cout << total_cost << " " << combs << endl;
    return 0;
}
