#include <bits/stdc++.h>
using namespace std;
ifstream fin("radiatie.in");
ofstream fout("radiatie.out");
const int DIM = 15005;
int n,m,k,C[DIM],M[DIM],B[DIM],D[DIM];
int WhatChain[DIM],PosInChain[DIM],Chains[DIM],nrChains,Parent[DIM],Cost[DIM],Head[DIM],a,b,P[DIM];
int t[DIM],rg[DIM],Tree[DIM*4+5],ans;
bitset <DIM> seen;
vector < pair<int,int> > G[DIM];
struct Graph
{
int x,y,c;
}T[DIM*2];
bool Compare(Graph a, Graph b)
{
return(a.c<b.c);
}
int Find(int nod)
{
while(nod!=t[nod])
nod=t[nod];
return nod;
}
void Union(int x, int y)
{
if(rg[x]<rg[y])
t[x]=y;
else if(rg[y]<rg[x])
t[y]=x;
else
{
t[x]=y;
rg[y]++;
}
}
void Read()
{
fin>>n>>m>>k;
for(int i=1;i<=m;i++)
fin>>T[i].x>>T[i].y>>T[i].c;
for(int i=1;i<=n;i++)
{
rg[i]=1;
t[i]=i;
}
sort(T+1,T+1+m,Compare);
}
void GetGraph()
{
for(int i=1;i<=m;i++)
{
int a=T[i].x;
int b=T[i].y;
if(Find(a)!=Find(b))
{
G[a].push_back(make_pair(b,T[i].c));
G[b].push_back(make_pair(a,T[i].c));
Union(Find(a),Find(b));
}
}
}
void DFS(int nod)
{
C[nod]=1;
vector < pair<int,int> > ::iterator it;
for(it=G[nod].begin();it!=G[nod].end();it++)
{
int next=(*it).first;
int edge=(*it).second;
if(!C[next])
{
D[next]=D[nod]+1;
Cost[next]=edge;
DFS(next);
C[nod]+=C[next];
if(C[next]>M[nod])
{
M[nod]=C[next];
B[nod]=next;
}
}
}
}
void GetChains(int nod)
{
seen[nod]=1;
vector < pair<int,int> > ::iterator it;
for(it=G[nod].begin();it!=G[nod].end();it++)
{
if(!seen[(*it).first])
GetChains((*it).first);
}
if(C[nod]==1)
{
nrChains++;
WhatChain[nod]=nrChains;
PosInChain[nod]=1;
}
else
{
WhatChain[nod]=WhatChain[B[nod]];
PosInChain[nod]=PosInChain[B[nod]]+1;
for(unsigned i=0;i<G[nod].size();i++)
{
int r = G[nod][i].first;
if(r!=B[nod])
Parent[WhatChain[r]]=nod;
}
}
Chains[WhatChain[nod]]++;
Head[WhatChain[nod]]=nod;
}
void UpdateTree(int nod, int st, int dr, int pos, int val)
{
if(st==dr)
{
Tree[nod]=val;
return;
}
int mij=(st+dr)>>1;
if(pos<=mij)
UpdateTree(2*nod,st,mij,pos,val);
else
UpdateTree(2*nod+1,mij+1,dr,pos,val);
Tree[nod]=max(Tree[2*nod],Tree[2*nod+1]);
}
void QueryTree(int nod, int st, int dr, int a, int b)
{
if(st>=a && dr<=b)
{
ans=max(ans,Tree[nod]);
return;
}
int mij=(st+dr)>>1;
if(a<=mij)
QueryTree(2*nod,st,mij,a,b);
if(b>mij)
QueryTree(2*nod+1,mij+1,dr,a,b);
}
void UpdateChains()
{
for(int i=1;i<=nrChains;i++)
P[i]=P[i-1]+Chains[i];
for(int i=1;i<=n;i++)
UpdateTree(1,1,n,P[WhatChain[i]-1]+PosInChain[i],Cost[i]);
}
void Query()
{
while(k--)
{
fin>>a>>b;
ans=0;
while(WhatChain[a]!=WhatChain[b])
{
int p1=Head[WhatChain[a]];
int p2=Head[WhatChain[b]];
if(D[p1]<=D[p2])
swap(a,b);
int l = P[WhatChain[a]-1] + PosInChain[a], r = P[WhatChain[a]];
QueryTree(1,1,n,l,r);
a = Parent[WhatChain[a]];
}
if(PosInChain[a]>PosInChain[b])
swap(a,b);
int l = P[WhatChain[a]-1] + PosInChain[a], r = P[WhatChain[b]-1] + PosInChain[b] - 1;
if(l<=r)
QueryTree(1,1,n,l,r);
fout<<ans<<'\n';
}
}
int main()
{
Read();
GetGraph();
DFS(1);
GetChains(1);
UpdateChains();
Query();
}