#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <set>
#include <queue>
#include <deque>
using namespace std;
ifstream f("radiatie.in");
ofstream g("radiatie.out");
#define nmax 15005
#define Mmax 30005
#define inf (1<<29)
#define ll long long
int n, m, K, t[nmax];
vector<pair<int,int> > gf[nmax];
pair<int, pair<int,int> > mc[Mmax];
int aint[nmax*4*2], v[2*nmax], P[nmax], nivel[nmax];
bool viz[nmax];
int Max[15][nmax], tata[15][nmax];
void citeste(){
f >> n >> m >> K;//numarul de noduri; numarul de muchii; numarul de query-uri
for(int i=1; i<=m; ++i){
int x, y, c;
f >> x >> y >> c;
mc[i] = make_pair( c, make_pair(x,y) );
}
}
int radacina(int X){
int i = X;
for(; t[X]!=0; X=t[X]);
while(i != X){
int aux = t[i];
t[i] = X;
i = aux;
}
return X;
}
void uneste(int X, int Y){
t[X] = Y;
}
void fa_APM(){
//fac cu Kruskal
sort(mc+1, mc+m+1);
for(int i=1; i<=m; ++i){
int X = mc[i].second.first;
int Y = mc[i].second.second;
int cost = mc[i].first;
int rad_X = radacina(X);//radacina lui X
int rad_Y = radacina(Y);
if (rad_X == rad_Y) continue;//daca sunt deja in arbore nu le mai bag
gf[X].push_back(make_pair(Y,cost));
gf[Y].push_back(make_pair(X,cost));
//cout << X << " " << Y << " " << cost << "\n";
uneste( rad_X, rad_Y );
}
}
void initializeaza(int vc, int nod, int cost){
//initializez Max[i][j] si tata[i][j]
Max[0][vc] = cost;//muchia maxima de pe drum vc, al 2^0-lea tata va fi cost
tata[0][vc] = nod;//si tatal al 2^0-lea va fi nod
}
void dfs(int nod, int niv){
viz[nod] = 1;
nivel[nod] = niv;
v[ ++v[0] ] = nod;
P[nod] = v[0];
for(int i=0; i<gf[nod].size(); ++i){
int vc = gf[nod][i].first;
int cost = gf[nod][i].second;
if (viz[vc] == 1) continue;
initializeaza(vc, nod, cost);//asta inseamna ca primul vecin al lui vc o sa fie nod si o sa aiba costul cost
dfs(vc, niv+1);
v[ ++v[0] ] = nod;
}
}
void preprocesare(){
//fac matricile Max[i][j] = muchia maxima de pe drumul j, al 2^i-lea tata
for(int i=1; i<=14; ++i){
for(int j=1; j<=n; ++j){
int X = tata[i-1][j];
tata[i][j] = tata[i-1][X];
Max[i][j] = max(Max[i-1][j], Max[i-1][X]);
}
}
}
void build(int nod, int st, int dr){
if (st == dr){
aint[nod] = st;
return;
}
int mij = (st + dr) / 2;
build(nod*2, st, mij);
build(nod*2+1, mij+1, dr);
aint[nod] = aint[nod*2];
if ( nivel[ v[ aint[nod] ] ] > nivel[ v[ aint[nod*2+1] ] ]){
aint[nod] = aint[nod*2+1];
}
}
void query(int nod, int st, int dr, int a, int b, int &nv, int &lca){
if(a <= st && dr <= b){
if ( nv > nivel[ v[ aint[nod] ] ] ){
nv = nivel[ v[ aint[nod] ] ];
lca = v[ aint[nod] ];
}
return;
}
int mij = (st + dr) / 2;
if (a <= mij) query(nod*2, st, mij, a, b, nv, lca);
if (b > mij) query(nod*2+1, mij+1, dr, a, b, nv, lca);
}
int afla_muchie(int lca, int nod, int bug){
int k = nivel[nod] - nivel[lca];//aflu al catelea tata e lca pentru nod
int rez = 0;
for(int i=14; i>=0; --i){
if ( ( k &(1<<i) ) != 0 ){//daca am 1
rez = max(rez, Max[i][nod]);
nod = tata[i][nod];
}
}
return rez;
}
void rezolva(){
//am k query-uri de forma (x,y) trebuie sa aleg un drum intre x si y a. i. muchia maxima de pe acel drum sa fie cat mai mica
// pentru un drum de la x la y costul acelui drum va fi dat de catre muchia maxima
//ma intereseaza sa gasesc acel drum care are muchia maxima minima = > am nevoie sa refac graful a. i. intre 2 noduri sa existe doar un drum unic
// iar muchiile de pe drum sa fie cat mai mici asa ca voi transforma graful initial intr-un arbore mai exact unul de cost minim
fa_APM();
//acum pentru un drum intre x,y trebuie sa afisez muchia maxima;
//asa ca impart acest drum in 2 : aflu Lca-ul
//si aflu cu ajutorul preprocesarii muchia maxima de pe drumul nod1 lca si nod2 lca
dfs(1, 0);//fac o parcurgere euler a arborelui + intializez matricea de Min si matricea de tata
build(1, 1, v[0]);//construiesc arborele de intervale pentru LCA
preprocesare();
for(int i=1; i<=K; ++i){
int x, y;
f >> x >> y;
//muchia maxima minima de pe drum X, Y;
//le aflu lca-ul
int first_X = P[x];
int first_Y = P[y];
if (first_X > first_Y) swap(first_X, first_Y);
int lca = 0;
int nv = inf;
query(1, 1, v[0], first_X, first_Y, nv, lca);
int rez = 0;
rez = max( rez, afla_muchie(lca, x, 0) );
rez = max( rez, afla_muchie(lca, y, 1) );
g << rez << "\n";
}
}
int main(){
citeste();
rezolva();
f.close();
g.close();
return 0;
}