#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
using namespace std;
ifstream f ("radiatie.in");
ofstream g ("radiatie.out");
struct Muchie {
int a, b, cost;
bool selectat;
Muchie(int a, int b, int cost) {
this->a = a;
this->b = b;
this->cost = cost;
this->selectat = false;
};
};
const int NMAX = 15000 + 1, MMAX = 30000 + 1;
const int LOGMAX = 16;
int n, m, q;
int e, nre;
int tata[NMAX], rang[NMAX], eticheta[NMAX], etichetat[NMAX], prima[NMAX], niv[NMAX];
int log2[2 * NMAX];
int rmq[LOGMAX][2 * NMAX], t[LOGMAX][NMAX], best[LOGMAX][NMAX];
vector <Muchie> muchii;
vector <int> arb[NMAX], cost[NMAX];
void citeste() {
int a, b, c;
f >> n >> m >> q;
for (int i = 1; i <= m; i++) {
f >> a >> b >> c;
muchii.push_back(Muchie(a, b, c));
}
}
inline bool comp(Muchie a, Muchie b) {
return a.cost < b.cost;
}
void initializeaza() {
for (int i = 1; i <= n; i++) {
tata[i] = i;
rang[i] = 1;
}
}
int radacina(int x) {
if (x == tata[x]) return x;
tata[x] = radacina(tata[x]);
return tata[x];
}
void uneste(int a, int b) {
a = radacina(a);
b = radacina(b);
if (rang[b] > rang[a]) tata[a] = b;
else tata[b] = a;
if (rang[b] == rang[a]) rang[a]++;
}
bool sunt_unite(int a, int b) {
a = radacina(a);
b = radacina(b);
return a == b;
}
void build_apm() {
int a, b, c;
initializeaza();
sort(muchii.begin(), muchii.end(), comp);
for (int i = 0; i < m; i++) {
a = muchii[i].a;
b = muchii[i].b;
c = muchii[i].cost;
if (sunt_unite(a, b)) continue;
uneste(a, b);
arb[a].push_back(b);
arb[b].push_back(a);
cost[a].push_back(c);
cost[b].push_back(c);
}
}
void liniarizare(int nod) {
int l = arb[nod].size(), fiu;
eticheta[nod] = ++e;
etichetat[e] = nod;
rmq[0][++nre] = e;
prima[nod] = nre;
for (int i = 0; i < l; i++) {
fiu = arb[nod][i];
if (eticheta[fiu]) continue;
t[0][fiu] = nod;
best[0][fiu] = cost[nod][i];
niv[fiu] = niv[nod] + 1;
liniarizare(fiu);
rmq[0][++nre] = eticheta[nod];
}
}
void precalculeaza() {
for (int i = 2; i <= nre; i++) log2[i] = log2[i / 2] + 1;
int l;
for (int i = 1; (1 << i) <= nre; i++) {
l = 1 << (i - 1);
for (int j = 1; j <= nre - (1 << i) + 1; j++)
rmq[i][j] = min(rmq[i - 1][j], rmq[i - 1][j + l]);
}
}
inline int lca(int a, int b) {
a = eticheta[a];
b = eticheta[b];
if (a > b) swap(a, b);
int l, secv1, secv2;
l = log2[b - a + 1];
secv1 = a;
secv2 = b - (1 << l) + 1;
return etichetat[min(rmq[l][secv1], rmq[l][secv2])];
}
void dinamica() {
int i, j, ant;
for (int i = 1; (1 << i) <= n; i++)
for (int j = 1; j <= n; j++) {
ant = t[i - 1][j];
t[i][j] = t[i - 1][ant];
best[i][j] = max(best[i - 1][j], best[i - 1][ant]);
//cout << best[i][j] << '\n';
}
}
int rez(int x, int y) {
int p = niv[x] - niv[y], sol = 0;
for (int i = 0; (1 << i) <= p; i++)
if (p & (1 << i)) {
sol = max(sol, best[i][x]);
x = t[i][x];
}
return sol;
}
void rezolva() {
int a, b, l;
while(q--) {
f >> a >> b;
l = lca(a, b);
//cout << l << ' ';
g << max(rez(a, l), rez(b, l)) << '\n';
}
}
int main() {
citeste();
build_apm();
niv[1] = 1;
liniarizare(1);
//cout << endl;
dinamica();
rezolva();
}