#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
#include<vector>
using namespace std;
const int MAX_SIZE = 12000;
const int INF = 0x3f3f3f3f;
struct Node{
int l, r;
Node *left, *right;
int minn, tag;
};
Node tree[MAX_SIZE * 2 + 10]; int tn;
inline void update(Node* cur, int v){
if(cur -> tag > v){
cur -> tag = v;
cur -> minn = min(cur -> minn, v);
}
}
inline void pushDown(Node* cur){
if(cur -> tag != INF){
if(cur -> l != cur -> r){
update(cur -> left, cur -> tag);
update(cur -> right, cur -> tag);
}
cur -> tag = INF;
}
}
Node* build(int l, int r){
Node* cur = tree + (tn ++);
cur -> l = l;
cur -> r = r;
cur -> minn = cur -> tag = INF;
if(l != r){
int mid = (l + r) >> 1;
cur -> left = build(l, mid);
cur -> right = build(mid + 1, r);
}
return cur;
}
Node* sroot;
struct O{
int id, co;
};
vector<int> event[MAX_SIZE + 10];
multiset<int> s[MAX_SIZE * 2 + 10];
int val[MAX_SIZE * 2 + 10], vn;
int data[MAX_SIZE + 10], n;
int nodes[MAX_SIZE + 10], nxt[MAX_SIZE * 2 + 10], to[MAX_SIZE * 2 + 10], en;
int len[MAX_SIZE * 2 + 10];
int m;
bool vis[MAX_SIZE + 10];
int root, minn, tot, size[MAX_SIZE + 10];
O cg[MAX_SIZE + 10];
int dist[MAX_SIZE + 10], clist[MAX_SIZE + 10], cn;
int cco[MAX_SIZE + 10];
int pre[MAX_SIZE * 2 + 10], tVal[MAX_SIZE * 2 + 10];
inline void addEdge(int f, int t, int w){
++ en;
to[en] = t;
len[en] = w;
nxt[en] = nodes[f];
nodes[f] = en;
}
void dfs(int cur, int fa){
size[cur] = 1;
for(int e = nodes[cur]; e; e = nxt[e]){
if(to[e] == fa || vis[to[e]])
continue;
dfs(to[e], cur);
size[cur] += size[to[e]];
}
}
void findRoot(int cur, int fa){
int maxn = tot - size[cur];
for(int e = nodes[cur]; e; e = nxt[e]){
if(to[e] == fa || vis[to[e]])
continue;
if(size[to[e]] > maxn)
maxn = size[to[e]];
findRoot(to[e], cur);
}
if(maxn < minn){
minn = maxn;
root = cur;
}
}
void dfsDist(int cur, int fa){
int si = (int)event[cur].size();
for(int i = 0; i < si; i ++)
clist[++ cn] = event[cur][i];
cco[cur] = data[cur];
int p = lower_bound(val, val + vn, data[cur]) - val;
s[p].insert(dist[cur]);
if((int)s[p].size() > 1){
set<int>::iterator it = s[p].begin();
int d = *it;
++ it;
d += *it;
if(tVal[p] > d)
tVal[p] = d;
}
for(int e = nodes[cur]; e; e = nxt[e]){
if(to[e] == fa || vis[to[e]])
continue;
dist[to[e]] = dist[cur] + len[e];
dfsDist(to[e], cur);
}
}
void change(Node* cur, int l, int r, int v){
if(cur -> l == l && cur -> r == r){
update(cur, v);
return;
}
pushDown(cur);
int mid = (cur -> l + cur -> r) >> 1;
if(r <= mid)
change(cur -> left, l, r, v);
else if(l > mid)
change(cur -> right, l, r, v);
else{
change(cur -> left, l, mid, v);
change(cur -> right, mid + 1, r, v);
}
cur -> minn = min(cur -> left -> minn, cur -> right -> minn);
}
void clear(int cur, int fa){
int p = lower_bound(val, val + vn, cco[cur]) - val;
s[p].clear();
p = lower_bound(val, val + vn, data[cur]) - val;
change(sroot, pre[p], m, tVal[p]);
pre[p] = 0; tVal[p] = INF;
for(int e = nodes[cur]; e; e = nxt[e]){
if(to[e] == fa || vis[to[e]])
continue;
clear(to[e], cur);
}
}
void work(int cur){
dfs(cur, 0);
tot = size[cur];
minn = INF;
findRoot(cur, 0);
cur = root;
dist[cur] = 0;
cn = 0;
dfsDist(cur, 0);
sort(clist + 1, clist + cn + 1);
for(int i = 1; i <= cn; i ++){
int t = clist[i];
int p;
p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
s[p].erase(s[p].find(dist[cg[t].id]));
int d;
if((int)s[p].size() > 1){
set<int>::iterator it = s[p].begin();
d = *it;
++ it;
d += *it;
} else
d = INF;
if(pre[p] != t){
change(sroot, pre[p], t - 1, tVal[p]);
pre[p] = t;
tVal[p] = d;
} else
tVal[p] = min(tVal[p], d);
cco[cg[t].id] = cg[t].co;
p = lower_bound(val, val + vn, cco[cg[t].id]) - val;
s[p].insert(dist[cg[t].id]);
if((int)s[p].size() > 1){
set<int>::iterator it = s[p].begin();
d = *it;
++ it;
d += *it;
} else
d = INF;
if(pre[p] != t){
change(sroot, pre[p], t - 1, tVal[p]);
pre[p] = t;
tVal[p] = d;
} else
tVal[p] = min(tVal[p], d);
}
// s[0].clear();
for(int i = 1; i <= cn; i ++){
int t = clist[i];
int p = lower_bound(val, val + vn, cg[t].co) - val;
change(sroot, pre[p], m, tVal[p]);
pre[p] = 0;
tVal[p] = INF;
}
clear(cur, 0);
vis[cur] = true;
for(int e = nodes[cur]; e; e = nxt[e]){
if(!vis[to[e]])
work(to[e]);
}
}
void print(Node* cur){
if(cur -> l == cur -> r){
if(cur -> minn == INF)
printf("-1\n");
else
printf("%d\n", cur -> minn);
return;
}
pushDown(cur);
print(cur -> left);
print(cur -> right);
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
freopen("test.out", "w", stdout);
#endif
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
scanf("%d", data + i);
val[vn ++] = data[i];
}
for(int i = 1; i < n; i ++){
int a, b, w;
scanf("%d%d%d", &a, &b, &w);
addEdge(a, b, w);
addEdge(b, a, w);
}
scanf("%d", &m);
for(int i = 1; i <= m; i ++){
scanf("%d%d", &cg[i].id, &cg[i].co);
event[cg[i].id].push_back(i);
val[vn ++] = cg[i].co;
}
sort(val, val + vn);
vn = unique(val, val + vn) - val;
sroot = build(0, m);
memset(tVal, INF, sizeof(tVal));
work(1);
for(int i = 0; i < vn; i ++)
s[0].insert(INF);
memset(pre, INF, sizeof(pre));
print(sroot);
// printf("%d\n", pre[2]);
return 0;
}