using namespace std;
#include <cstdio>
#include <vector>
#include <queue>
#include <algorithm>
#include <functional>
#define pb push_back
#define f first
#define s second
#define sz size
#define II inline
#define FOR(i,a,b) for(int i=a;i<=b;++i)
#define mp make_pair
#define IN "radiatie.in"
#define OUT "radiatie.out"
#define oo 1<<30
#define N_MAX 1<<14
#define LG_MAX 16
typedef vector<int> VI;
vector< vector< pair<int,int> > > A1(N_MAX),A(N_MAX);
int rez,S[N_MAX],SM[N_MAX];
int lg[N_MAX],CS[N_MAX],poz[N_MAX],stv[N_MAX],hg[N_MAX],maxhg,tata[N_MAX];
int rmq[LG_MAX][N_MAX],TA[LG_MAX][N_MAX],drum[LG_MAX][N_MAX];
bool viz[N_MAX];
int N,M,K;
priority_queue< pair<int,int> ,vector<pair<int,int> >, greater<pair<int,int> > > Q;
II void scan()
{
int x,y,cc;
freopen(IN,"r",stdin);
freopen(OUT,"w",stdout);
scanf("%d%d%d\n",&N,&M,&K);
FOR(i,1,M)
{
scanf("%d%d%d\n",&x,&y,&cc);
A1[x].pb( mp(y,cc) );
A1[y].pb( mp(x,cc) );
}
FOR(i,1,N)
sort(A1[i].begin(),A1[i].end() );
}
II int find(int nod,int vecin)
{
int l = A1[nod].sz() - 1;
if(l < 0)
return oo;
int step,m;
for(step = 1;step <= l;step <<= 1);
for(m = 0;step;step >>= 1)
if(m + step <= l && A1[nod][m+step-1].f < vecin)
m += step;
if(A1[nod][m].f == vecin)
return A1[nod][m].s;
else
return oo;
}
II void make_tree()
{
memset(viz,0,sizeof(viz));
FOR(i,0,N+1)
S[i] = oo;
viz[1] = true;
FOR(i,2,N)
{
S[i] = find(1,i);
if(S[i] != oo)
{
SM[i] = 1;
Q.push( mp(S[i],i) );
}
}
for(;!Q.empty();)
{
int nod = Q.top().s;
int dist = Q.top().f;
Q.pop();
if(viz[nod] || dist > S[nod])
continue;
viz[nod] = true;
A[ SM[nod] ].pb( mp(nod,S[nod]) );
A[ nod ].pb( mp(SM[nod],S[nod]) );
int l = A1[nod].sz() - 1;
FOR(i,0,l)
{
int next = A1[nod][i].f;
if(!viz[next] && S[next] > find(nod,next) )
{
S[next] = find(nod,next);
SM[next] = nod;
Q.push( mp(S[next],next) );
}
}
}
/* FOR(i,1,N)
{
int l = A[i].sz() - 1;
FOR(j,0,l)
if(A[i][j].f < i)
printf("%d %d\n",i,A[i][j].f);
} */
vector< vector< pair<int,int> > >().swap(A1);
}
void euler(int nod, int niv)
{
stv[ ++stv[0] ] = nod;
poz[nod] = stv[0];
hg[nod] = niv;
maxhg = max(maxhg,niv);
int l = A[nod].sz()-1;
FOR(i,0,l)
if ( !poz[ A[nod][i].f ] )
{
tata[ A[nod][i].f ] = nod;
CS[ A[nod][i].f ] = A[nod][i].s;
euler( A[nod][i].f , niv + 1);
stv[ ++stv[0] ] = nod;
}
}
void process()
{
--lg[0];
FOR(i,1,stv[0])
lg[i] = lg[i>>1] + 1;
FOR(i,1,stv[0])
rmq[0][i] = stv[i];
for(int i=1; (1<<i) <= stv[0];++i)
for(int j=1;j+(1<<i)-1 <= stv[0];++j)
if(hg[ rmq[i-1][j] ] < hg[ rmq[i-1][ j+(1<<i) - (1<<(i-1))] ])
rmq[i][j] = rmq[i-1][j];
else
rmq[i][j] = rmq[i-1][j+(1<<i) - (1<<(i-1))];
FOR(i,1,N)
TA[0][i] = tata[i],
drum[0][i] = CS[i];
for(int i=1; (1<<i) <= maxhg;++i)
for(int j=1; j <= N ;++j)
{
if(hg[j] < 1<<i )
continue;
TA[i][j] = TA[i-1][ TA[i-1][j] ],
drum[i][j] = max(drum[i-1][j],drum[i-1][ TA[i-1][j] ]);
}
}
inline int LCA(int nod1,int nod2)
{
int x = poz[nod1],y = poz[nod2];
if(x > y)
swap(x,y);
int log = lg[y-x+1];
if(hg[ rmq[log][x] ] < hg[ rmq[log][ y-(1<<log) + 1 ] ])
return rmq[log][x];
else
return rmq[log][ y-(1<<log) + 1 ];
}
void query(int x,int y)
{
if(!x)
return;
if(hg[y] < hg[x])
{
int log = lg[ hg[x]-hg[y] ];
if(rez < drum[log][x] )
rez = drum[log][x];
query(TA[log][x],y);
}
}
void solve()
{
int x,y;
FOR(i,1,K)
{
scanf("%d%d\n",&x,&y);
if(x == y)
{
printf("0\n");
continue;
}
rez = 0;
int nod = LCA(x,y);
query(x,nod);
query(y,nod);
printf("%d\n",rez);
}
}
int main()
{
scan();
make_tree();
euler(1,0);
process();
solve();
return 0;
}