#include <bits/stdc++.h>
using namespace std;
const int maxN = 1e5 + 2;
const int base = 1e9 + 7;
const int available = -1;
const int deleted = -2;
int k(0), n, m, a[maxN];
long long res, ans;
vector<int> adj[maxN];
multiset<int> sub[maxN];
int num[maxN], low[maxN];
stack<int> Stack;
template <typename T>
inline void Cin(T& x) {
  char c = getchar();
  x = 0;
  while (c < '0' || c > '9') c = getchar();
  while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
}
template <typename T, typename... Args>
inline void Cin(T& a, Args&... args) {
  Cin(a);
  Cin(args...);
}
void ReadInput() {
  Cin(n);
  for (int i = 1; i <= n; i++) Cin(a[i]);
  Cin(m);
  while (m--) {
    int u, v;
    Cin(u, v);
    adj[u].push_back(v);
  }
}
inline void Minimize(int& Target, int Value) {
  if (Value < Target) Target = Value;
}
void DFSVisit(int u) {
  static int Time = 0;
  num[u] = Time++;
  low[u] = maxN;
  Stack.push(u);
  for (int v : adj[u]) {
    if (num[v] == deleted) continue;
    if (num[v] != available)
      Minimize(low[u], num[v]);
    else {
      DFSVisit(v);
      Minimize(low[u], low[v]);
    }
  }
  if (low[u] >= num[u]) {
    int v;
    k++;
    do {
      v = Stack.top();
      Stack.pop();
      sub[k].insert(a[v]);
      num[v] = deleted;
    } while (v != u);
  }
}
void Tarjan() {
  fill(num + 1, num + n + 1, available);
  for (int u = 1; u <= n; ++u)
    if (num[u] == -1) DFSVisit(u);
}
void Sol() {
  res = 1;
  ans = 0;
  for (int i = 1; i <= k; i++) {
    auto it = sub[i].begin();
    ans = ans + *it;
    res = res * sub[i].count(*it) % base;
  }
  cout << ans << ' ' << res;
}
int main() {
  ReadInput();
  Tarjan();
  Sol();
}
