#include <stdio.h>
#include <fstream>
using namespace std;
#define in "radiatie.in"
#define out "radiatie.out"
#define dim 15001
#define inf 1000000001
int a[3][30001];
int t[dim], niv[dim];
int n, m, k;
typedef struct nod {
int vf, cost;
bool ok;
nod* next;
}*PNOD;
PNOD graph[dim];
bool sel[dim];
void ReadData();
void GG(int,int);
void Kruskal();
int Find(int);
void Union(int,int);
void Qsort(int,int);
void Add(int,int,int);
int LCA(int,int);
void DF(int,int);
int main()
{
ReadData();
return 0;
}
void ReadData()
{
int x,y,c;
freopen(in,"r",stdin);
freopen(out,"w",stdout);
scanf("%d%d%d",&n,&m,&k);
for ( int i = 1; i <= m; i++ )
{
scanf("%d%d%d",&y,&x,&c);
a[0][i] = x;
a[1][i] = y;
a[2][i] = c;
Add(x,y,c);
Add(y,x,c);
}
Qsort(1,m);
Kruskal();
DF(1,0);
for ( int i = 1; i <= k; i++ )
{
scanf("%d%d",&x,&y);
printf("%d\n",LCA(x,y));
}
}
int LCA(int x, int y)
{
int maxim=-1, c=0;
while ( t[x] != t[y] )
{
if ( niv[x] > niv[y] )
{
for ( PNOD q = graph[x]; q; q=q->next )
if ( t[x] == q->vf )
{
c = q->cost;
break;
}
if ( maxim < c ) maxim = c;
x = t[x];
}
else
{
for ( PNOD q = graph[y]; q; q=q->next )
if ( t[y] == q->vf )
{
c = q->cost;
break;
}
if ( maxim < c ) maxim = c;
y = t[y];
}
}
while ( x != y )
{
if ( niv[x] > niv[y] )
{
for ( PNOD q = graph[x]; q; q=q->next )
if ( t[x] == q->vf )
{
c = q->cost;
break;
}
if ( maxim < c ) maxim = c;
x = t[x];
}
else
{
for ( PNOD q = graph[y]; q; q=q->next )
if ( t[y] == q->vf )
{
c = q->cost;
break;
}
if ( maxim < c ) maxim = c;
y = t[y];
}
}
return maxim;
}
void Add(int i, int j, int c)
{
PNOD q = new nod;
q->vf = i;
q->ok = 0;
q->cost = c;
q->next = graph[j];
graph[j] = q;
}
void Qsort(int st, int dr)
{
int i = st - 1;
int j = dr + 1;
int pivot = a[2][st];
while ( i <= j )
{
do { i++; } while ( a[2][i] < pivot );
do { j--; } while ( a[2][j] > pivot );
if ( i <= j )
{
int aux = a[2][i];
a[2][i] = a[2][j];
a[2][j] = aux;
int aux2 = a[0][i];
a[0][i] = a[0][j];
a[0][j] = aux2;
int aux3 = a[1][i];
a[1][i] = a[1][j];
a[1][j] = aux3;
}
}
if ( st < j ) Qsort(st,j);
if ( i < dr ) Qsort(i,dr);
}
int Find(int x)
{
if ( x != t[x] ) t[x] = Find(t[x]);
return t[x];
}
void DF(int nod, int nivel)
{
niv[nod] = nivel;
sel[nod] = 1;
for ( PNOD q = graph[nod]; q; q=q->next )
{
if ( !sel[q->vf] && q->ok == 1 )
{
t[q->vf] = nod;
DF(q->vf,nivel+1);
}
}
}
void Union(int x, int y)
{
if ( x != y )
{
if ( niv[x] > niv[y] ) t[y] = x;
else
{
t[x] = y;
if ( niv[x] == niv[y] ) niv[y]++;
}
}
}
void Kruskal()
{
for ( int i = 1; i <= n; i++ ) niv[t[i]=i] = 0;
int k = 0;
for ( int i = 1; i <= m; i++ )
{
int r1 = Find(a[0][i]);
int r2 = Find(a[1][i]);
if ( r1 != r2 )
{
GG(a[0][i],a[1][i]);
k++;
Union(r1,r2);
if ( k == n-1 ) break;
}
}
for ( int i = 1; i <= n; i++ ) niv[t[i]=i] = 0;
}
void GG(int i, int j)
{
for ( PNOD q = graph[i]; q; q=q->next )
if ( q->vf == j )
{
q->ok = 1;
break;
}
for ( PNOD q = graph[j]; q; q=q->next )
if ( q->vf == i )
{
q->ok = 1;
break;
}
}