#include <cstdio>
#include <algorithm>
#define NMax 15005
using namespace std;
struct Edge
{
int x, y, c;
} E[NMax];
int N, M, NQ, Father[NMax], Rank[NMax], Cost[NMax], Used[NMax];
inline int Find (int X)
{
for (; Father[X]!=X; X=Father[X]);
return X;
}
inline void Unite (int X, int Y, int C)
{
if (Rank[X]<Rank[Y])
{
Father[X]=Y, Cost[X]=C;
}
else
{
Father[Y]=X, Cost[Y]=C;
}
if (Rank[X]==Rank[Y])
{
++Rank[X];
}
}
inline bool Compare (Edge a, Edge b)
{
return a.c<b.c;
}
void Kruskal ()
{
for (int i=1; i<=N; ++i)
{
Father[i]=i;
}
sort (E+1, E+M+1, Compare);
for (int i=1; i<=M; ++i)
{
int X=Find (E[i].x);
int Y=Find (E[i].y);
if (X!=Y)
{
Unite (X, Y, E[i].c);
}
}
}
inline int LCA (int X, int Y, int I)
{
for (; Father[X]!=X; Used[X]=I, X=Father[X]);
for (; Father[Y]!=Y and Used[Y]!=I; Y=Father[Y]);
return Y;
}
inline int GetMax (int X, int Y)
{
int C;
for (C=0; X!=Y; C=max (C, Cost[X]), X=Father[X]);
return C;
}
inline int Query (int X, int Y, int I)
{
int Z=LCA (X, Y, I);
return max (GetMax (X, Z), GetMax (Y, Z));
}
void Solve ()
{
freopen ("radiatie.out", "w", stdout);
Kruskal ();
for (; NQ>0; --NQ)
{
int X, Y;
scanf ("%d %d", &X, &Y);
printf ("%d\n", Query (X, Y, NQ));
}
}
void Read ()
{
freopen ("radiatie.in", "r", stdin);
scanf ("%d %d %d", &N, &M, &NQ);
for (int i=1; i<=M; ++i)
{
scanf ("%d %d %d", &E[i].x, &E[i].y, &E[i].c);
}
}
int main()
{
Read ();
Solve ();
return 0;
}