#include<bits/stdc++.h>
#define maxN 15005
#define maxM 30005
#define inf 2000000000
using namespace std;
typedef struct tip
{
int x,y,c;
};
vector<pair<int,int> > v[maxN];
bool cmp(tip a,tip b)
{
return a.c<b.c;
}
int t[maxN],A[4*maxN+5],dp[maxN],h[8*maxN+5],dh,Lev[2*maxN+5],ap[maxN],best,fat[maxN],fEdge[maxN];
int anc[15][maxN],maxim[15][maxN];
int loga[maxN];
bool seen[maxN];
inline int GetRoot(int x)
{
int root=x;
int y=x;
while(t[x]>0)
{
x=t[x];
root=x;
}
while(t[y]>0)
{
t[y]=root;
y=t[y];
}
return root;
}
inline void Unite(int x,int y)
{
if(t[x]<t[y])
{
t[x]+=t[y];
t[y]=x;
}
else
{
t[y]+=t[x];
t[x]=y;
}
}
tip Edges[maxM];
vector<tip> APMEdges;
int n,m,q;
inline void BuildAPM()
{
sort(Edges+1,Edges+m+1,cmp);
int selected=0;
for(int i=1;i<=n;i++)
t[i]=-1;
for(int i=1;i<=m && selected<(n-1);i++)
{
int x,y,c;
x=Edges[i].x;
y=Edges[i].y;
c=Edges[i].c;
int rootx=GetRoot(x);
int rooty=GetRoot(y);
if(rootx!=rooty)
{
selected++;
APMEdges.push_back(Edges[i]);
Unite(rootx,rooty);
}
}
for(vector<tip>::iterator it=APMEdges.begin();it!=APMEdges.end();it++)
{
v[it->x].push_back({it->y,it->c});
v[it->y].push_back({it->x,it->c});
}
}
inline void Euler(int nod,int niv)
{
h[++dh]=nod;
Lev[dh]=niv;
ap[nod]=dh;
seen[nod]=1;
for(vector<pair<int,int> >::iterator it=v[nod].begin();it!=v[nod].end();it++)
{
if(!seen[it->first]) Euler(it->first,niv+1);
h[++dh]=nod;
Lev[dh]=niv;
}
}
inline void dfs(int nod)
{
seen[nod]=1;
for(vector<pair<int,int> >::iterator it=v[nod].begin();it!=v[nod].end();it++)
{
if(!seen[it->first])
{
fat[it->first]=nod;
fEdge[it->first]=it->second;
dfs(it->first);
}
}
}
inline void Build(int nod,int st,int dr)
{
if(st==dr)
{
A[nod]=st;
}
else
{
int mid=(st+dr)>>1;
Build(2*nod,st,mid);
Build(2*nod+1,mid+1,dr);
if(Lev[A[2*nod]]<Lev[A[2*nod+1]]) A[nod]=A[2*nod];
else A[nod]=A[2*nod+1];
}
}
int sol=inf;
inline void Query(int nod,int st,int dr,int a,int b)
{
if(a<=st && dr<=b)
{
if(Lev[A[nod]]<sol)
{
sol=Lev[A[nod]];
best=A[nod];
}
}
else
{
int mid=(st+dr)>>1;
if(a<=mid) Query(2*nod,st,mid,a,b);
if(b>mid) Query(2*nod+1,mid+1,dr,a,b);
}
}
inline void BuildLCA()
{
Euler(1,1);
Build(1,1,dh);
memset(seen,0,sizeof(seen));
dfs(1);
}
inline void BuildAncestors()
{
loga[1]=0;
for(int i=2;i<=n;i++)
loga[i]=1+loga[i>>1];
for(int i=1;i<=n;i++)
{
anc[0][i]=fat[i];
maxim[0][i]=fEdge[i];
}
for(int nivel=1;nivel<=loga[n];nivel++)
{
for(int i=1;i<=n;i++)
{
anc[nivel][i]=anc[nivel-1][anc[nivel-1][i]];
maxim[nivel][i]=max(maxim[nivel-1][i],maxim[nivel-1][anc[nivel-1][i]]);
}
}
}
inline int Solve(int x,int y)
{
int xa=ap[x];
int ya=ap[y];
if(xa>ya) swap(xa,ya);
sol=inf;
Query(1,1,dh,xa,ya);
// return dp[x]-dp[best]+dp[y]-dp[best];
int nivel,ans1,ans2;
best=h[best];
nivel=Lev[x]-Lev[best];
ans1=0;
ans2=0;
while(nivel)
{
ans1=max(ans1,maxim[loga[nivel]][x]);
x=anc[loga[nivel]][x];
nivel-=(1<<loga[nivel]);
}
nivel=Lev[y]-Lev[best];
while(nivel)
{
ans2=max(ans2,maxim[loga[nivel]][y]);
y=anc[loga[nivel]][y];
nivel-=(1<<loga[nivel]);
}
return max(ans1,ans2);
}
int x,y,c;
int main()
{
freopen("radiatie.in","r",stdin);
freopen("radiatie.out","w",stdout);
scanf("%d%d%d",&n,&m,&q);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
Edges[i]={x,y,c};
}
BuildAPM();
BuildLCA();
BuildAncestors();
while(q--)
{
scanf("%d%d",&x,&y);
printf("%d\n",Solve(x,y));
}
return 0;
}