#include<stdio.h>
#include<vector>
#include<queue>
#include<algorithm>
const int N=30001, LOG=16;
using namespace std;
FILE *f,*g;
int parent[N], depth[N]; int n,m,k; //pentru multimi disjuncte
struct nod{
int x,y,val;
bool operator< (nod const &b) const{
return val>b.val;
}
};
priority_queue<nod> edges; vector<pair<int, int> > graph[N]; //in edges tinem valorile muchiilor in heap, pt kruskal; graph va avea padurea de cost minim
int stramos[N][LOG+5], maxval[N][LOG+5]; bool seen[N]; int adanc[N]; //stramos[v][i] are stramosul 2^i al lui v; maxval[v][i] are valoarea maxima a unei muchii de la v la stramosul 2^i
void read(void){
f=fopen("radiatie.in","r");
g=fopen("radiatie.out","w");
fscanf(f,"%d%d%d",&n,&m,&k);
int i; nod dumm;
for(i=1; i<=m; i++){
fscanf(f,"%d%d%d",&dumm.x,&dumm.y,&dumm.val);
edges.push(dumm);
}
}
void initparents(void){
int i;
for(i=1; i<=n; i++) parent[i]=i;
}
int findparent(int v){
if (v == parent[v]) return v;
else{
parent[v] = findparent(parent[v]);
return parent[v];
}
}
void unite(int x,int y,int val){
if (findparent(x) != findparent(y)){
graph[x].push_back (make_pair (y,val) );
graph[y].push_back (make_pair (x,val) );
x=findparent(x);
y=findparent(y);
if (x != y){
if (depth[x] < depth[y]) parent[x]=y;
else if (depth[x] == depth[y]) {parent[x] = y; depth[y]++; }
else parent[y] = x;
}
}
}
void kruskal(void){
nod dumm;
while (! edges.empty()){
dumm = edges.top();
edges.pop();
unite(dumm.x,dumm.y,dumm.val);
}
}
void resolvevertex(int v){
vector<pair<int, int> >::iterator it=graph[v].begin(); int i;
seen[v]=1;
while(it != graph[v].end() ){
if ( ! seen[it->first] ){
stramos[it->first][0]=v;
for(i=1; i<=LOG; i++) stramos[it->first][i]=stramos[stramos[it->first][i-1]][i-1];
maxval[it->first][0]=it->second;
for(i=1;i<=LOG; i++) maxval[it->first][i] = max( maxval[it->first][i-1], maxval[stramos[it->first][i-1]][i-1]);
adanc[it->first]=adanc[v]+1;
resolvevertex(it->first);
}
it++;
}
}
void findstramosi(void){
int i,j;
for(i=1;i<=n;i++){
if (! seen[i]){
for(j=0; j<=LOG; j++) {stramos[i][j]=i; maxval[i][j]=0;}
resolvevertex(i);
}
}
}
pair<int,int> damistramos(int v, int k){
int i=1,t=0, maxim=0;
while (i<k) {i*=2; t++;}
while (k){
if (k>=i) {
if (maxval[v][t]>maxim) maxim=maxval[v][t];
v=stramos[v][t];
k-=i;
}
i/=2;
t--;
}
return make_pair(v,maxim);
}
int findlca(int a, int b){
if (stramos[a][0] == stramos[b][0] ) { if (a == b) return 0; else return max (maxval[a][0], maxval[b][0]);}
else{
int i=LOG;
while (stramos[a][i] == stramos[b][i]) i--;
int maxim=0;
if (maxval[a][i]>maxim) maxim=maxval[a][i];
if (maxval[b][i]>maxim) maxim=maxval[b][i];
a=stramos[a][i]; b=stramos[b][i];
i--;
while (i>=0) {
if (stramos[a][i] != stramos[b][i]){
if (maxim<maxval[a][i]) maxim=maxval[a][i];
if (maxim<maxval[b][i]) maxim=maxval[b][i];
a=stramos[a][i]; b=stramos[b][i];
}
i--;
}
if (maxim<maxval[a][0]) maxim=maxval[a][0];
return maxim;
}
}
int findmax(int a,int b){
pair<int,int> aux;
int maxim;
if (adanc[a]<adanc[b]) swap(a,b);
aux=damistramos(a,adanc[a]-adanc[b]);
maxim=findlca(aux.first,b);
if (aux.second>maxim) maxim=aux.second;
return maxim;
}
void solve(void){
int i; int a,b;
for(i=1; i<=k; i++){
fscanf(f,"%d%d",&a,&b);
fprintf(g,"%d\n",findmax(a,b));
}
}
int main(void){
read();
initparents();
kruskal();
findstramosi();
solve();
return 0;
}