#include <cstdio>
#include <algorithm>
#include <vector>
#include <queue>
#define NMAX 16007
#define LMAX 17
#define Ind first
#define Last second
using namespace std;
struct apm{
int x;
int y;
int c;
bool operator < (const apm &x) const{
return c < x.c;
}
};
vector< apm > a;
vector< int > Sol, v[NMAX];
int T[NMAX], H[NMAX], Cost[NMAX], Viz[NMAX], D[LMAX][NMAX], Level[NMAX], Mat[NMAX][NMAX];
int n, m, k;
inline apm make_apm(int _x, int _y, int _c){
apm a;
a.x = _x;
a.y = _y;
a.c = _c;
return a;
}
inline int father(int _x){
if(_x == T[_x])
return _x;
return father(T[_x]);
}
inline void unite(int _x, int _y, int c){
if(H[_x] < H[_y])
T[_x] = _y;
else
if(H[_x] > H[_y])
T[_y] = _x;
else{
T[_y] = _x;
++H[_x];
}
}
void Fa_Apm(){
sort(a.begin(), a.end());
int Nr = 0;
for(int i = 1; i <= n; ++i){
T[i] = i;
H[i] = 1;
}
for(vector< apm >::iterator it = a.begin(); it != a.end(); ++it){
int Tx = father(it->x);
int Ty = father(it->y);
if(Tx != Ty){
unite(Tx, Ty, it->c);
Sol.push_back(Nr);
}
++Nr;
}
}
void Dfs_level(int Nod, int Lev){
Level[Nod] = Lev;
for(vector< int >::iterator it = v[Nod].begin(); it != v[Nod].end(); ++it){
D[0][*it] = Nod;
Dfs_level(*it, Lev + 1);
}
}
void make_new_graph(){
for(vector< int >::iterator it = Sol.begin(); it != Sol.end(); ++it){
v[a[*it].x].push_back(a[*it].y);
Mat[a[*it].x][a[*it].y] = Mat[a[*it].y][a[*it].x] = a[*it].c;
}
}
void Dinamica_stramosi(){
for(int i = 1; (1 << i) <= n; ++i)
for(int j = 1; j <= n; ++j)
D[i][j] = D[i - 1][D[i - 1][j]];
}
inline int Find_Max(int Start, int Finish){
return Mat[Start][Finish];
}
inline int LCA(int a, int b){
int Max = 0;
if(Level[a] < Level[b])
swap(a, b);
for(int i = LMAX - 1; i >= 0; --i)
if(Level[a] - (1 << i) >= Level[b]){
Max = max(Max, Find_Max(a, D[i][a]));
a = D[i][a];
}
if(a == b)
return Max;
for(int i = LMAX - 1; i >= 0; --i)
if(D[i][a] && D[i][a] != D[i][b]){
Max = max(Max, Find_Max(a, D[i][a]));
Max = max(Max, Find_Max(b, D[i][b]));
a = D[i][a];
b = D[i][b];
}
Max = max(Max, Find_Max(a, D[0][a]));
Max = max(Max, Find_Max(b, D[0][b]));
return Max;
}
inline int query(int a, int b){
return LCA(a, b);
}
void bfs(int a){
queue< pair< int, int > > q;
q.push(make_pair(a, 0));
while(! q.empty()){
pair< int, int > Nod = q.front();
q.pop();
for(int i = 0; i < v[Nod.Ind].size(); ++i){
int it = v[Nod.Ind][i];
Mat[a][it] = max(Mat[Nod.Ind][it], max(Mat[a][it], Nod.Last));
Mat[it][a] = Mat[a][it];
q.push(make_pair(it, Mat[a][it]));
}
}
}
int main(){
freopen("radiatie.in", "r", stdin);
freopen("radiatie.out", "w", stdout);
scanf("%d %d %d", &n, &m, &k);
for(int i = 1; i <= m; ++i){
int _a = 0, _b = 0, _c = 0;
scanf("%d %d %d", &_a, &_b, &_c);
a.push_back(make_apm(_a, _b, _c));
}
Fa_Apm();
make_new_graph();
Dfs_level(1, 1);
for(int i = 1; i <= n; ++i)
bfs(i);
/**for(int i = 1; i <= n; ++i, printf("\n"))
for(int j = 1; j <= n; ++j)
printf("%d ", Mat[i][j]);**/
/**for(int i = 1; i <= n; ++i)
printf("%d ", Level[i]);
printf("\n");**/
/**for(int i = 1; i <= n; ++i, printf("\n"))
for(vector< int >::iterator it = v[i].begin(); it != v[i].end(); ++it)
printf("%d ", *it);
printf("\n");**/
/**for(int i = 1; i <= n; ++i, printf("\n"))
for(int j = 1; j <= n; ++j)
printf("%d ", Mat[i][j]);**/
Dinamica_stramosi();
/// pt fiecare query
for(int i = 1; i <= k; ++i){
int a = 0, b = 0;
scanf("%d %d", &a, &b);
printf("%d\n", query(a, b));
}
return 0;
}