#include <bits/stdc++.h>
using namespace std;
struct node {
  int cur, pre;
} edge[300010];
int head[100010], cnt;
int n;
void init() {
  memset(head, -1, sizeof(head));
  cnt = 0;
}
void addEdge(int from, int cur) {
  edge[cnt].cur = cur;
  edge[cnt].pre = head[from];
  head[from] = cnt++;
}
int low[100010], dfn[100010], tme, ins[100010];
long long ans1, ans2, cost[100010];
stack<int> s;
void tarjan(int cur) {
  dfn[cur] = low[cur] = tme++;
  s.push(cur);
  ins[cur] = 1;
  for (int i = head[cur]; i != -1; i = edge[i].pre) {
    int to = edge[i].cur;
    if (!dfn[to]) {
      tarjan(to);
      low[cur] = min(low[cur], low[to]);
    } else if (ins[to]) {
      low[cur] = min(low[cur], dfn[to]);
    }
  }
  if (low[cur] == dfn[cur]) {
    int tmp;
    long long x, Min = 2000000000;
    do {
      tmp = s.top();
      s.pop();
      if (cost[tmp] < Min) {
        Min = cost[tmp];
        x = 0;
      }
      if (cost[tmp] == Min) x++;
      ins[tmp] = 0;
    } while (tmp != cur);
    ans1 += Min;
    ans2 = (ans2 * x) % 1000000007;
  }
}
void solve() {
  while (!s.empty()) {
    s.pop();
  }
  tme = 1, ans2 = 1;
  ans1 = 0;
  memset(low, 0, sizeof(low));
  memset(dfn, 0, sizeof(dfn));
  memset(ins, 0, sizeof(ins));
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) {
      tarjan(i);
    }
  }
  printf("%I64d %I64d\n", ans1, ans2);
}
int main() {
  int m;
  int a, b;
  scanf("%d", &n);
  init();
  for (int i = 1; i <= n; i++) scanf("%I64d", &cost[i]);
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    scanf("%d%d", &a, &b);
    addEdge(a, b);
  }
  solve();
  return 0;
}
