#include<cstdio>
#include<algorithm>
#include<vector>
#define PII pair<int,int>
#define pb push_back
#define mp make_pair
using namespace std;
const int MMAX = 30005;
const int NMAX = 15005;
const int LMAX = 15;
int N,M,K,i,j,X,Y,C,A,B,E,F;
int D[NMAX],Level[NMAX];
int S[NMAX][LMAX],Max[NMAX][LMAX];
vector<PII> G[NMAX];
struct Edge
{
int X,Y,C;
};
Edge V[MMAX];
bool cmp(Edge A,Edge B)
{
return A.C<B.C;
}
int Find(int X)
{
if(D[X]!=X) D[X]=Find(D[X]);
return D[X];
}
void Unite(int X,int Y)
{
D[X]=Y;
}
void DFS(int X,int Y)
{
Level[X]=Y;
for(vector<PII>::iterator it=G[X].begin();it!=G[X].end();it++)
if(!Level[it->first])
{
DFS(it->first,Y+1);
S[it->first][0]=X;
Max[it->first][0]=it->second;
}
}
void Read()
{
freopen("radiatie.in","r",stdin);
freopen("radiatie.out","w",stdout);
scanf("%d%d%d",&N,&M,&K);
for(i=1;i<=M;i++) scanf("%d%d%d",&V[i].X,&V[i].Y,&V[i].C);
}
void BuildAPM()
{
sort(V+1,V+M+1,cmp);
for(i=1;i<=N;i++) D[i]=i;
for(i=1;i<=M;i++)
{
X=V[i].X; Y=V[i].Y; C=V[i].C;
A=Find(X); B=Find(Y);
if(A!=B)
{
Unite(A,B);
G[X].pb(mp(Y,C));
G[Y].pb(mp(X,C));
}
}
}
void BuildAncestors()
{
DFS(1,1);
for(i=1;(i<<1)<=N;i++)
for(j=1;j<=N;j++)
{
S[j][i]=S[S[j][i-1]][i-1];
Max[j][i]=max(Max[j][i-1],Max[S[j][i-1]][i-1]);
}
}
void AnswerQueries()
{
for(;K;K--)
{
scanf("%d%d",&X,&Y);
if(Level[X]>Level[Y]) swap(X,Y);
C=Level[Y]-Level[X]; E=F=0;
for(i=0,j=1;j<=C;i++,j<<=1)
if(j&C)
{
F=max(F,Max[Y][i]);
Y=S[Y][i];
}
if(X!=Y)
{
for(A=0;(1<<A)<=Level[X];A++);
for(i=A;i;i--)
if(S[X][i] && S[X][i]!=S[Y][i])
{
E=max(E,Max[X][i]);
F=max(F,Max[Y][i]);
X=S[X][i]; Y=S[Y][i];
}
}
printf("%d\n",max(E,F));
}
}
int main()
{
Read();
BuildAPM();
//BuildAncestors();
//AnswerQueries();
return 0;
}