#include <algorithm>
#include <iostream>
#include <limits>
class Graph {
public:
typedef unsigned weight_t;
friend class Floyd;
private:
const std::size_t size;
weight_t** graph;
public:
void add_nf_edge(std::size_t node1, std::size_t node2, weight_t value) {
graph[node1][node2] = graph[node2][node1] = value;
}
explicit Graph(std::size_t n)
: size(n), graph(new weight_t*[n]) {
for (int i = 0; i < n; i++)
{
graph[i] = new weight_t[n]();
std::fill_n(graph[i], n, std::numeric_limits<weight_t>::max() / 2);
}
}
~Graph() {
for (int i = 0; i < size; i++)
delete[] graph[i];
delete[] graph;
}
};
class Floyd {
Graph::weight_t** dist;
std::size_t size;
public:
void update(std::size_t node) {
for (int i = 0; i < size; i++)
for (int j = 0; j < size; j++)
if (dist[i][node] + dist[node][j] < dist[i][j])
dist[j][i] = dist[i][j] = dist[i][node] + dist[node][j];
}
const Graph::weight_t* operator[](std::size_t from) const {
return dist[from];
}
Floyd(const Graph& G)
: dist(new Graph::weight_t*[G.size]), size(G.size) {
for (int i = 0; i < size; i++)
{
dist[i] = new Graph::weight_t[size];
std::copy_n(G.graph[i], size, dist[i]);
dist[i][i] = 0;
}
}
~Floyd() {
for (int i = 0; i < size; i++)
delete[] dist[i];
delete[] dist;
}
};
int main() {
using namespace std;
int n, m, q;
cin >> n >> m;
auto time = new int[n];
for (int i = 0; i < n; i++)
cin >> time[i];
Graph G(n);
while (m--)
{
int u, v, w;
cin >> u >> v >> w;
G.add_nf_edge(u, v, w);
}
Floyd dist(G);
int pos = -1;
cin >> q;
while (q--)
{
int x, y, t;
cin >> x >> y >> t;
while (++pos < n && time[pos] <= t)
dist.update(pos);
if (dist[x][y] >= numeric_limits<Graph::weight_t>::max() / 2)
cout << -1 << endl;
else
cout << dist[x][y] << endl;
}
delete[] time;
return 0;
}