#include <bits/stdc++.h>
using namespace std;
stack<int> s;
long long int sum = 0;
long long int com = 1;
long long int cur_type;
long long int cur_min;
void dfs(int node, vector<int> graph[], bool visited[]) {
  visited[node] = true;
  for (auto i : graph[node]) {
    if (visited[i] == false) {
      dfs(i, graph, visited);
    }
  }
  s.push(node);
}
void mod_dfs(int node, vector<int> graph[], bool visited[],
             long long int cost[]) {
  visited[node] = true;
  if (cost[node] < cur_min) {
    cur_min = cost[node];
    cur_type = 1;
  } else if (cost[node] == cur_min) {
    cur_type = (cur_type + 1) % 1000000007;
  }
  for (auto i : graph[node]) {
    if (visited[i] == false) {
      mod_dfs(i, graph, visited, cost);
    }
  }
}
int main() {
  int n;
  cin >> n;
  long long int cost[n];
  int i;
  for (i = 0; i < n; i++) {
    cin >> cost[i];
  }
  int m, node;
  cin >> m;
  vector<int> graph[n];
  vector<int> reverse_graph[n];
  int a, b;
  for (i = 0; i < m; i++) {
    cin >> a >> b;
    graph[a - 1].push_back(b - 1);
    reverse_graph[b - 1].push_back(a - 1);
  }
  bool visited[n];
  memset(visited, false, sizeof(visited));
  for (i = 0; i < n; i++) {
    if (visited[i] == false) {
      dfs(i, graph, visited);
    }
  }
  memset(visited, false, sizeof(visited));
  while (!s.empty()) {
    node = s.top();
    s.pop();
    if (!visited[node]) {
      cur_min = cost[node];
      cur_type = 0;
      mod_dfs(node, reverse_graph, visited, cost);
      sum += cur_min;
      com = (com * cur_type) % 1000000007;
    }
  }
  cout << sum << " " << com << "\n";
}
