//kruskal -> APM -> parcurgere DFS/BFS -> impartire pe niveluri, vectorul de parinti
#include <cstdio>
#include <algorithm>
#include <vector>
#define NMAX 50000
using namespace std;
FILE*fin=fopen("radiatie.in", "r");
FILE*fout=fopen("radiatie.out", "w");
int n, m, k;
struct muchie
{
int x, y;
int cost;
};
muchie M[NMAX];
int sol[NMAX];
int conex[NMAX];
struct vecin
{
int varf;
int cost;
};
vector <vecin> Gprim[NMAX];
int level[NMAX], father[NMAX], costuri[NMAX];
void citire();
void kruskal();
bool ord(muchie A, muchie B);
void initializare();
void unific(int x, int y);
void creareGprim();
void DFS(int nod, int parinte, int nivel, int cost);
int query(int x, int y);
int main()
{
citire();
kruskal();
creareGprim();
DFS(1, 0, 1, 0);
int i, x, y;
for(i=1;i<=k;i++)
{
fscanf(fin, "%d %d\n", &x, &y);
fprintf(fout, "%d\n", query(x, y));
}
return 0;
}
void citire()
{
int i;
fscanf(fin, "%d %d %d\n", &n, &m, &k);
for(i=1;i<=m;i++)
fscanf(fin, "%d %d %d\n", &M[i].x, &M[i].y, &M[i].cost);
}
void kruskal()
{
int i=0, nrm=0;
sort(M+1, M+m+1, ord);
initializare();
while(nrm<n-1)
{
++i;
while(conex[M[i].x]==conex[M[i].y])
++i;
unific(M[i].x, M[i].y);
sol[++nrm]=i;
}
}
bool ord(muchie A, muchie B)
{
return A.cost<=B.cost;
}
void initializare()
{
int i;
for(i=1;i<=n;i++)
conex[i]=i;
}
void unific(int x, int y)
{
int i;
int a, b;
if(conex[x]<=conex[y])
{
a=conex[x];
b=conex[y];
}
else
{
a=conex[y];
b=conex[x];
}
for(i=1;i<=n;i++)
if(conex[i]==b)
conex[i]=a;
}
void creareGprim()
{
int i;
int nodParinte, nodFiu;
vecin Vecin;
int Cost;
for(i=1;i<n;i++)
{
//solutie[i] - indicele muchiei
nodParinte=M[sol[i]].x;
nodFiu=M[sol[i]].y;
Cost=M[sol[i]].cost;
Vecin.varf=nodFiu;
Vecin.cost=Cost;
Gprim[nodParinte].push_back(Vecin);
Vecin.varf=nodParinte;
Vecin.cost=Cost;
Gprim[nodFiu].push_back(Vecin);
}
}
void DFS(int nod, int parinte, int nivel, int cost)
{
father[nod]=parinte;
level[nod]=nivel;
costuri[nod]=cost;
int i, lg=Gprim[nod].size();
for(i=0;i<lg;i++)
if(!level[Gprim[nod][i].varf])
DFS(Gprim[nod][i].varf, nod, nivel+1, Gprim[nod][i].cost);
}
int query(int x, int y)
{
int rezultat=0;
if(level[y]<level[x])
swap(x, y);
while(level[y]!=level[x])
{
rezultat=max(rezultat, costuri[y]);
y=father[y];
}
while(x!=y)
{
rezultat=max(rezultat, max(costuri[x], costuri[y]));
x=father[x]; y=father[y];
}
return rezultat;
}