#include <stdio.h>
#include <algorithm>
const int nmax=15001;
const int mmax=30001;
const int NIL=-1;
struct muchie
{
int n1,n2,cost;
};
muchie mv[mmax];
struct element
{
int nod,cost,next;
};
element buff[2*(nmax-1)];
int head[nmax];
bool cmp(muchie a, muchie b)
{
return a.cost < b.cost;
}
int parent[nmax];
int nrnoduri[nmax];
int findparent(int x)
{
if (parent[x] == x)
return x;
return findparent(parent[x]);
}
void unire(int a, int b)
{
if (nrnoduri[a] > nrnoduri[b])
{
parent[b]=a;
nrnoduri[a]+=nrnoduri[b];
}
else
{
parent[a]=b;
nrnoduri[b]+=nrnoduri[a];
}
}
void push(int n1, int n2, int cost, int pos)
{
buff[pos].nod=n2;
buff[pos].cost=cost;
buff[pos].next=head[n1];
head[n1]=pos;
}
struct element2
{
int nod,cost;
};
element2 str[14][nmax];///str [i][j]=stramosul cu 2^i nivele mai sus al lui j
int ap[nmax];
int lvl[nmax];
void dfs(int nod, int lev)
{
int i;
ap[nod]=1;
lvl[nod]=lev;
i=head[nod];
while (i != NIL)
{
if (!ap[buff[i].nod])
{
str[0][buff[i].nod].nod=nod;///stramosul direc al nodului buff[i].nod este nod
str[0][buff[i].nod].cost=buff[i].cost;
dfs(buff[i].nod,lev+1);
}
i=buff[i].next;
}
}
int lg[nmax];
void precalc (int n)
{
int i;
lg[1]=0;
for (i=2; i<=n; i++)
lg[i]=lg[i/2]+1;
}
int lca(int x, int y)
{
int log1,log2,i,aux;
log1=lg[lvl[x]];
log2=lg[lvl[y]];
if (lvl[x] < lvl[y])
{
aux=x;
x=y;
y=aux;
}
aux=-1;
for (i=log1; i>=0; i--)
if (lvl[x] - (1 << i) >= lvl[y])
{
if (str[i][x].cost > aux)
aux=str[i][x].cost;
x=str[i][x].nod;
}
if (x == y)
return aux;
for (i=log2; i>=0; i--)
if ((str[i][x].nod != str[i][y].nod) && (str[i][x].nod != 1))
{
if (str[i][x].cost > aux)
aux=str[i][x].cost;
if (str[i][y].cost > aux)
aux=str[i][y].cost;
x=str[i][x].nod;
y=str[i][y].nod;
}
if (str[0][x].cost > aux)
aux=str[0][x].cost;
if (str[0][y].cost > aux)
aux=str[0][y].cost;
return aux;
}
int main()
{
FILE *fin,*fout;
int n,m,k,a,b,i,j,nrcconex,pos,x,y;
fin=fopen("radiatie.in","r");
fscanf(fin,"%d%d%d",&n,&m,&k);
for (i=1; i<=n; i++)
fscanf(fin,"%d%d%d",&mv[i].n1,&mv[i].n2,&mv[i].cost);
///incepe Kruskal
std::sort(mv+1,mv+m+1,cmp);///sortare muchii
for (i=1; i<=n; i++)
{
parent[i]=i;///initializare parinti noduri arbore
nrnoduri[i]=1;///initializez numarul de noduri pe care il are fiecare arbore
head[i]=-1;
}
nrcconex=n;
pos=1;///poz in vectorul de muchii
j=1;///poz in buff
while (nrcconex != 1)
{
a=findparent(mv[pos].n1);
b=findparent(mv[pos].n2);
if (a != b)
{
unire(a,b);
push(mv[pos].n1,mv[pos].n2,mv[pos].cost,j);
j++;
push(mv[pos].n2,mv[pos].n1,mv[pos].cost,j);
j++;
nrcconex--;
}
pos++;
}
///se termina Kruskal
dfs(1,1);///fac un dfs ca sa aflu nivelul fiecarui nod in arbore, considerand ca nodul 1 este radacina
///incepe Stramosi
for (i=1; (1 << i) <= n; i++)
for (j=1; j <= n; j++)
{
str[i][j].nod=str[i-1][str[i-1][j].nod].nod;
str[i][j].cost=str[i-1][str[i-1][j].nod].cost;
if (str[i-1][j].cost > str[i][j].cost)
str[i][j].cost=str[i-1][j].cost;
}
///se termina Stramosi
precalc(n);
fout=fopen("radiatie.out","w");
for (i=1; i <= k; i++)
{
fscanf(fin,"%d%d",&x,&y);
fprintf(fout,"%d\n",lca(x,y));
}
fclose(fin);
fclose(fout);
}