#include <iostream>
#include <fstream>
#include <vector>
#include <queue>
using namespace std;
#define INF 1000000001
#define nst (nod << 1)
#define ndr (nst + 1)
#define mij ((li + lf) >> 1)
int N, M, K, st, dr, sol, hsol;
int A[30*30002 + 666];
int Arb[15002], H[666 + 15002 << 1], L[666 + 15002 << 1], poz[15002], dist[15002], k;
struct Tati {
int t;
int c;
} tata[15002], stra[17][15002];
bool viz[15002];
vector<pair<int, int> > G[15002];
struct Muchii {
int x;
int y;
int c;
} Mc[30002];
int cmp(Muchii a, Muchii b) {
return a.c<b.c;
}
int CC(int nod) {
while(Arb[nod]!=nod) {
nod=Arb[nod];
}
return nod;
}
void Un(int nod1, int nod2) {
Arb[nod2]=nod1;
}
void DetArbore(int nod) {
int p;
queue<int> Q;
vector<pair<int, int> > X;
viz[nod]=1;
Q.push(nod);
while(!Q.empty()) {
p=Q.front(); Q.pop();
for(vector<pair<int, int> >::iterator it=G[p].begin(); it!=G[p].end(); it++) {
if(!viz[(*it).first]) {
viz[(*it).first]=1;
X.push_back(make_pair((*it).first, (*it).second));
Q.push((*it).first);
}
}
G[p].clear();
for(vector<pair<int, int> >::iterator it=X.begin(); it!=X.end(); it++) {
dist[(*it).first]=dist[p]+1;
tata[(*it).first].t=p;
tata[(*it).first].c=(*it).second;
G[p].push_back(make_pair((*it).first, (*it).second));
}
X.clear();
}
}
void Euler(int nod, int lev) {
H[++k]=nod;
L[k]=lev;
poz[nod]=k;
for(vector<pair<int, int> >::iterator it=G[nod].begin(); it!=G[nod].end(); it++) {
Euler((*it).first, lev+1);
H[++k]=nod;
L[k]=lev;
}
}
void builda(int nod, int li, int lf) {
if(li == lf)
{
A[nod] = li;
return;
}
builda(nst, li, mij);
builda(ndr, mij+1, lf);
if(L[A[nst]] <= L[A[ndr]])
A[nod] = A[nst];
else
A[nod] = A[ndr];
}
void query(int nod, int li, int lf) {
if(st <= li && lf <= dr)
{
if(L[A[nod]] < hsol)
sol = H[A[nod]],
hsol = L[A[nod]];
return;
}
if(st <= mij) query(nst, li, mij);
if(mij < dr) query(ndr, mij+1, lf);
}
int lca(int x, int y) {
st = poz[x], dr = poz[y];
if(st > dr) swap(st, dr);
sol = hsol = INF;
query(1, 1, k);
return sol;
}
int main() {
fstream f1, f2;
int i, j, p, q, x, d, n, ns, maxim;
f1.open("radiatie.in", ios::in);
f1>>N>>M>>K;
for(i=1; i<=M; i++) {
f1>>Mc[i].x>>Mc[i].y>>Mc[i].c;
}
sort(Mc+1, Mc+M+1, cmp);
for(i=1; i<=N; i++) {
Arb[i]=i;
}
ns=N-1;
for(i=1; i<=M && ns; i++) {
//aleg muchia i doar daca Mc[i].x si Mc[i].y se afla in comp conexe diferite
p=CC(Mc[i].x); q=CC(Mc[i].y);
if(p!=q) {
//folosesc muchia Mc[i].x -> Mc[i].y;
G[Mc[i].x].push_back(make_pair(Mc[i].y, Mc[i].c));
G[Mc[i].y].push_back(make_pair(Mc[i].x, Mc[i].c));
//unesc pe Mc[i].x cu Mc[i].y;
Un(p, q);
ns--;
}
}
for(i=1; i<=N; i++) {
if(!viz[i]) {
//i = radacina
tata[i].t=i; tata[i].c=0;
dist[i]=0;
DetArbore(i);
}
}
for(i=1; i<=N; i++) {
stra[0][i].t=tata[i].t;
stra[0][i].c=tata[i].c;
}
for(i=1; i<=15; i++) {
for(j=1; j<=N; j++) {
stra[i][j].t=stra[i-1][stra[i-1][j].t].t;
stra[i][j].c=max(stra[i-1][j].c, stra[i-1][stra[i-1][j].t].c);
}
}
for(i=1; i<=N; i++) {
if(tata[i].t==i) {
Euler(i, 0);
}
}
builda(1, 1, k);
f2.open("radiatie.out", ios::out);
for(i=1; i<=K; i++) {
f1>>p>>q;
if(p==q) {
f2<<0<<endl;
}
else {
x=lca(p, q);
//aflu maximul pe intervalele (p, x) si (q, x);
d=dist[p]-dist[x];
j=0; n=p; maxim=0;
while(d) {
if(d%2) {
maxim=max(maxim, stra[j][n].c);
n=stra[j][n].t;
}
j++; d=d>>1;
}
d=dist[q]-dist[x];
j=0; n=q;
while(d) {
if(d%2) {
maxim=max(maxim, stra[j][n].c);
n=stra[j][n].t;
}
j++; d=d>>1;
}
f2<<maxim<<endl;
}
}
f1.close(); f2.close();
return 0;
}