#include <cstdio>
#include <algorithm>
#include <vector>
#include <cstring>
#include <utility>
using namespace std;
#define MAXN 15010
#define MAXLGN 16
#define MAXM 30010
int C[MAXM];
inline int find(int *T, int x){
while(x!=T[x])
x=T[x];
return x;
}
inline void unite(int *T, int x, int y){
T[x]=y;
}
int cmp(int a, int b){
return C[a]<C[b];
}
int main(){
freopen("radiatie.in", "r", stdin);
freopen("radiatie.out", "w", stdout);
int N, M, K, i, j, k, a, b, e, qp, lca, x, y, maxd, dist, up;
static int X[MAXM], Y[MAXM], IND[MAXM], T[MAXM];
static int Q[MAXN], use[MAXN], E[MAXN<<1], L[MAXN<<1], F[MAXN];
static int RMQ[MAXLGN][MAXN<<1], lg[MAXN<<1], S[MAXLGN][MAXN], D[MAXLGN][MAXN];
pair<int,int> P[MAXN];
vector< pair<int,int> > G[MAXN];
vector< pair<int,int> >::iterator dfs[MAXN];
scanf("%d%d%d", &N, &M, &K);
for(i=1; i<=M; i++)
scanf("%d%d%d", X+i, Y+i, C+i);
// Minimum spanning tree
for(i=1; i<=M; i++){
T[i]=i;
IND[i]=i;
}
sort(IND+1, IND+M+1, cmp);
for(i=1; i<=M; i++)
if((a=find(T, X[IND[i]])) != (b=find(T, Y[IND[i]]))){
unite(T, a, b);
G[X[IND[i]]].push_back(make_pair(Y[IND[i]], C[IND[i]]));
G[Y[IND[i]]].push_back(make_pair(X[IND[i]], C[IND[i]]));
}
memset(use, 0, sizeof(use));
memset(F, 0, sizeof(F));
// Euler + level (DFS)
Q[0]=1; qp=0; dfs[0]=G[1].begin();
use[1]=1; e=0;
while(qp>=0){
if(!qp || qp!=L[e]){
E[++e]=Q[qp]; L[e]=qp;
if(!F[Q[qp]])
F[Q[qp]]=e;
}
if(dfs[qp] != G[Q[qp]].end()){
if(!use[dfs[qp]->first]){
Q[qp+1]=dfs[qp]->first;
dfs[qp+1]=G[Q[qp+1]].begin();
use[Q[qp+1]]=1;
P[Q[qp+1]].first=Q[qp];
P[Q[qp+1]].second=dfs[qp]->second;
qp++;
}
else
dfs[qp]++;
}
else {
qp--;
dfs[qp]++;
}
}
// RMQ
for(i=1; i<=e; i++)
RMQ[0][i]=i;
for(i=1; (1<<i)<=e; i++)
for(j=1; j+(1<<i)-1 <= e; j++){
if(L[RMQ[i-1][j]] < L[RMQ[i-1][j+(1<<(i-1))]])
RMQ[i][j]=RMQ[i-1][j];
else
RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
}
for(i=1; i<=N; i++){
S[0][i]=P[i].first;
D[0][i]=P[i].second;
}
for(i=1; (1<<i)<=N; i++)
for(j=1; j+(1<<i)-1 <= e; j++){
S[i][j]=S[i-1][S[i-1][j]];
D[i][j]=max(D[i-1][j], D[i-1][S[i-1][j]]);
}
lg[1]=0;
for(i=2; i<=e; i++)
lg[i]=lg[i>>1]+1;
// Query
for(i=1; i<=K; i++){
scanf("%d%d", &a, &b);
// LCA
x=F[a], y=F[b];
if(x>y)
swap(x,y);
k=lg[y-x+1];
if(L[RMQ[k][x]] < L[RMQ[k][y-(1<<k)+1]])
lca=RMQ[k][x];
else
lca=RMQ[k][y-(1<<k)+1];
// MAX DIST
maxd=0;
if(a!=lca){
dist=L[F[a]]-L[F[lca]];
k=lg[dist];
maxd=max(maxd, D[k][a]);
// move upwards to secure 2nd interval
up=dist-(1<<k);
x=a;
while(up){
x=S[lg[up]][x];
up-=1<<lg[up];
}
maxd=max(maxd, D[k][x]);
}
if(b!=lca){
dist=L[F[b]]-L[F[lca]];
k=lg[dist];
maxd=max(maxd, D[k][b]);
// move upwards to secure 2nd interval
up=dist-(1<<k);
x=b;
while(up){
x=S[lg[up]][x];
up-=1<<lg[up];
}
maxd=max(maxd, D[k][x]);
}
printf("%d\n", maxd);
}
return 0;
}