#include <cstdio>
#include <vector>
#include <algorithm>
#define MUCMAX 30023
#define NMAX 15023
#define INFINIT 100023
#define LG 31
using namespace std;
int n,m,p;
struct str
{
int n1;
int n2;
int cost;
}s[MUCMAX];
int rmq1[INFINIT][17],aparitie[NMAX],stram[NMAX][LG],muchie[NMAX][LG];
vector<int>adjt[NMAX],costt[NMAX],adj[NMAX],cost[NMAX],ap[NMAX];
int ps,parc[INFINIT],niv[INFINIT],c[INFINIT],t[NMAX],marime[NMAX],setm[MUCMAX],lunset,nniv[NMAX];
bool vis[NMAX];
int log2(int a)
{
for(int i=31;i>=0;i--)
{
if(a&(1<<i)) return i;
}
return 0;
}
int comp(const str &a,const str &b)
{
return a.cost<b.cost;
}
int tata(int nod)
{
if(t[nod]!=0)
{
t[nod]=tata(t[nod]);
return t[nod];
}
return nod;
}
void kruskal()
{
for(int i=1;i<=n;i++) marime[i]=1;
for(int i=1;i<=m;i++)
{
int t1=tata(s[i].n1),t2=tata(s[i].n2);
if(t1==t2) continue;
if(marime[t1]<=marime[t2])
{
t[t2]=t1;
marime[t1]=max(marime[t1],marime[t2]+1);
}
else
{
t[t1]=t2;
marime[t2]=max(marime[t2],marime[t1]+1);
}
setm[++lunset]=i;
}
}
void dfs(int nod)
{
vis[nod]=1;
vector<int>::iterator it1,it2;
for(it1=adjt[nod].begin(),it2=costt[nod].begin();it1!=adjt[nod].end();++it1,++it2)
{
if(vis[*it1]==0)
{
adj[nod].push_back(*it1);
cost[nod].push_back(*it2);
dfs(*it1);
}
}
}
void df(int nod,int nivel)
{
parc[++ps]=nod;
niv[ps]=nivel;
nniv[nod]=nivel;
vector<int>::iterator it1,it2;
for(it1=adj[nod].begin(),it2=cost[nod].begin();it1!=adj[nod].end();++it1,++it2)
{
df(*it1,nivel+1);
parc[++ps]=nod;
niv[ps]=nivel;
}
}
inline void creatermq1()
{
int lg=log2(ps);
for(int i=1;i<=ps;i++) rmq1[i][0]=i;
for(int j=1;j<=lg;j++)
{
for(int i=1;i+(1<<j)<=ps;i++)
{
if(niv[rmq1[i][j-1]]<niv[rmq1[i+(1<<(j-1))][j-1]]) rmq1[i][j]=rmq1[i][j-1];
else rmq1[i][j]=rmq1[i+(1<<(j-1))][j-1];
}
}
}
int query1(int p1,int p2)
{
if(p1>p2) swap(p1,p2);
int lg=log2(p2-p1+1);
if(niv[rmq1[p1][lg]]<=niv[rmq1[p2-(1<<lg)+1][lg]]) return parc[rmq1[p1][lg]];
return parc[rmq1[p2-(1<<lg)+1][lg]];
}
int querystram(int n1,int n2)
{
int cat=nniv[n2]-nniv[n1];
int maxim=0,sum=0;
// printf("%d ",n2);
for(int i=0;i<=30;i++)
{
if(cat&(1<<i))
{
if(maxim<muchie[n2][i]) maxim=muchie[n2][i];
n2=stram[n2][i];
sum+=(1<<i);
// printf("%d ",n2);
}
}
if(sum!=cat) while(1);
return maxim;
}
int main()
{
freopen ("radiatie.in","r",stdin);
freopen ("radiatie.out","w",stdout);
scanf("%d%d%d",&n,&m,&p);
for(int i=1;i<=m;i++) scanf("%d%d%d",&s[i].n1,&s[i].n2,&s[i].cost);
sort(s+1,s+m+1,comp);
kruskal();
for(int i=1;i<=lunset;i++)
{
adjt[s[setm[i]].n1].push_back(s[setm[i]].n2);
adjt[s[setm[i]].n2].push_back(s[setm[i]].n1);
costt[s[setm[i]].n1].push_back(s[setm[i]].cost);
costt[s[setm[i]].n2].push_back(s[setm[i]].cost);
}
dfs(1);
df(1,1);
for(int i=1;i<=ps;i++) if(aparitie[parc[i]]==0) aparitie[parc[i]]=i;
creatermq1();
int nr1,nr2;
for(int i=1;i<=n;i++)
{
vector<int>::iterator it1,it2;
for(it1=adj[i].begin(),it2=cost[i].begin();it1!=adj[i].end();++it1,++it2)
{
stram[*it1][0]=i;
muchie[*it1][0]=*it2;
}
}
for(int i=2;i<=n;i++) if(stram[i][0]==0) while(1);
for(int i=1;i<=n;i++)
{
for(int j=1;j<LG;j++) stram[i][j]=stram[stram[i][j-1]][j-1];
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<LG;j++) muchie[i][j]=max(muchie[i][j-1],muchie[stram[i][j-1]][j-1]);
}
int nod1,nod2,t1,t2;
for(int i=1;i<=p;i++)
{
scanf("%d%d",&nod1,&nod2);
t1=aparitie[nod1];
t2=aparitie[nod2];
int fin=query1(t1,t2);
printf("%d\n",max(querystram(fin,nod1),querystram(fin,nod2)));
}
}