#include <algorithm>
#include <stdio.h>
#include <vector>
#define pb push_back
#define mp make_pair
#define f first
#define s second
#define LIM 100000
#define MAX 20000
using namespace std;
vector <pair <int, int> > listDrum[MAX], fii[MAX];
pair <int, pair <int, int> > vctEdge[MAX * 2];
pair <short, int> stramos[MAX][15];
pair <short, short> nivele[LIM][18];
int n, m, testCases, nrViz;
int log2[LIM];
int poz[MAX], sel[MAX], tata[MAX];
inline int rad(int nod)
{
if (tata[nod] == nod)
return nod;
tata[nod] = rad(tata[nod]);
return tata[nod];
}
inline int constrArb(int nod)
{
if (sel[nod])
return 0;
sel[nod] = 1;
for (int i = 0; i < listDrum[nod].size(); i++)
if (constrArb(listDrum[nod][i].f))
{
stramos[listDrum[nod][i].f][0] = mp(nod, listDrum[nod][i].s);
fii[nod].pb(listDrum[nod][i]);
}
return 1;
}
inline void bRmqStramos(int nod)
{
if (sel[nod])
return;
sel[nod] = 1;
for (int alKlea = 1, ruda = stramos[nod][0].f; ruda; ruda = stramos[ruda][alKlea - 1].f, alKlea++)
stramos[nod][alKlea] = mp(stramos[ruda][alKlea - 1].f, max(stramos[nod][alKlea - 1].s, stramos[ruda][alKlea - 1].s));
for (int i = 0; i < fii[nod].size(); i++)
bRmqStramos(fii[nod][i].f);
}
inline void parcurgereEulerArb(int nod, int depth)
{
nivele[++nrViz][0] = mp(depth, nod);
poz[nod] = nrViz;
for (int i = 0; i < fii[nod].size(); i++)
{
parcurgereEulerArb(fii[nod][i].f, depth + 1);
nivele[++nrViz][0] = mp(depth, nod);
}
}
inline void bRmqLca()
{
for (int lg = 0; lg <= log2[nrViz]; lg++)
{
int h = (1 << lg);
for (int i = 1; i <= nrViz - h; i++)
nivele[i][lg + 1] = (nivele[i][lg].f < nivele[i + h][lg].f)? nivele[i][lg] : nivele[i + h][lg];
}
}
inline int aflaDist(int nod, int ad)
{
int dist = 0;
for (int lg = log2[ad] + 1, ruda = nod; ad && lg >= 0; lg--)
if (ad >= (1 << lg))
{
dist = max(dist, stramos[ruda][lg].s);
ruda = stramos[ruda][lg].f;
ad -= (1 << lg);
}
return dist;
}
int main()
{
freopen("radiatie.in", "r", stdin);
freopen("radiatie.out", "w", stdout);
for (int i = 2; i < LIM; i++)
log2[i] = log2[i / 2] + 1;
scanf("%d %d %d", &n, &m, &testCases);
for (int i = 1; i <= m; i++)
scanf("%d %d %d", &vctEdge[i].s.f, &vctEdge[i].s.s, &vctEdge[i].f);
// Creez APM
sort(vctEdge + 1, vctEdge + 1 + m);
for (int i = 1; i <= n; i++)
tata[i] = i;
for (int i = 1; i <= m; i++)
if (rad(vctEdge[i].s.f) != rad(vctEdge[i].s.s))
{
tata[rad(vctEdge[i].s.f)] = rad(vctEdge[i].s.s);
listDrum[vctEdge[i].s.f].pb(mp(vctEdge[i].s.s, vctEdge[i].f));
listDrum[vctEdge[i].s.s].pb(mp(vctEdge[i].s.f, vctEdge[i].f));
}
memset(sel, 0, sizeof(sel));
constrArb(1);
// Fac RMQ pe stramosi
memset(sel, 0, sizeof(sel));
bRmqStramos(1);
// parcurgere Euler
memset(sel, 0, sizeof(sel));
parcurgereEulerArb(1, 1);
// RMQ pentru LCA
bRmqLca();
// Acu raspund:)
for (; testCases; testCases--)
{
int nod1, nod2;
scanf("%d %d", &nod1, &nod2);
int l1 = poz[nod1], l2 = poz[nod2];
if (l1 > l2)
swap(l1, l2), swap(nod1, nod2);
int lung = l2 - l1;
pair <short, short> maxDepth = (nivele[l1][log2[lung]].f < nivele[l2 - lung + 1][log2[lung]].f)? nivele[l1][log2[lung]] : nivele[l2 - lung + 1][log2[lung]];
int maxGs = aflaDist(nod1, nivele[l1][0].f - maxDepth.f);
maxGs = max(maxGs, aflaDist(nod2, nivele[l2][0].f - maxDepth.f));
printf("%d\n", maxGs);
}
fclose(stdin);
fclose(stdout);
return 0;
}