#include <iostream>
#include <vector>
#include <algorithm>
#define MAXM 30000
#define MAXN 15000
#define MAX_LOG 14
using namespace std;
struct edge{
int b, cost;
};
struct node{
int lvl;
bool visited;
int parent, parentCost;
vector <edge> children;
};
struct graphEdge{
int a, b, cost;
};
bool comp(graphEdge a, graphEdge b) {
return a.cost < b.cost;
}
graphEdge m[MAXM];
node tree[MAXN + 1];
int unions[MAXN + 1];
int firstApp[MAXN + 1];
int euler[MAXN * 2];
int eulerSize;
int logg[MAXN * 2];
int rmq[MAXN * 2][MAX_LOG];
int findFather(int x) {
if ( unions[x] == 0 )
return x;
return unions[x] = findFather(unions[x]);
}
void unite(int x, int y) {
int fatherX, fatherY;
fatherX = findFather(x);
fatherY = findFather(y);
if ( fatherX != fatherY )
unions[fatherX] = fatherY;
}
void addEdge(int a, int b, int cost) {
tree[a].children.push_back({b, cost});
tree[b].children.push_back({a, cost});
}
void dfs(int pos, int level) {
tree[pos].visited = true;
firstApp[pos] = eulerSize;
euler[eulerSize] = pos;
tree[pos].lvl = level;
eulerSize++;
for ( edge i : tree[pos].children ) {
if ( !tree[i.b].visited ) {
tree[i.b].parent = pos;
tree[i.b].parentCost = i.cost;
dfs(i.b, level + 1);
euler[eulerSize] = pos;
eulerSize++;
}
}
}
void precalcLog(int n) {
int i;
for ( i = 2; i <= n; i++ ) {
logg[i] = logg[i / 2] + 1;
}
}
void buildRmq(int n) {
int i, i2;
for ( i = 1; i <= n; i++ ) {
rmq[i][0] = euler[i];
}
for ( i = 1; i <= logg[n]; i++ ) {
for ( i2 = 1; i2 + (1 << i) - 1 <= n; i2++ ) {
if ( tree[rmq[i2][i - 1]].lvl < tree[rmq[i2 + (1 << (i - 1))][i - 1]].lvl ) {
rmq[i2][i] = rmq[i2][i - 1];
} else {
rmq[i2][i] = rmq[i2 + (1 << (i - 1))][i - 1];
}
}
}
}
int query(int a, int b) {
int st, dr, lenght;
st = firstApp[a];
dr = firstApp[b];
if ( st > dr )
swap(st, dr);
lenght = dr - st + 1;
if ( tree[rmq[st][logg[lenght]]].lvl < tree[rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]]].lvl )
return rmq[st][logg[lenght]];
return rmq[dr - (1 << logg[lenght]) + 1][logg[lenght]];
}
int solve(int a, int b) {
int lca, ans;
lca = query(a, b);
ans = 0;
while ( tree[a].lvl > lca ) {
ans = max(tree[a].parentCost, ans);
a = tree[a].parent;
}
while ( tree[b].lvl > lca ) {
ans = max(tree[b].parentCost, ans);
b = tree[b].parent;
}
return ans;
}
int main() {
FILE *fin, *fout;
fin = fopen("radiatie.in", "r");
fout = fopen("radiatie.out", "w");
int n, m2, i, k, fatherA, fatherB, a, b;
fscanf(fin, "%d%d%d", &n, &m2, &k);
for ( i = 0; i < m2; i++ ) {
fscanf(fin, "%d%d%d", &m[i].a, &m[i].b, &m[i].cost);
}
sort(m, m + m2, comp);
for ( i = 0; i < m2; i++ ) {
fatherA = findFather(m[i].a);
fatherB = findFather(m[i].b);
if ( fatherA != fatherB ) {
addEdge(m[i].a, m[i].b, m[i].cost);
unite(m[i].a, m[i].b);
}
}
eulerSize = 1;
dfs(1, 1);
eulerSize--;
precalcLog(eulerSize);
buildRmq(eulerSize);
while ( k-- ) {
fscanf(fin, "%d%d", &a, &b);
fprintf(fout, "%d\n", solve(a, b));
}
fclose(fin);
fclose(fout);
return 0;
}