#include <bits/stdc++.h>
#define ll int
#define pp pair< int, int >
#define tt tuple< int, int, int >
using namespace std;
const int mxn = 15 * 1000 + 10;
const int mxx = 2e9;
vector< pp > graf[ mxn ];
vector< int > partial[ mxn ];
ll dist[ mxn ];
int nivel[ 2 * mxn ];
int parcurgere[ mxn ];
int poz[ mxn ];
int p;
int arb_min[ 8 * mxn ], arb_max[ 8 * mxn ];
int n, m, k;
int a, b;
inline tt atribuire(pp muchie, int daddy){
return make_tuple(muchie.first, muchie.second, daddy);
}
void construire_partial(){
priority_queue< tt, vector< tt >, greater< tt > > q_min;
bitset< mxn > viz;
int ramas = n - 1;
for(auto it: graf[ 1 ])
q_min.push( atribuire( it, 1 ) );
viz[ 1 ] = 1;
int cost, nod, daddy;
while(!q_min.empty() && ramas > 0){
tie(cost, nod, daddy) = q_min.top();
q_min.pop();
if(viz[ nod ] == 0){
partial[ daddy ].push_back( nod );
ramas--;
viz[ nod ] = 1;
dist[ nod ] = cost;
for(auto it: graf[ nod ])
q_min.push( atribuire( it, nod ) );
}
}
}
void euler(int nod, int lvl){
nivel[ nod ] = lvl;
poz[ nod ] = p;
parcurgere[ p++ ] = nod;
for(auto it: partial[ nod ]){
euler( it, lvl + 1 );
parcurgere[ p++ ] = nod;
}
}
int build_lca(int nod, int st, int sf){
if(st == sf){
arb_min[ nod ] = parcurgere[ st ];
return nivel[ arb_min[ nod ] ];
}
else{
int mid = (st + sf) / 2;
int n1 = build_lca(2 * nod, st, mid);
int n2 = build_lca(2 * nod + 1, mid + 1, sf);
if(n1 <= n2){
arb_min[ nod ] = arb_min[ 2 * nod ];
return n1;
}
else{
arb_min[ nod ] = arb_min[ 2 * nod + 1];
return n2;
}
}
}
int lca(int nod, int st, int sf){
if(st >= a && sf <= b)
return arb_min[ nod ];
else{
if(st <= b && sf >= a){
int mid = (st + sf) / 2;
int n1 = lca(2 * nod, st, mid);
int n2 = lca(2 * nod + 1, mid + 1, sf);
if(nivel[ n1 ] <= nivel[ n2 ]){
return n1;
}
else{
return n2;
}
}
}
return mxn;
}
void atribuire_interval(int x, int y){
a = poz[ x ];
b = poz[ y ];
if(a > b)
swap(a, b);
}
int build_radiation(int nod, int st, int sf){
if(st == sf){
arb_max[ nod ] = parcurgere[ st ];
return dist[ arb_max[ nod ] ];
}
else{
int mid = (st + sf) / 2;
int n1 = build_radiation(2 * nod, st, mid);
int n2 = build_radiation(2 * nod + 1, mid + 1, sf);
if(n1 >= n2){
arb_max[ nod ] = arb_max[ 2 * nod ];
return n1;
}
else{
arb_max[ nod ] = arb_max[ 2 * nod + 1];
return n2;
}
}
}
int query(int nod, int st, int sf){
if(st >= a && sf <= b)
return arb_max[ nod ];
else{
if(st <= b && sf >= a){
int mid = (st + sf) / 2;
int n1 = query(2 * nod, st, mid);
int n2 = query(2 * nod + 1, mid + 1, sf);
if(dist[ n1 ] >= dist[ n2 ]){
return n1;
}
else{
return n2;
}
}
}
return 0;
}
int main()
{
ifstream cin("radiatie.in");
ofstream cout("radiatie.out");
cin>> n >> m >> k;
for(int i = 1, x, y, z; i <= m; i++){
cin>> x >> y >> z;
graf[ x ].push_back(make_pair(z, y));
graf[ y ].push_back(make_pair(z, x));
}
construire_partial();
euler(1, 1);
build_lca(1, 0, p - 1);
build_radiation(1, 0 ,p - 1);
nivel[ mxn ] = mxn;
int aux, daddy;
int q1, q2;
for(int i = 1, x, y; i <= k; i++){
cin>> x >> y;
atribuire_interval(x, y);
daddy = lca(1, 0, p - 1);
aux = dist[ daddy ];
dist[ daddy ] = 0;
atribuire_interval(daddy, x);
q1 = query(1, 0, p - 1);
atribuire_interval(daddy, y);
q2 = query(1, 0, p - 1);
dist[ daddy ] = aux;
cout<< max(dist[ q1 ], dist[ q2 ]) << '\n';
}
return 0;
}