#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
#define MAXN 30001
#define INF 0x3f3f3f3f
int N, M, K, arb[MAXN], used[MAXN], sir[2 * MAXN], first[MAXN], rmq[20][2 * MAXN], stramosi[20][MAXN], strmin[20][MAXN], dad[MAXN], cost[MAXN], adan[MAXN];
struct muchia {
int c, x, y;
};
vector<muchia> muchie;
vector< pair<int, int> > graph[MAXN];
void initPADURE() {
for (int i = 1; i <= N; ++i)
arb[i] = i;
}
int getRADACINA(int nod) {
if (arb[nod] == nod)
return nod;
arb[nod] = getRADACINA(arb[nod]);
return arb[nod];
}
void uneste(int nod1, int nod2) {
arb[arb[nod1]] = arb[nod2];
}
muchia make_muchia(int x, int y, int c) {
muchia a;
a.x = x;
a.y = y;
a.c = c;
return a;
}
bool cmp(muchia a, muchia b) {
return a.c < b.c;
}
void doDFS(int nod, int dist) {
used[nod] = 1;
sir[++sir[0]] = nod;
first[nod] = sir[0];
adan[nod] = dist;
for (int i = 0; i < graph[nod].size(); ++i) {
int node = graph[nod][i].first;
if (!used[node]) {
doDFS(node, dist + 1);
sir[++sir[0]] = nod;
}
}
}
void doRMQ() {
for (int i = 1; i <= sir[0]; ++i)
rmq[0][i] = sir[i];
for (int i = 1; (1 << i) <= sir[0]; ++i)
for (int j = 1; j + (1 << i) - 1 <= sir[0]; ++j)
rmq[i][j] = min (rmq[i - 1][j], rmq[i - 1][j + (1 << (i - 1))]);
}
int LCA(int nod1, int nod2) {
int node1 = first[nod1], node2 = first[nod2];
if (node1 > node2) swap(node1, node2);
int put, dist = node2 - node1 + 1;
for (put = 0; (1 << put) <= dist; ++put); --put;
return min (rmq[put][node1], rmq[put][node2 - (1 << put) + 1]);
}
void make_dad(int nod) {
used[nod] = 1;
for (int i = 0; i < graph[nod].size(); ++i) {
int node = graph[nod][i].first;
if (!used[node]) {
dad[node] = nod;
cost[node] = graph[nod][i].second;
make_dad(node);
}
}
}
void doSTRAMOSI() {
for (int i = 1; i <= N; ++i)
stramosi[0][i] = dad[i];
for (int i = 1; (1 << i) <= N; ++i)
for (int j = 1; j <= N; ++j)
stramosi[i][j] = stramosi[i - 1][stramosi[i - 1][j]];
for (int i = 1; i <= N; ++i)
strmin[0][i] = cost[i];
for (int i = 1; (1 << i) <= N; ++i)
for (int j = 1; j <= N; ++j)
strmin[i][j] = max (strmin[i - 1][j], strmin[i - 1][stramosi[i - 1][j]]);
}
int getMIN (int nod1, int nod2) {
int maxim = -1;
int dist = adan[nod1] - adan[nod2];
int distMerge, nod = nod1;
for (distMerge = 0; (1 << distMerge) <= dist; ++distMerge); --distMerge;
while (dist != 0) {
maxim = max (maxim, strmin[distMerge][nod]);
nod = stramosi[distMerge][nod];
dist -= (1 << distMerge);
while ((1 << distMerge) > dist) --distMerge;
}
return maxim;
}
int main() {
fin >> N >> M >> K;
for (int i = 1; i <= M; ++i) {
int x, y, c;
fin >> x >> y >> c;
muchie.push_back(make_muchia(x, y, c));
}
sort (muchie.begin(), muchie.end(), cmp);
initPADURE();
for (int i = 0; i < muchie.size(); ++i) {
muchia a = muchie[i];
if (getRADACINA(a.x) != getRADACINA(a.y)) {
uneste(a.x, a.y);
graph[a.x].push_back(make_pair(a.y, a.c));
graph[a.y].push_back(make_pair(a.x, a.c));
}
}
doDFS(1, 0);
doRMQ();
memset(used, 0, sizeof(used));
make_dad(1);
doSTRAMOSI();
for (int i = 1; i <= K; ++i) {
int nod1, nod2;
fin >> nod1 >> nod2;
int lca = LCA(nod1, nod2);
fout << max (getMIN(nod1, lca), getMIN(nod2, lca)) << "\n";
}
return 0;
}